Implement substitution of function parameters in macro calls.

This makes tests 16 - 19 pass.
diff --git a/glcpp-parse.y b/glcpp-parse.y
index 0460f71..eb93bad 100644
--- a/glcpp-parse.y
+++ b/glcpp-parse.y
@@ -405,9 +405,6 @@
 {
 	argument_node_t *node;
 
-	if (argument == NULL || argument->head == NULL)
-		return;
-
 	node = xtalloc (list, argument_node_t);
 	node->argument = argument;
 
@@ -741,8 +738,9 @@
  *	Macro name is not followed by a balanced set of parentheses.
  */
 static function_status_t
-_find_arguments (token_node_t **node_ret, argument_list_t **arguments)
+_arguments_parse (argument_list_t *arguments, token_node_t **node_ret)
 {
+	token_list_t *argument;
 	token_node_t *node = *node_ret, *last;
 	int paren_count;
 	int arg_count;
@@ -757,6 +755,8 @@
 	if (node == NULL || node->token->type != '(')
 		return FUNCTION_NOT_A_FUNCTION;
 
+	argument = NULL;
+
 	paren_count = 0;
 	arg_count = 0;
 	do {
@@ -771,7 +771,14 @@
 		else if (node->token->type == ',' &&
 			 paren_count == 1)
 		{
-			arg_count++;
+			argument = NULL;
+		}
+		else {
+			if (argument == NULL) {
+				argument = _token_list_create (arguments);
+				_argument_list_append (arguments, argument);
+			}
+			_token_list_append (argument, node->token);
 		}
 
 		last = node;
@@ -799,6 +806,9 @@
 	const char *identifier;
 	argument_list_t *arguments;
 	function_status_t status;
+	token_list_t *expanded;
+	token_node_t *i, *j;
+	int parameter_index;
 
 	node = *node_ret;
 	identifier = node->token->value.str;
@@ -807,7 +817,8 @@
 
 	assert (macro->is_function);
 
-	status = _find_arguments (node_ret, &arguments);
+	arguments = _argument_list_create (parser);
+	status = _arguments_parse (arguments, node_ret);
 
 	switch (status) {
 	case FUNCTION_STATUS_SUCCESS:
@@ -821,10 +832,48 @@
 		exit (1);
 	}
 
+	if (macro->replacements == NULL) {
+		talloc_free (arguments);
+		return;
+	}
+
+
+	if (_argument_list_length (arguments) !=
+	    _string_list_length (macro->parameters))
+	{
+		fprintf (stderr,
+			 "Error: macro %s invoked with %d arguments (expected %d)\n",
+			 identifier,
+			 _argument_list_length (arguments),
+			 _string_list_length (macro->parameters));
+		return;
+	}
+
+	expanded = _token_list_create (arguments);
+
+	for (i = macro->replacements->head; i; i = i->next) {
+		if (i->token->type == IDENTIFIER &&
+		    _string_list_contains (macro->parameters,
+					   i->token->value.str,
+					   &parameter_index))
+		{
+			token_list_t *argument;
+			argument = _argument_list_member_at (arguments,
+							     parameter_index);
+			for (j = argument->head; j; j = j->next)
+			{
+				_token_list_append (expanded, j->token);
+			}
+		} else {
+			_token_list_append (expanded, i->token);
+		}
+	}
+
 	_string_list_push (parser->active, identifier);
-	_glcpp_parser_print_expanded_token_list (parser,
-						 macro->replacements);
+	_glcpp_parser_print_expanded_token_list (parser, expanded);
 	_string_list_pop (parser->active);
+
+	talloc_free (arguments);
 }
 
 void