mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 06:48:06 +02:00
Implement substitution of function parameters in macro calls.
This makes tests 16 - 19 pass.
This commit is contained in:
parent
e9397867dd
commit
9ce18cf983
1 changed files with 57 additions and 8 deletions
|
|
@ -405,9 +405,6 @@ _argument_list_append (argument_list_t *list, token_list_t *argument)
|
||||||
{
|
{
|
||||||
argument_node_t *node;
|
argument_node_t *node;
|
||||||
|
|
||||||
if (argument == NULL || argument->head == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
node = xtalloc (list, argument_node_t);
|
node = xtalloc (list, argument_node_t);
|
||||||
node->argument = argument;
|
node->argument = argument;
|
||||||
|
|
||||||
|
|
@ -741,8 +738,9 @@ typedef enum function_status
|
||||||
* Macro name is not followed by a balanced set of parentheses.
|
* Macro name is not followed by a balanced set of parentheses.
|
||||||
*/
|
*/
|
||||||
static function_status_t
|
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;
|
token_node_t *node = *node_ret, *last;
|
||||||
int paren_count;
|
int paren_count;
|
||||||
int arg_count;
|
int arg_count;
|
||||||
|
|
@ -757,6 +755,8 @@ _find_arguments (token_node_t **node_ret, argument_list_t **arguments)
|
||||||
if (node == NULL || node->token->type != '(')
|
if (node == NULL || node->token->type != '(')
|
||||||
return FUNCTION_NOT_A_FUNCTION;
|
return FUNCTION_NOT_A_FUNCTION;
|
||||||
|
|
||||||
|
argument = NULL;
|
||||||
|
|
||||||
paren_count = 0;
|
paren_count = 0;
|
||||||
arg_count = 0;
|
arg_count = 0;
|
||||||
do {
|
do {
|
||||||
|
|
@ -771,7 +771,14 @@ _find_arguments (token_node_t **node_ret, argument_list_t **arguments)
|
||||||
else if (node->token->type == ',' &&
|
else if (node->token->type == ',' &&
|
||||||
paren_count == 1)
|
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;
|
last = node;
|
||||||
|
|
@ -799,6 +806,9 @@ _glcpp_parser_print_expanded_function (glcpp_parser_t *parser,
|
||||||
const char *identifier;
|
const char *identifier;
|
||||||
argument_list_t *arguments;
|
argument_list_t *arguments;
|
||||||
function_status_t status;
|
function_status_t status;
|
||||||
|
token_list_t *expanded;
|
||||||
|
token_node_t *i, *j;
|
||||||
|
int parameter_index;
|
||||||
|
|
||||||
node = *node_ret;
|
node = *node_ret;
|
||||||
identifier = node->token->value.str;
|
identifier = node->token->value.str;
|
||||||
|
|
@ -807,7 +817,8 @@ _glcpp_parser_print_expanded_function (glcpp_parser_t *parser,
|
||||||
|
|
||||||
assert (macro->is_function);
|
assert (macro->is_function);
|
||||||
|
|
||||||
status = _find_arguments (node_ret, &arguments);
|
arguments = _argument_list_create (parser);
|
||||||
|
status = _arguments_parse (arguments, node_ret);
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case FUNCTION_STATUS_SUCCESS:
|
case FUNCTION_STATUS_SUCCESS:
|
||||||
|
|
@ -821,10 +832,48 @@ _glcpp_parser_print_expanded_function (glcpp_parser_t *parser,
|
||||||
exit (1);
|
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,
|
||||||
|
¶meter_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);
|
_string_list_push (parser->active, identifier);
|
||||||
_glcpp_parser_print_expanded_token_list (parser,
|
_glcpp_parser_print_expanded_token_list (parser, expanded);
|
||||||
macro->replacements);
|
|
||||||
_string_list_pop (parser->active);
|
_string_list_pop (parser->active);
|
||||||
|
|
||||||
|
talloc_free (arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue