Provide support for empty arguments in macro invocations.
authorCarl Worth <cworth@cworth.org>
Thu, 27 May 2010 20:29:19 +0000 (13:29 -0700)
committerCarl Worth <cworth@cworth.org>
Thu, 27 May 2010 20:29:19 +0000 (13:29 -0700)
For this we always add a new argument to the argument list as soon as
possible, without waiting until we see some argument token. This does
mean we need to take some extra care when comparing the number of
arguments with the number of expected arguments. In addition to
matching numbers, we also support one (empty) argument when zero
arguments are expected.

Add a test case here for this, which does pass.

glcpp-parse.y
tests/057-empty-arguments.c [new file with mode: 0644]

index ba79a611f6e9bc24d0cc98df9015298b2b6d7f03..3e0a96528b4a6a92371839cf122ef7a8feb2cd0e 100644 (file)
@@ -1044,7 +1044,8 @@ _arguments_parse (argument_list_t *arguments, token_node_t **node_ret)
        last = node;
        node = node->next;
 
-       argument = NULL;
+       argument = _token_list_create (arguments);
+       _argument_list_append (arguments, argument);
 
        for (paren_count = 1; node; last = node, node = node->next) {
                if (node->token->type == '(')
@@ -1064,18 +1065,16 @@ _arguments_parse (argument_list_t *arguments, token_node_t **node_ret)
                if (node->token->type == ',' &&
                         paren_count == 1)
                {
-                       if (argument)
-                               _token_list_trim_trailing_space (argument);
-                       argument = NULL;
+                       _token_list_trim_trailing_space (argument);
+                       argument = _token_list_create (arguments);
+                       _argument_list_append (arguments, argument);
                }
                else {
-                       if (argument == NULL) {
+                       if (argument->head == NULL) {
                                /* Don't treat initial whitespace as
                                 * part of the arguement. */
                                if (node->token->type == SPACE)
                                        continue;
-                               argument = _token_list_create (arguments);
-                               _argument_list_append (arguments, argument);
                        }
                        _token_list_append (argument, node->token);
                }
@@ -1132,8 +1131,11 @@ _expand_function_onto (glcpp_parser_t *parser,
                return FUNCTION_STATUS_SUCCESS;
        }
 
-       if (_argument_list_length (arguments) !=
-           _string_list_length (macro->parameters))
+       if (! ((_argument_list_length (arguments) == 
+               _string_list_length (macro->parameters)) ||
+              (_string_list_length (macro->parameters) == 0 &&
+               _argument_list_length (arguments) == 1 &&
+               arguments->head->argument->head == NULL)))
        {
                fprintf (stderr,
                         "Error: macro %s invoked with %d arguments (expected %d)\n",
diff --git a/tests/057-empty-arguments.c b/tests/057-empty-arguments.c
new file mode 100644 (file)
index 0000000..6140232
--- /dev/null
@@ -0,0 +1,6 @@
+#define zero() success
+zero()
+#define one(x) success
+one()
+#define two(x,y) success
+two(,)