summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2010-05-14 10:44:19 -0700
committerCarl Worth <cworth@cworth.org>2010-05-14 11:50:27 -0700
commit8f6a828e4a454e1bdce359c43e1108ff0315a89c (patch)
tree988c482b8fae6fe96ddcdbba5c0149d7bfcc9f24
parentdb272e6e6fbfe349ea6d9877bb7715ecb2d9f0c1 (diff)
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).
-rw-r--r--glcpp-parse.y115
-rw-r--r--glcpp.h11
2 files changed, 102 insertions, 24 deletions
diff --git a/glcpp-parse.y b/glcpp-parse.y
index d0ee78e008..27b5514e92 100644
--- a/glcpp-parse.y
+++ b/glcpp-parse.y
@@ -62,7 +62,7 @@ _expand_object_macro (glcpp_parser_t *parser, const char *identifier);
string_list_t *
_expand_function_macro (glcpp_parser_t *parser,
const char *identifier,
- string_list_t *arguments);
+ argument_list_t *arguments);
void
_print_string_list (string_list_t *list);
@@ -79,17 +79,27 @@ _string_list_append_list (string_list_t *list, string_list_t *tail);
int
_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
_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 {
char *str;
- string_list_t *list;
+ string_list_t *string_list;
+ argument_list_t *argument_list;
}
%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
%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 {
- $$ = _string_list_create (parser);
- _string_list_append_list ($$, $1);
+ $$ = _argument_list_create (parser);
+ _argument_list_append ($$, $1);
+ }
+| argument_list ',' SPACE argument {
+ _argument_list_append ($1, $4);
+ $$ = $1;
}
| argument_list ',' argument {
- _string_list_append_list ($1, $3);
+ _argument_list_append ($1, $3);
$$ = $1;
}
;
@@ -156,6 +171,11 @@ argument:
_string_list_append_item ($1, $2);
talloc_free ($2);
}
+| argument SPACE word {
+ _string_list_append_item ($1, " ");
+ _string_list_append_item ($1, $3);
+ talloc_free ($3);
+ }
| argument '(' argument ')'
;
@@ -343,10 +363,59 @@ _print_string_list (string_list_t *list)
printf ("%s", node->str);
}
-const char *
-_string_list_member_at (string_list_t *list, int index)
+argument_list_t *
+_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;
if (list == NULL)
@@ -360,7 +429,7 @@ _string_list_member_at (string_list_t *list, int index)
}
if (node)
- return node->str;
+ return node->argument;
return NULL;
}
@@ -453,14 +522,14 @@ _expand_macro_recursive (glcpp_parser_t *parser,
const char *token,
const char *orig,
string_list_t *parameters,
- string_list_t *arguments);
+ argument_list_t *arguments);
static string_list_t *
_expand_string_list_recursive (glcpp_parser_t *parser,
string_list_t *list,
const char *orig,
string_list_t *parameters,
- string_list_t *arguments)
+ argument_list_t *arguments)
{
string_list_t *result;
string_list_t *child;
@@ -479,11 +548,11 @@ _expand_string_list_recursive (glcpp_parser_t *parser,
}
if (_string_list_contains (parameters, token, &index)) {
- const char *argument;
+ string_list_t *argument;
- argument = _string_list_member_at (arguments, index);
- child = _expand_macro_recursive (parser, argument,
- orig, NULL, NULL);
+ argument = _argument_list_member_at (arguments, index);
+ child = _expand_string_list_recursive (parser, argument,
+ orig, NULL, NULL);
_string_list_append_list (result, child);
} else {
child = _expand_macro_recursive (parser, token,
@@ -502,7 +571,7 @@ _expand_macro_recursive (glcpp_parser_t *parser,
const char *token,
const char *orig,
string_list_t *parameters,
- string_list_t *arguments)
+ argument_list_t *arguments)
{
macro_t *macro;
string_list_t *replacements;
@@ -537,7 +606,7 @@ _expand_object_macro (glcpp_parser_t *parser, const char *identifier)
string_list_t *
_expand_function_macro (glcpp_parser_t *parser,
const char *identifier,
- string_list_t *arguments)
+ argument_list_t *arguments)
{
string_list_t *result;
macro_t *macro;
@@ -547,13 +616,13 @@ _expand_function_macro (glcpp_parser_t *parser,
macro = hash_table_find (parser->defines, identifier);
assert (macro->is_function);
- if (_string_list_length (arguments) !=
+ if (_argument_list_length (arguments) !=
_string_list_length (macro->parameters))
{
fprintf (stderr,
"Error: macro %s invoked with %d arguments (expected %d)\n",
identifier,
- _string_list_length (arguments),
+ _argument_list_length (arguments),
_string_list_length (macro->parameters));
return NULL;
}
diff --git a/glcpp.h b/glcpp.h
index cee08faa98..7966a2a3d2 100644
--- a/glcpp.h
+++ b/glcpp.h
@@ -30,7 +30,6 @@
/* Some data types used for parser value. */
-
typedef struct string_node {
const char *str;
struct string_node *next;
@@ -41,6 +40,16 @@ typedef struct string_list {
string_node_t *tail;
} 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;
glcpp_parser_t *