mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 11:20:11 +01:00
Support macro invocations with multiple tokens for a single argument.
We provide for this by changing the value of the argument-list production from a list of strings (string_list_t) to a new data-structure that holds a list of lists of strings (argument_list_t).
This commit is contained in:
parent
db272e6e6f
commit
8f6a828e4a
2 changed files with 102 additions and 24 deletions
115
glcpp-parse.y
115
glcpp-parse.y
|
|
@ -62,7 +62,7 @@ _expand_object_macro (glcpp_parser_t *parser, const char *identifier);
|
||||||
string_list_t *
|
string_list_t *
|
||||||
_expand_function_macro (glcpp_parser_t *parser,
|
_expand_function_macro (glcpp_parser_t *parser,
|
||||||
const char *identifier,
|
const char *identifier,
|
||||||
string_list_t *arguments);
|
argument_list_t *arguments);
|
||||||
|
|
||||||
void
|
void
|
||||||
_print_string_list (string_list_t *list);
|
_print_string_list (string_list_t *list);
|
||||||
|
|
@ -79,17 +79,27 @@ _string_list_append_list (string_list_t *list, string_list_t *tail);
|
||||||
int
|
int
|
||||||
_string_list_contains (string_list_t *list, const char *member, int *index);
|
_string_list_contains (string_list_t *list, const char *member, int *index);
|
||||||
|
|
||||||
const char *
|
|
||||||
_string_list_member_at (string_list_t *list, int index);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
_string_list_length (string_list_t *list);
|
_string_list_length (string_list_t *list);
|
||||||
|
|
||||||
|
argument_list_t *
|
||||||
|
_argument_list_create (void *ctx);
|
||||||
|
|
||||||
|
void
|
||||||
|
_argument_list_append (argument_list_t *list, string_list_t *argument);
|
||||||
|
|
||||||
|
int
|
||||||
|
_argument_list_length (argument_list_t *list);
|
||||||
|
|
||||||
|
string_list_t *
|
||||||
|
_argument_list_member_at (argument_list_t *list, int index);
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
char *str;
|
char *str;
|
||||||
string_list_t *list;
|
string_list_t *string_list;
|
||||||
|
argument_list_t *argument_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
%parse-param {glcpp_parser_t *parser}
|
%parse-param {glcpp_parser_t *parser}
|
||||||
|
|
@ -97,7 +107,8 @@ _string_list_length (string_list_t *list);
|
||||||
|
|
||||||
%token DEFINE FUNC_MACRO IDENTIFIER NEWLINE OBJ_MACRO SPACE TOKEN UNDEF
|
%token DEFINE FUNC_MACRO IDENTIFIER NEWLINE OBJ_MACRO SPACE TOKEN UNDEF
|
||||||
%type <str> FUNC_MACRO IDENTIFIER identifier_perhaps_macro OBJ_MACRO TOKEN word word_or_symbol
|
%type <str> FUNC_MACRO IDENTIFIER identifier_perhaps_macro OBJ_MACRO TOKEN word word_or_symbol
|
||||||
%type <list> argument argument_list macro parameter_list replacement_list
|
%type <string_list> argument macro parameter_list replacement_list
|
||||||
|
%type <argument_list> argument_list
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
|
@ -139,11 +150,15 @@ macro:
|
||||||
|
|
||||||
argument_list:
|
argument_list:
|
||||||
argument {
|
argument {
|
||||||
$$ = _string_list_create (parser);
|
$$ = _argument_list_create (parser);
|
||||||
_string_list_append_list ($$, $1);
|
_argument_list_append ($$, $1);
|
||||||
|
}
|
||||||
|
| argument_list ',' SPACE argument {
|
||||||
|
_argument_list_append ($1, $4);
|
||||||
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| argument_list ',' argument {
|
| argument_list ',' argument {
|
||||||
_string_list_append_list ($1, $3);
|
_argument_list_append ($1, $3);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -156,6 +171,11 @@ argument:
|
||||||
_string_list_append_item ($1, $2);
|
_string_list_append_item ($1, $2);
|
||||||
talloc_free ($2);
|
talloc_free ($2);
|
||||||
}
|
}
|
||||||
|
| argument SPACE word {
|
||||||
|
_string_list_append_item ($1, " ");
|
||||||
|
_string_list_append_item ($1, $3);
|
||||||
|
talloc_free ($3);
|
||||||
|
}
|
||||||
| argument '(' argument ')'
|
| argument '(' argument ')'
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -343,10 +363,59 @@ _print_string_list (string_list_t *list)
|
||||||
printf ("%s", node->str);
|
printf ("%s", node->str);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
argument_list_t *
|
||||||
_string_list_member_at (string_list_t *list, int index)
|
_argument_list_create (void *ctx)
|
||||||
{
|
{
|
||||||
string_node_t *node;
|
argument_list_t *list;
|
||||||
|
|
||||||
|
list = xtalloc (ctx, argument_list_t);
|
||||||
|
list->head = NULL;
|
||||||
|
list->tail = NULL;
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_argument_list_append (argument_list_t *list, string_list_t *argument)
|
||||||
|
{
|
||||||
|
argument_node_t *node;
|
||||||
|
|
||||||
|
if (argument == NULL || argument->head == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
node = xtalloc (list, argument_node_t);
|
||||||
|
node->argument = argument;
|
||||||
|
|
||||||
|
node->next = NULL;
|
||||||
|
|
||||||
|
if (list->head == NULL) {
|
||||||
|
list->head = node;
|
||||||
|
} else {
|
||||||
|
list->tail->next = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
list->tail = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_argument_list_length (argument_list_t *list)
|
||||||
|
{
|
||||||
|
int length = 0;
|
||||||
|
argument_node_t *node;
|
||||||
|
|
||||||
|
if (list == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (node = list->head; node; node = node->next)
|
||||||
|
length++;
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
string_list_t *
|
||||||
|
_argument_list_member_at (argument_list_t *list, int index)
|
||||||
|
{
|
||||||
|
argument_node_t *node;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (list == NULL)
|
if (list == NULL)
|
||||||
|
|
@ -360,7 +429,7 @@ _string_list_member_at (string_list_t *list, int index)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
return node->str;
|
return node->argument;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -453,14 +522,14 @@ _expand_macro_recursive (glcpp_parser_t *parser,
|
||||||
const char *token,
|
const char *token,
|
||||||
const char *orig,
|
const char *orig,
|
||||||
string_list_t *parameters,
|
string_list_t *parameters,
|
||||||
string_list_t *arguments);
|
argument_list_t *arguments);
|
||||||
|
|
||||||
static string_list_t *
|
static string_list_t *
|
||||||
_expand_string_list_recursive (glcpp_parser_t *parser,
|
_expand_string_list_recursive (glcpp_parser_t *parser,
|
||||||
string_list_t *list,
|
string_list_t *list,
|
||||||
const char *orig,
|
const char *orig,
|
||||||
string_list_t *parameters,
|
string_list_t *parameters,
|
||||||
string_list_t *arguments)
|
argument_list_t *arguments)
|
||||||
{
|
{
|
||||||
string_list_t *result;
|
string_list_t *result;
|
||||||
string_list_t *child;
|
string_list_t *child;
|
||||||
|
|
@ -479,11 +548,11 @@ _expand_string_list_recursive (glcpp_parser_t *parser,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_string_list_contains (parameters, token, &index)) {
|
if (_string_list_contains (parameters, token, &index)) {
|
||||||
const char *argument;
|
string_list_t *argument;
|
||||||
|
|
||||||
argument = _string_list_member_at (arguments, index);
|
argument = _argument_list_member_at (arguments, index);
|
||||||
child = _expand_macro_recursive (parser, argument,
|
child = _expand_string_list_recursive (parser, argument,
|
||||||
orig, NULL, NULL);
|
orig, NULL, NULL);
|
||||||
_string_list_append_list (result, child);
|
_string_list_append_list (result, child);
|
||||||
} else {
|
} else {
|
||||||
child = _expand_macro_recursive (parser, token,
|
child = _expand_macro_recursive (parser, token,
|
||||||
|
|
@ -502,7 +571,7 @@ _expand_macro_recursive (glcpp_parser_t *parser,
|
||||||
const char *token,
|
const char *token,
|
||||||
const char *orig,
|
const char *orig,
|
||||||
string_list_t *parameters,
|
string_list_t *parameters,
|
||||||
string_list_t *arguments)
|
argument_list_t *arguments)
|
||||||
{
|
{
|
||||||
macro_t *macro;
|
macro_t *macro;
|
||||||
string_list_t *replacements;
|
string_list_t *replacements;
|
||||||
|
|
@ -537,7 +606,7 @@ _expand_object_macro (glcpp_parser_t *parser, const char *identifier)
|
||||||
string_list_t *
|
string_list_t *
|
||||||
_expand_function_macro (glcpp_parser_t *parser,
|
_expand_function_macro (glcpp_parser_t *parser,
|
||||||
const char *identifier,
|
const char *identifier,
|
||||||
string_list_t *arguments)
|
argument_list_t *arguments)
|
||||||
{
|
{
|
||||||
string_list_t *result;
|
string_list_t *result;
|
||||||
macro_t *macro;
|
macro_t *macro;
|
||||||
|
|
@ -547,13 +616,13 @@ _expand_function_macro (glcpp_parser_t *parser,
|
||||||
macro = hash_table_find (parser->defines, identifier);
|
macro = hash_table_find (parser->defines, identifier);
|
||||||
assert (macro->is_function);
|
assert (macro->is_function);
|
||||||
|
|
||||||
if (_string_list_length (arguments) !=
|
if (_argument_list_length (arguments) !=
|
||||||
_string_list_length (macro->parameters))
|
_string_list_length (macro->parameters))
|
||||||
{
|
{
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"Error: macro %s invoked with %d arguments (expected %d)\n",
|
"Error: macro %s invoked with %d arguments (expected %d)\n",
|
||||||
identifier,
|
identifier,
|
||||||
_string_list_length (arguments),
|
_argument_list_length (arguments),
|
||||||
_string_list_length (macro->parameters));
|
_string_list_length (macro->parameters));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
11
glcpp.h
11
glcpp.h
|
|
@ -30,7 +30,6 @@
|
||||||
|
|
||||||
/* Some data types used for parser value. */
|
/* Some data types used for parser value. */
|
||||||
|
|
||||||
|
|
||||||
typedef struct string_node {
|
typedef struct string_node {
|
||||||
const char *str;
|
const char *str;
|
||||||
struct string_node *next;
|
struct string_node *next;
|
||||||
|
|
@ -41,6 +40,16 @@ typedef struct string_list {
|
||||||
string_node_t *tail;
|
string_node_t *tail;
|
||||||
} string_list_t;
|
} string_list_t;
|
||||||
|
|
||||||
|
typedef struct argument_node {
|
||||||
|
string_list_t *argument;
|
||||||
|
struct argument_node *next;
|
||||||
|
} argument_node_t;
|
||||||
|
|
||||||
|
typedef struct argument_list {
|
||||||
|
argument_node_t *head;
|
||||||
|
argument_node_t *tail;
|
||||||
|
} argument_list_t;
|
||||||
|
|
||||||
typedef struct glcpp_parser glcpp_parser_t;
|
typedef struct glcpp_parser glcpp_parser_t;
|
||||||
|
|
||||||
glcpp_parser_t *
|
glcpp_parser_t *
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue