diff options
| -rw-r--r-- | glcpp-parse.y | 193 | 
1 files changed, 120 insertions, 73 deletions
diff --git a/glcpp-parse.y b/glcpp-parse.y index a2bff6e0ad..e25cfa9214 100644 --- a/glcpp-parse.y +++ b/glcpp-parse.y @@ -100,6 +100,11 @@ _glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser,  					 token_list_t *list);  static void +_glcpp_parser_expand_token_list_onto (glcpp_parser_t *parser, +				      token_list_t *list, +				      token_list_t *result); + +static void  _glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, int condition);  static void @@ -470,55 +475,6 @@ _token_create_ival (void *ctx, int type, int ival)  	return token;  } -void -_glcpp_parser_print_token (glcpp_parser_t *parser, token_t *token) -{ -	if (token->type < 256) { -		printf ("%c", token->type); -		return; -	} - -	switch (token->type) { -	case IDENTIFIER: -	case OTHER: -		printf ("%s", token->value.str); -		break; -	case SPACE: -		printf (" "); -		break; -	case LEFT_SHIFT: -		printf ("<<"); -		break; -	case RIGHT_SHIFT: -		printf (">>"); -		break; -	case LESS_OR_EQUAL: -		printf ("<="); -		break; -	case GREATER_OR_EQUAL: -		printf (">="); -		break; -	case EQUAL: -		printf ("=="); -		break; -	case NOT_EQUAL: -		printf ("!="); -		break; -	case AND: -		printf ("&&"); -		break; -	case OR: -		printf ("||"); -		break; -	case PASTE: -		printf ("##"); -		break; -	default: -		fprintf (stderr, "Error: Don't know how to print token type %d\n", token->type); -		break; -	} -} -  token_list_t *  _token_list_create (void *ctx)  { @@ -584,6 +540,67 @@ _token_list_trim_trailing_space (token_list_t *list)  	}  } +static void +_token_print (token_t *token) +{ +	if (token->type < 256) { +		printf ("%c", token->type); +		return; +	} + +	switch (token->type) { +	case IDENTIFIER: +	case OTHER: +		printf ("%s", token->value.str); +		break; +	case SPACE: +		printf (" "); +		break; +	case LEFT_SHIFT: +		printf ("<<"); +		break; +	case RIGHT_SHIFT: +		printf (">>"); +		break; +	case LESS_OR_EQUAL: +		printf ("<="); +		break; +	case GREATER_OR_EQUAL: +		printf (">="); +		break; +	case EQUAL: +		printf ("=="); +		break; +	case NOT_EQUAL: +		printf ("!="); +		break; +	case AND: +		printf ("&&"); +		break; +	case OR: +		printf ("||"); +		break; +	case PASTE: +		printf ("##"); +		break; +	default: +		fprintf (stderr, "Error: Don't know how to print token type %d\n", token->type); +		break; +	} +} + +static void +_token_list_print (token_list_t *list) +{ +	token_node_t *node; + +	if (list == NULL) +		return; + +	for (node = list->head; node; node = node->next) +		_token_print (node->token); +} +  void  yyerror (void *scanner, const char *error)  { @@ -624,23 +641,26 @@ glcpp_parser_destroy (glcpp_parser_t *parser)  	talloc_free (parser);  } -/* Print a non-macro token, or the expansion of an object-like macro. +/* Appends onto 'expansion' a non-macro token or the expansion of an + * object-like macro.   * - * Returns 0 if this token is completely printed. + * Returns 0 if this token is completely processed.   *   * Returns 1 in the case that 'token' is a function-like macro that   * needs further expansion.   */  static int -_glcpp_parser_print_expanded_token (glcpp_parser_t *parser, -				    token_t *token) +_glcpp_parser_expand_token_onto (glcpp_parser_t *parser, +				 token_t *token, +				 token_list_t *result)  {  	const char *identifier;  	macro_t *macro; +	token_list_t *expansion;  	/* We only expand identifiers */  	if (token->type != IDENTIFIER) { -		_glcpp_parser_print_token (parser, token); +		_token_list_append (result, token);  		return 0;  	} @@ -648,16 +668,16 @@ _glcpp_parser_print_expanded_token (glcpp_parser_t *parser,  	identifier = token->value.str;  	macro = hash_table_find (parser->defines, identifier); -	/* Not a macro, so just print directly. */ +	/* Not a macro, so just append. */  	if (macro == NULL) { -		printf ("%s", identifier); +		_token_list_append (result, token);  		return 0;  	}  	/* Finally, don't expand this macro if we're already actively  	 * expanding it, (to avoid infinite recursion). */  	if (_string_list_contains (parser->active, identifier, NULL)) { -		printf ("%s", identifier); +		_token_list_append (result, token);  		return 0;  	} @@ -667,8 +687,9 @@ _glcpp_parser_print_expanded_token (glcpp_parser_t *parser,  	}  	_string_list_push (parser->active, identifier); -	_glcpp_parser_print_expanded_token_list (parser, -						 macro->replacements); +	_glcpp_parser_expand_token_list_onto (parser, +					      macro->replacements, +					      result);  	_string_list_pop (parser->active);  	return 0; @@ -770,15 +791,16 @@ _arguments_parse (argument_list_t *arguments, token_node_t **node_ret)   * list as necessary). Upon return *node will be the last consumed   * node, such that further processing can continue with node->next. */  static void -_glcpp_parser_print_expanded_function (glcpp_parser_t *parser, -				       token_node_t **node_ret) +_glcpp_parser_expand_function_onto (glcpp_parser_t *parser, +				    token_node_t **node_ret, +				    token_list_t *result)  {  	macro_t *macro;  	token_node_t *node;  	const char *identifier;  	argument_list_t *arguments;  	function_status_t status; -	token_list_t *expanded; +	token_list_t *substituted;  	token_node_t *i, *j;  	int parameter_index; @@ -796,7 +818,7 @@ _glcpp_parser_print_expanded_function (glcpp_parser_t *parser,  	case FUNCTION_STATUS_SUCCESS:  		break;  	case FUNCTION_NOT_A_FUNCTION: -		printf ("%s", identifier); +		_token_list_append (result, node->token);  		return;  	case FUNCTION_UNBALANCED_PARENTHESES:  		fprintf (stderr, "Error: Macro %s call has unbalanced parentheses\n", @@ -809,7 +831,6 @@ _glcpp_parser_print_expanded_function (glcpp_parser_t *parser,  		return;  	} -  	if (_argument_list_length (arguments) !=  	    _string_list_length (macro->parameters))  	{ @@ -821,7 +842,8 @@ _glcpp_parser_print_expanded_function (glcpp_parser_t *parser,  		return;  	} -	expanded = _token_list_create (arguments); +	/* Perform argument substitution on the replacement list. */ +	substituted = _token_list_create (arguments);  	for (i = macro->replacements->head; i; i = i->next) {  		if (i->token->type == IDENTIFIER && @@ -834,36 +856,61 @@ _glcpp_parser_print_expanded_function (glcpp_parser_t *parser,  							     parameter_index);  			for (j = argument->head; j; j = j->next)  			{ -				_token_list_append (expanded, j->token); +				_token_list_append (substituted, j->token);  			}  		} else { -			_token_list_append (expanded, i->token); +			_token_list_append (substituted, i->token);  		}  	}  	_string_list_push (parser->active, identifier); -	_glcpp_parser_print_expanded_token_list (parser, expanded); +	_glcpp_parser_expand_token_list_onto (parser, substituted, result);  	_string_list_pop (parser->active);  	talloc_free (arguments);  } +static void +_glcpp_parser_expand_token_list_onto (glcpp_parser_t *parser, +				      token_list_t *list, +				      token_list_t *result) +{ +	token_node_t *node; + +	if (list == NULL) +		return; + +	for (node = list->head; node; node = node->next) +	{ +		if (_glcpp_parser_expand_token_onto (parser, node->token, +						     result)) +		{ +			_glcpp_parser_expand_function_onto (parser, &node, +							    result); +		} +	} +} +  void  _glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser,  					 token_list_t *list)  { +	token_list_t *expanded;  	token_node_t *node;  	function_status_t function_status;  	if (list == NULL)  		return; -	_token_list_trim_trailing_space (list); +	expanded = _token_list_create (parser); -	for (node = list->head; node; node = node->next) { -		if (_glcpp_parser_print_expanded_token (parser, node->token)) -			_glcpp_parser_print_expanded_function (parser, &node); -	} +	_glcpp_parser_expand_token_list_onto (parser, list, expanded); + +	_token_list_trim_trailing_space (expanded); + +	_token_list_print (expanded); + +	talloc_free (expanded);  }  void  | 
