blob: d0ee78e008eacf4cf29d0473ffcd5b8f169ead72 [file] [log] [blame]
Carl Worth3a37b872010-05-10 11:44:09 -07001%{
2/*
3 * Copyright © 2010 Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <stdio.h>
26#include <stdlib.h>
Carl Worthfcbbb462010-05-13 09:36:23 -070027#include <assert.h>
Carl Worth33cc4002010-05-12 12:17:10 -070028#include <talloc.h>
Carl Worth3a37b872010-05-10 11:44:09 -070029
Carl Wortha1e32bc2010-05-10 13:17:25 -070030#include "glcpp.h"
31
Carl Worth0b27b5f2010-05-10 16:16:06 -070032#define YYLEX_PARAM parser->scanner
Carl Worth3a37b872010-05-10 11:44:09 -070033
Carl Worthfcbbb462010-05-13 09:36:23 -070034typedef struct {
35 int is_function;
Carl Worthc5e98552010-05-14 10:12:21 -070036 string_list_t *parameters;
37 string_list_t *replacements;
Carl Worthfcbbb462010-05-13 09:36:23 -070038} macro_t;
39
Carl Worth33cc4002010-05-12 12:17:10 -070040struct glcpp_parser {
41 yyscan_t scanner;
42 struct hash_table *defines;
43};
44
Carl Worth3a37b872010-05-10 11:44:09 -070045void
Carl Wortha1e32bc2010-05-10 13:17:25 -070046yyerror (void *scanner, const char *error);
Carl Worth3a37b872010-05-10 11:44:09 -070047
Carl Worth33cc4002010-05-12 12:17:10 -070048void
Carl Worthfcbbb462010-05-13 09:36:23 -070049_define_object_macro (glcpp_parser_t *parser,
50 const char *macro,
Carl Worthc5e98552010-05-14 10:12:21 -070051 string_list_t *replacements);
Carl Worthfcbbb462010-05-13 09:36:23 -070052
53void
54_define_function_macro (glcpp_parser_t *parser,
55 const char *macro,
Carl Worthc5e98552010-05-14 10:12:21 -070056 string_list_t *parameters,
57 string_list_t *replacements);
Carl Worthfcbbb462010-05-13 09:36:23 -070058
Carl Worth2be8be02010-05-14 10:31:43 -070059string_list_t *
60_expand_object_macro (glcpp_parser_t *parser, const char *identifier);
61
62string_list_t *
63_expand_function_macro (glcpp_parser_t *parser,
64 const char *identifier,
65 string_list_t *arguments);
Carl Worthfcbbb462010-05-13 09:36:23 -070066
67void
Carl Worth2be8be02010-05-14 10:31:43 -070068_print_string_list (string_list_t *list);
Carl Worth33cc4002010-05-12 12:17:10 -070069
Carl Worth610053b2010-05-14 10:05:11 -070070string_list_t *
71_string_list_create (void *ctx);
Carl Worth33cc4002010-05-12 12:17:10 -070072
73void
Carl Worth610053b2010-05-14 10:05:11 -070074_string_list_append_item (string_list_t *list, const char *str);
Carl Worthfcbbb462010-05-13 09:36:23 -070075
76void
Carl Worth610053b2010-05-14 10:05:11 -070077_string_list_append_list (string_list_t *list, string_list_t *tail);
Carl Worthc6d5af32010-05-11 12:30:09 -070078
Carl Worthdcc2ecd2010-05-13 12:56:42 -070079int
Carl Worth610053b2010-05-14 10:05:11 -070080_string_list_contains (string_list_t *list, const char *member, int *index);
Carl Worthdcc2ecd2010-05-13 12:56:42 -070081
82const char *
Carl Worth610053b2010-05-14 10:05:11 -070083_string_list_member_at (string_list_t *list, int index);
Carl Worthdcc2ecd2010-05-13 12:56:42 -070084
85int
Carl Worth610053b2010-05-14 10:05:11 -070086_string_list_length (string_list_t *list);
Carl Worthdcc2ecd2010-05-13 12:56:42 -070087
Carl Worth3a37b872010-05-10 11:44:09 -070088%}
89
Carl Worth33cc4002010-05-12 12:17:10 -070090%union {
91 char *str;
Carl Worth610053b2010-05-14 10:05:11 -070092 string_list_t *list;
Carl Worth33cc4002010-05-12 12:17:10 -070093}
94
Carl Worth0b27b5f2010-05-10 16:16:06 -070095%parse-param {glcpp_parser_t *parser}
Carl Worth38aa8352010-05-10 11:52:29 -070096%lex-param {void *scanner}
97
Carl Worth0a93cbb2010-05-13 10:29:07 -070098%token DEFINE FUNC_MACRO IDENTIFIER NEWLINE OBJ_MACRO SPACE TOKEN UNDEF
Carl Worth7f9aa362010-05-13 12:58:49 -070099%type <str> FUNC_MACRO IDENTIFIER identifier_perhaps_macro OBJ_MACRO TOKEN word word_or_symbol
Carl Worth2be8be02010-05-14 10:31:43 -0700100%type <list> argument argument_list macro parameter_list replacement_list
Carl Worth3a37b872010-05-10 11:44:09 -0700101
102%%
103
Carl Worth33cc4002010-05-12 12:17:10 -0700104input:
105 /* empty */
Carl Worth8bcb6f12010-05-12 13:21:20 -0700106| input content
Carl Worth3a37b872010-05-10 11:44:09 -0700107;
108
Carl Worth04af1352010-05-14 10:17:38 -0700109 /* We do all printing at the content level */
Carl Worth33cc4002010-05-12 12:17:10 -0700110content:
Carl Worth9f62a7e2010-05-13 07:38:29 -0700111 IDENTIFIER {
112 printf ("%s", $1);
113 talloc_free ($1);
114 }
115| TOKEN {
116 printf ("%s", $1);
117 talloc_free ($1);
118 }
Carl Worth2be8be02010-05-14 10:31:43 -0700119| macro {
120 _print_string_list ($1);
121 }
Carl Worth04af1352010-05-14 10:17:38 -0700122| directive_with_newline { printf ("\n"); }
Carl Worth0a93cbb2010-05-13 10:29:07 -0700123| NEWLINE { printf ("\n"); }
124| '(' { printf ("("); }
125| ')' { printf (")"); }
126| ',' { printf (","); }
Carl Worth48b94da2010-05-13 10:46:29 -0700127| SPACE { printf (" "); }
Carl Worthcd27e642010-05-12 13:11:50 -0700128;
129
Carl Worthfcbbb462010-05-13 09:36:23 -0700130macro:
131 FUNC_MACRO '(' argument_list ')' {
Carl Worth2be8be02010-05-14 10:31:43 -0700132 $$ = _expand_function_macro (parser, $1, $3);
Carl Worthfcbbb462010-05-13 09:36:23 -0700133 }
134| OBJ_MACRO {
Carl Worth2be8be02010-05-14 10:31:43 -0700135 $$ = _expand_object_macro (parser, $1);
Carl Worthfcbbb462010-05-13 09:36:23 -0700136 talloc_free ($1);
137 }
138;
139
140argument_list:
Carl Worthdb35d552010-05-14 08:47:32 -0700141 argument {
Carl Worth610053b2010-05-14 10:05:11 -0700142 $$ = _string_list_create (parser);
143 _string_list_append_list ($$, $1);
Carl Worthfcbbb462010-05-13 09:36:23 -0700144 }
145| argument_list ',' argument {
Carl Worth610053b2010-05-14 10:05:11 -0700146 _string_list_append_list ($1, $3);
Carl Worthfcbbb462010-05-13 09:36:23 -0700147 $$ = $1;
148 }
149;
150
151argument:
152 /* empty */ {
Carl Worth610053b2010-05-14 10:05:11 -0700153 $$ = _string_list_create (parser);
Carl Worthfcbbb462010-05-13 09:36:23 -0700154 }
Carl Worth0a93cbb2010-05-13 10:29:07 -0700155| argument word {
Carl Worth610053b2010-05-14 10:05:11 -0700156 _string_list_append_item ($1, $2);
Carl Worthfcbbb462010-05-13 09:36:23 -0700157 talloc_free ($2);
158 }
159| argument '(' argument ')'
160;
161
Carl Worthcd27e642010-05-12 13:11:50 -0700162directive_with_newline:
Carl Worth04af1352010-05-14 10:17:38 -0700163 directive NEWLINE
Carl Worth3a37b872010-05-10 11:44:09 -0700164;
165
Carl Worth33cc4002010-05-12 12:17:10 -0700166directive:
Carl Worth0a93cbb2010-05-13 10:29:07 -0700167 DEFINE IDENTIFIER {
Carl Worth610053b2010-05-14 10:05:11 -0700168 string_list_t *list = _string_list_create (parser);
Carl Worth0a93cbb2010-05-13 10:29:07 -0700169 _define_object_macro (parser, $2, list);
170 }
171| DEFINE IDENTIFIER SPACE replacement_list {
172 _define_object_macro (parser, $2, $4);
Carl Worthcd27e642010-05-12 13:11:50 -0700173 }
Carl Worth48b94da2010-05-13 10:46:29 -0700174| DEFINE IDENTIFIER '(' parameter_list ')' {
Carl Worth610053b2010-05-14 10:05:11 -0700175 string_list_t *list = _string_list_create (parser);
Carl Worth48b94da2010-05-13 10:46:29 -0700176 _define_function_macro (parser, $2, $4, list);
177 }
178| DEFINE IDENTIFIER '(' parameter_list ')' SPACE replacement_list {
179 _define_function_macro (parser, $2, $4, $7);
Carl Worthfcbbb462010-05-13 09:36:23 -0700180 }
181| UNDEF FUNC_MACRO {
Carl Worth610053b2010-05-14 10:05:11 -0700182 string_list_t *replacement = hash_table_find (parser->defines, $2);
Carl Worthfcbbb462010-05-13 09:36:23 -0700183 if (replacement) {
184 /* XXX: Need hash table to support a real way
185 * to remove an element rather than prefixing
186 * a new node with data of NULL like this. */
187 hash_table_insert (parser->defines, NULL, $2);
188 talloc_free (replacement);
189 }
190 talloc_free ($2);
191 }
192| UNDEF OBJ_MACRO {
Carl Worth610053b2010-05-14 10:05:11 -0700193 string_list_t *replacement = hash_table_find (parser->defines, $2);
Carl Worthcd27e642010-05-12 13:11:50 -0700194 if (replacement) {
195 /* XXX: Need hash table to support a real way
196 * to remove an element rather than prefixing
197 * a new node with data of NULL like this. */
198 hash_table_insert (parser->defines, NULL, $2);
199 talloc_free (replacement);
200 }
201 talloc_free ($2);
Carl Worth33cc4002010-05-12 12:17:10 -0700202 }
203;
204
205replacement_list:
Carl Worth48b94da2010-05-13 10:46:29 -0700206 word_or_symbol {
Carl Worth610053b2010-05-14 10:05:11 -0700207 $$ = _string_list_create (parser);
208 _string_list_append_item ($$, $1);
Carl Worth48b94da2010-05-13 10:46:29 -0700209 talloc_free ($1);
Carl Worth33cc4002010-05-12 12:17:10 -0700210 }
Carl Worth0a93cbb2010-05-13 10:29:07 -0700211| replacement_list word_or_symbol {
Carl Worth610053b2010-05-14 10:05:11 -0700212 _string_list_append_item ($1, $2);
Carl Worth5070a202010-05-12 12:45:33 -0700213 talloc_free ($2);
Carl Worth33cc4002010-05-12 12:17:10 -0700214 $$ = $1;
215 }
216;
217
Carl Worthfcbbb462010-05-13 09:36:23 -0700218parameter_list:
219 /* empty */ {
Carl Worth610053b2010-05-14 10:05:11 -0700220 $$ = _string_list_create (parser);
Carl Worthfcbbb462010-05-13 09:36:23 -0700221 }
Carl Worth7f9aa362010-05-13 12:58:49 -0700222| identifier_perhaps_macro {
Carl Worth610053b2010-05-14 10:05:11 -0700223 $$ = _string_list_create (parser);
224 _string_list_append_item ($$, $1);
Carl Worthfcbbb462010-05-13 09:36:23 -0700225 talloc_free ($1);
226 }
Carl Worth7f9aa362010-05-13 12:58:49 -0700227| parameter_list ',' identifier_perhaps_macro {
Carl Worth610053b2010-05-14 10:05:11 -0700228 _string_list_append_item ($1, $3);
Carl Worthfcbbb462010-05-13 09:36:23 -0700229 talloc_free ($3);
230 $$ = $1;
231 }
232;
233
Carl Worth7f9aa362010-05-13 12:58:49 -0700234identifier_perhaps_macro:
235 IDENTIFIER { $$ = $1; }
236| FUNC_MACRO { $$ = $1; }
237| OBJ_MACRO { $$ = $1; }
238;
239
Carl Worth0a93cbb2010-05-13 10:29:07 -0700240word_or_symbol:
241 word { $$ = $1; }
242| '(' { $$ = xtalloc_strdup (parser, "("); }
243| ')' { $$ = xtalloc_strdup (parser, ")"); }
244| ',' { $$ = xtalloc_strdup (parser, ","); }
Carl Worth48b94da2010-05-13 10:46:29 -0700245| SPACE { $$ = xtalloc_strdup (parser, " "); }
Carl Worth0a93cbb2010-05-13 10:29:07 -0700246;
247
248word:
Carl Worth9f62a7e2010-05-13 07:38:29 -0700249 IDENTIFIER { $$ = $1; }
Carl Worthfcbbb462010-05-13 09:36:23 -0700250| FUNC_MACRO { $$ = $1; }
251| OBJ_MACRO { $$ = $1; }
Carl Worth9f62a7e2010-05-13 07:38:29 -0700252| TOKEN { $$ = $1; }
Carl Worth33cc4002010-05-12 12:17:10 -0700253;
254
255%%
256
Carl Worth610053b2010-05-14 10:05:11 -0700257string_list_t *
258_string_list_create (void *ctx)
Carl Worth33cc4002010-05-12 12:17:10 -0700259{
Carl Worth610053b2010-05-14 10:05:11 -0700260 string_list_t *list;
Carl Worth33cc4002010-05-12 12:17:10 -0700261
Carl Worth610053b2010-05-14 10:05:11 -0700262 list = xtalloc (ctx, string_list_t);
Carl Worth33cc4002010-05-12 12:17:10 -0700263 list->head = NULL;
264 list->tail = NULL;
265
266 return list;
Carl Worth0b27b5f2010-05-10 16:16:06 -0700267}
Carl Worth0b27b5f2010-05-10 16:16:06 -0700268
Carl Worth33cc4002010-05-12 12:17:10 -0700269void
Carl Worth610053b2010-05-14 10:05:11 -0700270_string_list_append_list (string_list_t *list, string_list_t *tail)
Carl Worthfcbbb462010-05-13 09:36:23 -0700271{
272 if (list->head == NULL) {
273 list->head = tail->head;
274 } else {
275 list->tail->next = tail->head;
276 }
277
278 list->tail = tail->tail;
279}
280
281void
Carl Worth610053b2010-05-14 10:05:11 -0700282_string_list_append_item (string_list_t *list, const char *str)
Carl Worth33cc4002010-05-12 12:17:10 -0700283{
Carl Worth610053b2010-05-14 10:05:11 -0700284 string_node_t *node;
Carl Worth3a37b872010-05-10 11:44:09 -0700285
Carl Worth610053b2010-05-14 10:05:11 -0700286 node = xtalloc (list, string_node_t);
Carl Worth5070a202010-05-12 12:45:33 -0700287 node->str = xtalloc_strdup (node, str);
Carl Worth33cc4002010-05-12 12:17:10 -0700288
289 node->next = NULL;
290
291 if (list->head == NULL) {
292 list->head = node;
293 } else {
294 list->tail->next = node;
295 }
296
297 list->tail = node;
298}
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700299
300int
Carl Worth610053b2010-05-14 10:05:11 -0700301_string_list_contains (string_list_t *list, const char *member, int *index)
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700302{
Carl Worth610053b2010-05-14 10:05:11 -0700303 string_node_t *node;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700304 int i;
305
306 if (list == NULL)
307 return 0;
308
309 for (i = 0, node = list->head; node; i++, node = node->next) {
310 if (strcmp (node->str, member) == 0) {
311 *index = i;
312 return 1;
313 }
314 }
315
316 return 0;
317}
318
319int
Carl Worth610053b2010-05-14 10:05:11 -0700320_string_list_length (string_list_t *list)
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700321{
322 int length = 0;
Carl Worth610053b2010-05-14 10:05:11 -0700323 string_node_t *node;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700324
325 if (list == NULL)
326 return 0;
327
328 for (node = list->head; node; node = node->next)
329 length++;
330
331 return length;
332}
333
Carl Worth2be8be02010-05-14 10:31:43 -0700334void
335_print_string_list (string_list_t *list)
336{
337 string_node_t *node;
338
339 if (list == NULL)
340 return;
341
342 for (node = list->head; node; node = node->next)
343 printf ("%s", node->str);
344}
345
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700346const char *
Carl Worth610053b2010-05-14 10:05:11 -0700347_string_list_member_at (string_list_t *list, int index)
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700348{
Carl Worth610053b2010-05-14 10:05:11 -0700349 string_node_t *node;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700350 int i;
351
352 if (list == NULL)
353 return NULL;
354
355 node = list->head;
356 for (i = 0; i < index; i++) {
357 node = node->next;
358 if (node == NULL)
359 break;
360 }
361
362 if (node)
363 return node->str;
364
365 return NULL;
366}
Carl Worth33cc4002010-05-12 12:17:10 -0700367
Carl Worth3a37b872010-05-10 11:44:09 -0700368void
Carl Wortha1e32bc2010-05-10 13:17:25 -0700369yyerror (void *scanner, const char *error)
Carl Worth3a37b872010-05-10 11:44:09 -0700370{
371 fprintf (stderr, "Parse error: %s\n", error);
372}
Carl Worth0b27b5f2010-05-10 16:16:06 -0700373
Carl Worth33cc4002010-05-12 12:17:10 -0700374glcpp_parser_t *
375glcpp_parser_create (void)
Carl Worth0b27b5f2010-05-10 16:16:06 -0700376{
Carl Worth33cc4002010-05-12 12:17:10 -0700377 glcpp_parser_t *parser;
378
Carl Worth5070a202010-05-12 12:45:33 -0700379 parser = xtalloc (NULL, glcpp_parser_t);
Carl Worth33cc4002010-05-12 12:17:10 -0700380
Carl Worth5070a202010-05-12 12:45:33 -0700381 yylex_init_extra (parser, &parser->scanner);
Carl Worth0b27b5f2010-05-10 16:16:06 -0700382 parser->defines = hash_table_ctor (32, hash_table_string_hash,
383 hash_table_string_compare);
Carl Worth33cc4002010-05-12 12:17:10 -0700384
385 return parser;
Carl Worth0b27b5f2010-05-10 16:16:06 -0700386}
387
388int
389glcpp_parser_parse (glcpp_parser_t *parser)
390{
391 return yyparse (parser);
392}
393
394void
Carl Worth33cc4002010-05-12 12:17:10 -0700395glcpp_parser_destroy (glcpp_parser_t *parser)
Carl Worth0b27b5f2010-05-10 16:16:06 -0700396{
397 yylex_destroy (parser->scanner);
398 hash_table_dtor (parser->defines);
Carl Worth33cc4002010-05-12 12:17:10 -0700399 talloc_free (parser);
Carl Worth0b27b5f2010-05-10 16:16:06 -0700400}
Carl Worthc6d5af32010-05-11 12:30:09 -0700401
Carl Worthfcbbb462010-05-13 09:36:23 -0700402macro_type_t
403glcpp_parser_macro_type (glcpp_parser_t *parser, const char *identifier)
Carl Worth9f62a7e2010-05-13 07:38:29 -0700404{
Carl Worthfcbbb462010-05-13 09:36:23 -0700405 macro_t *macro;
406
407 macro = hash_table_find (parser->defines, identifier);
408
409 if (macro == NULL)
410 return MACRO_TYPE_UNDEFINED;
411
412 if (macro->is_function)
413 return MACRO_TYPE_FUNCTION;
414 else
415 return MACRO_TYPE_OBJECT;
Carl Worth9f62a7e2010-05-13 07:38:29 -0700416}
417
Carl Worth33cc4002010-05-12 12:17:10 -0700418void
Carl Worthfcbbb462010-05-13 09:36:23 -0700419_define_object_macro (glcpp_parser_t *parser,
420 const char *identifier,
Carl Worthc5e98552010-05-14 10:12:21 -0700421 string_list_t *replacements)
Carl Worthfcbbb462010-05-13 09:36:23 -0700422{
423 macro_t *macro;
424
425 macro = xtalloc (parser, macro_t);
426
427 macro->is_function = 0;
Carl Worthc5e98552010-05-14 10:12:21 -0700428 macro->parameters = NULL;
429 macro->replacements = talloc_steal (macro, replacements);
Carl Worthfcbbb462010-05-13 09:36:23 -0700430
431 hash_table_insert (parser->defines, macro, identifier);
432}
433
434void
435_define_function_macro (glcpp_parser_t *parser,
436 const char *identifier,
Carl Worthc5e98552010-05-14 10:12:21 -0700437 string_list_t *parameters,
438 string_list_t *replacements)
Carl Worthfcbbb462010-05-13 09:36:23 -0700439{
440 macro_t *macro;
441
442 macro = xtalloc (parser, macro_t);
443
444 macro->is_function = 1;
Carl Worthc5e98552010-05-14 10:12:21 -0700445 macro->parameters = talloc_steal (macro, parameters);
446 macro->replacements = talloc_steal (macro, replacements);
Carl Worthfcbbb462010-05-13 09:36:23 -0700447
448 hash_table_insert (parser->defines, macro, identifier);
449}
450
Carl Worth2be8be02010-05-14 10:31:43 -0700451static string_list_t *
452_expand_macro_recursive (glcpp_parser_t *parser,
453 const char *token,
454 const char *orig,
455 string_list_t *parameters,
456 string_list_t *arguments);
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700457
Carl Worth2be8be02010-05-14 10:31:43 -0700458static string_list_t *
459_expand_string_list_recursive (glcpp_parser_t *parser,
460 string_list_t *list,
461 const char *orig,
462 string_list_t *parameters,
463 string_list_t *arguments)
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700464{
Carl Worth2be8be02010-05-14 10:31:43 -0700465 string_list_t *result;
466 string_list_t *child;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700467 const char *token;
Carl Worth610053b2010-05-14 10:05:11 -0700468 string_node_t *node;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700469 int index;
470
Carl Worth2be8be02010-05-14 10:31:43 -0700471 result = _string_list_create (parser);
472
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700473 for (node = list->head ; node ; node = node->next) {
474 token = node->str;
475
476 if (strcmp (token, orig) == 0) {
Carl Worth2be8be02010-05-14 10:31:43 -0700477 _string_list_append_item (result, token);
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700478 continue;
479 }
480
Carl Worth610053b2010-05-14 10:05:11 -0700481 if (_string_list_contains (parameters, token, &index)) {
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700482 const char *argument;
483
Carl Worth610053b2010-05-14 10:05:11 -0700484 argument = _string_list_member_at (arguments, index);
Carl Worth2be8be02010-05-14 10:31:43 -0700485 child = _expand_macro_recursive (parser, argument,
486 orig, NULL, NULL);
487 _string_list_append_list (result, child);
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700488 } else {
Carl Worth2be8be02010-05-14 10:31:43 -0700489 child = _expand_macro_recursive (parser, token,
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700490 orig, parameters,
491 arguments);
Carl Worth2be8be02010-05-14 10:31:43 -0700492 _string_list_append_list (result, child);
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700493 }
494 }
Carl Worth2be8be02010-05-14 10:31:43 -0700495
496 return result;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700497}
498
499
Carl Worth2be8be02010-05-14 10:31:43 -0700500static string_list_t *
501_expand_macro_recursive (glcpp_parser_t *parser,
502 const char *token,
503 const char *orig,
504 string_list_t *parameters,
505 string_list_t *arguments)
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700506{
507 macro_t *macro;
Carl Worthc5e98552010-05-14 10:12:21 -0700508 string_list_t *replacements;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700509
510 macro = hash_table_find (parser->defines, token);
511 if (macro == NULL) {
Carl Worth2be8be02010-05-14 10:31:43 -0700512 string_list_t *result;
513
514 result = _string_list_create (parser);
515 _string_list_append_item (result, token);
516 return result;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700517 }
518
Carl Worthc5e98552010-05-14 10:12:21 -0700519 replacements = macro->replacements;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700520
Carl Worth2be8be02010-05-14 10:31:43 -0700521 return _expand_string_list_recursive (parser, replacements,
522 orig, parameters, arguments);
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700523}
524
Carl Worth2be8be02010-05-14 10:31:43 -0700525string_list_t *
526_expand_object_macro (glcpp_parser_t *parser, const char *identifier)
Carl Worth33cc4002010-05-12 12:17:10 -0700527{
Carl Worthfcbbb462010-05-13 09:36:23 -0700528 macro_t *macro;
Carl Worth33cc4002010-05-12 12:17:10 -0700529
Carl Worthfcbbb462010-05-13 09:36:23 -0700530 macro = hash_table_find (parser->defines, identifier);
531 assert (! macro->is_function);
532
Carl Worth2be8be02010-05-14 10:31:43 -0700533 return _expand_macro_recursive (parser, identifier, identifier,
534 NULL, NULL);
Carl Worthfcbbb462010-05-13 09:36:23 -0700535}
536
Carl Worth2be8be02010-05-14 10:31:43 -0700537string_list_t *
538_expand_function_macro (glcpp_parser_t *parser,
539 const char *identifier,
540 string_list_t *arguments)
Carl Worthfcbbb462010-05-13 09:36:23 -0700541{
Carl Worth2be8be02010-05-14 10:31:43 -0700542 string_list_t *result;
Carl Worthfcbbb462010-05-13 09:36:23 -0700543 macro_t *macro;
544
Carl Worth2be8be02010-05-14 10:31:43 -0700545 result = _string_list_create (parser);
546
Carl Worthfcbbb462010-05-13 09:36:23 -0700547 macro = hash_table_find (parser->defines, identifier);
548 assert (macro->is_function);
549
Carl Worth2be8be02010-05-14 10:31:43 -0700550 if (_string_list_length (arguments) !=
551 _string_list_length (macro->parameters))
552 {
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700553 fprintf (stderr,
554 "Error: macro %s invoked with %d arguments (expected %d)\n",
555 identifier,
Carl Worth610053b2010-05-14 10:05:11 -0700556 _string_list_length (arguments),
Carl Worthc5e98552010-05-14 10:12:21 -0700557 _string_list_length (macro->parameters));
Carl Worth2be8be02010-05-14 10:31:43 -0700558 return NULL;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700559 }
Carl Worthfcbbb462010-05-13 09:36:23 -0700560
Carl Worth2be8be02010-05-14 10:31:43 -0700561 return _expand_macro_recursive (parser, identifier, identifier,
562 macro->parameters, arguments);
Carl Worth33cc4002010-05-12 12:17:10 -0700563}