blob: 27b5514e92828631e557813aface43ae1dd55e60 [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,
Carl Worth8f6a8282010-05-14 10:44:19 -070065 argument_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
Carl Worthdcc2ecd2010-05-13 12:56:42 -070082int
Carl Worth610053b2010-05-14 10:05:11 -070083_string_list_length (string_list_t *list);
Carl Worthdcc2ecd2010-05-13 12:56:42 -070084
Carl Worth8f6a8282010-05-14 10:44:19 -070085argument_list_t *
86_argument_list_create (void *ctx);
87
88void
89_argument_list_append (argument_list_t *list, string_list_t *argument);
90
91int
92_argument_list_length (argument_list_t *list);
93
94string_list_t *
95_argument_list_member_at (argument_list_t *list, int index);
96
Carl Worth3a37b872010-05-10 11:44:09 -070097%}
98
Carl Worth33cc4002010-05-12 12:17:10 -070099%union {
100 char *str;
Carl Worth8f6a8282010-05-14 10:44:19 -0700101 string_list_t *string_list;
102 argument_list_t *argument_list;
Carl Worth33cc4002010-05-12 12:17:10 -0700103}
104
Carl Worth0b27b5f2010-05-10 16:16:06 -0700105%parse-param {glcpp_parser_t *parser}
Carl Worth38aa8352010-05-10 11:52:29 -0700106%lex-param {void *scanner}
107
Carl Worth0a93cbb2010-05-13 10:29:07 -0700108%token DEFINE FUNC_MACRO IDENTIFIER NEWLINE OBJ_MACRO SPACE TOKEN UNDEF
Carl Worth7f9aa362010-05-13 12:58:49 -0700109%type <str> FUNC_MACRO IDENTIFIER identifier_perhaps_macro OBJ_MACRO TOKEN word word_or_symbol
Carl Worth8f6a8282010-05-14 10:44:19 -0700110%type <string_list> argument macro parameter_list replacement_list
111%type <argument_list> argument_list
Carl Worth3a37b872010-05-10 11:44:09 -0700112
113%%
114
Carl Worth33cc4002010-05-12 12:17:10 -0700115input:
116 /* empty */
Carl Worth8bcb6f12010-05-12 13:21:20 -0700117| input content
Carl Worth3a37b872010-05-10 11:44:09 -0700118;
119
Carl Worth04af1352010-05-14 10:17:38 -0700120 /* We do all printing at the content level */
Carl Worth33cc4002010-05-12 12:17:10 -0700121content:
Carl Worth9f62a7e2010-05-13 07:38:29 -0700122 IDENTIFIER {
123 printf ("%s", $1);
124 talloc_free ($1);
125 }
126| TOKEN {
127 printf ("%s", $1);
128 talloc_free ($1);
129 }
Carl Worth2be8be02010-05-14 10:31:43 -0700130| macro {
131 _print_string_list ($1);
132 }
Carl Worth04af1352010-05-14 10:17:38 -0700133| directive_with_newline { printf ("\n"); }
Carl Worth0a93cbb2010-05-13 10:29:07 -0700134| NEWLINE { printf ("\n"); }
135| '(' { printf ("("); }
136| ')' { printf (")"); }
137| ',' { printf (","); }
Carl Worth48b94da2010-05-13 10:46:29 -0700138| SPACE { printf (" "); }
Carl Worthcd27e642010-05-12 13:11:50 -0700139;
140
Carl Worthfcbbb462010-05-13 09:36:23 -0700141macro:
142 FUNC_MACRO '(' argument_list ')' {
Carl Worth2be8be02010-05-14 10:31:43 -0700143 $$ = _expand_function_macro (parser, $1, $3);
Carl Worthfcbbb462010-05-13 09:36:23 -0700144 }
145| OBJ_MACRO {
Carl Worth2be8be02010-05-14 10:31:43 -0700146 $$ = _expand_object_macro (parser, $1);
Carl Worthfcbbb462010-05-13 09:36:23 -0700147 talloc_free ($1);
148 }
149;
150
151argument_list:
Carl Worthdb35d552010-05-14 08:47:32 -0700152 argument {
Carl Worth8f6a8282010-05-14 10:44:19 -0700153 $$ = _argument_list_create (parser);
154 _argument_list_append ($$, $1);
155 }
156| argument_list ',' SPACE argument {
157 _argument_list_append ($1, $4);
158 $$ = $1;
Carl Worthfcbbb462010-05-13 09:36:23 -0700159 }
160| argument_list ',' argument {
Carl Worth8f6a8282010-05-14 10:44:19 -0700161 _argument_list_append ($1, $3);
Carl Worthfcbbb462010-05-13 09:36:23 -0700162 $$ = $1;
163 }
164;
165
166argument:
167 /* empty */ {
Carl Worth610053b2010-05-14 10:05:11 -0700168 $$ = _string_list_create (parser);
Carl Worthfcbbb462010-05-13 09:36:23 -0700169 }
Carl Worth0a93cbb2010-05-13 10:29:07 -0700170| argument word {
Carl Worth610053b2010-05-14 10:05:11 -0700171 _string_list_append_item ($1, $2);
Carl Worthfcbbb462010-05-13 09:36:23 -0700172 talloc_free ($2);
173 }
Carl Worth8f6a8282010-05-14 10:44:19 -0700174| argument SPACE word {
175 _string_list_append_item ($1, " ");
176 _string_list_append_item ($1, $3);
177 talloc_free ($3);
178 }
Carl Worthfcbbb462010-05-13 09:36:23 -0700179| argument '(' argument ')'
180;
181
Carl Worthcd27e642010-05-12 13:11:50 -0700182directive_with_newline:
Carl Worth04af1352010-05-14 10:17:38 -0700183 directive NEWLINE
Carl Worth3a37b872010-05-10 11:44:09 -0700184;
185
Carl Worth33cc4002010-05-12 12:17:10 -0700186directive:
Carl Worth0a93cbb2010-05-13 10:29:07 -0700187 DEFINE IDENTIFIER {
Carl Worth610053b2010-05-14 10:05:11 -0700188 string_list_t *list = _string_list_create (parser);
Carl Worth0a93cbb2010-05-13 10:29:07 -0700189 _define_object_macro (parser, $2, list);
190 }
191| DEFINE IDENTIFIER SPACE replacement_list {
192 _define_object_macro (parser, $2, $4);
Carl Worthcd27e642010-05-12 13:11:50 -0700193 }
Carl Worth48b94da2010-05-13 10:46:29 -0700194| DEFINE IDENTIFIER '(' parameter_list ')' {
Carl Worth610053b2010-05-14 10:05:11 -0700195 string_list_t *list = _string_list_create (parser);
Carl Worth48b94da2010-05-13 10:46:29 -0700196 _define_function_macro (parser, $2, $4, list);
197 }
198| DEFINE IDENTIFIER '(' parameter_list ')' SPACE replacement_list {
199 _define_function_macro (parser, $2, $4, $7);
Carl Worthfcbbb462010-05-13 09:36:23 -0700200 }
201| UNDEF FUNC_MACRO {
Carl Worth610053b2010-05-14 10:05:11 -0700202 string_list_t *replacement = hash_table_find (parser->defines, $2);
Carl Worthfcbbb462010-05-13 09:36:23 -0700203 if (replacement) {
204 /* XXX: Need hash table to support a real way
205 * to remove an element rather than prefixing
206 * a new node with data of NULL like this. */
207 hash_table_insert (parser->defines, NULL, $2);
208 talloc_free (replacement);
209 }
210 talloc_free ($2);
211 }
212| UNDEF OBJ_MACRO {
Carl Worth610053b2010-05-14 10:05:11 -0700213 string_list_t *replacement = hash_table_find (parser->defines, $2);
Carl Worthcd27e642010-05-12 13:11:50 -0700214 if (replacement) {
215 /* XXX: Need hash table to support a real way
216 * to remove an element rather than prefixing
217 * a new node with data of NULL like this. */
218 hash_table_insert (parser->defines, NULL, $2);
219 talloc_free (replacement);
220 }
221 talloc_free ($2);
Carl Worth33cc4002010-05-12 12:17:10 -0700222 }
223;
224
225replacement_list:
Carl Worth48b94da2010-05-13 10:46:29 -0700226 word_or_symbol {
Carl Worth610053b2010-05-14 10:05:11 -0700227 $$ = _string_list_create (parser);
228 _string_list_append_item ($$, $1);
Carl Worth48b94da2010-05-13 10:46:29 -0700229 talloc_free ($1);
Carl Worth33cc4002010-05-12 12:17:10 -0700230 }
Carl Worth0a93cbb2010-05-13 10:29:07 -0700231| replacement_list word_or_symbol {
Carl Worth610053b2010-05-14 10:05:11 -0700232 _string_list_append_item ($1, $2);
Carl Worth5070a202010-05-12 12:45:33 -0700233 talloc_free ($2);
Carl Worth33cc4002010-05-12 12:17:10 -0700234 $$ = $1;
235 }
236;
237
Carl Worthfcbbb462010-05-13 09:36:23 -0700238parameter_list:
239 /* empty */ {
Carl Worth610053b2010-05-14 10:05:11 -0700240 $$ = _string_list_create (parser);
Carl Worthfcbbb462010-05-13 09:36:23 -0700241 }
Carl Worth7f9aa362010-05-13 12:58:49 -0700242| identifier_perhaps_macro {
Carl Worth610053b2010-05-14 10:05:11 -0700243 $$ = _string_list_create (parser);
244 _string_list_append_item ($$, $1);
Carl Worthfcbbb462010-05-13 09:36:23 -0700245 talloc_free ($1);
246 }
Carl Worth7f9aa362010-05-13 12:58:49 -0700247| parameter_list ',' identifier_perhaps_macro {
Carl Worth610053b2010-05-14 10:05:11 -0700248 _string_list_append_item ($1, $3);
Carl Worthfcbbb462010-05-13 09:36:23 -0700249 talloc_free ($3);
250 $$ = $1;
251 }
252;
253
Carl Worth7f9aa362010-05-13 12:58:49 -0700254identifier_perhaps_macro:
255 IDENTIFIER { $$ = $1; }
256| FUNC_MACRO { $$ = $1; }
257| OBJ_MACRO { $$ = $1; }
258;
259
Carl Worth0a93cbb2010-05-13 10:29:07 -0700260word_or_symbol:
261 word { $$ = $1; }
262| '(' { $$ = xtalloc_strdup (parser, "("); }
263| ')' { $$ = xtalloc_strdup (parser, ")"); }
264| ',' { $$ = xtalloc_strdup (parser, ","); }
Carl Worth48b94da2010-05-13 10:46:29 -0700265| SPACE { $$ = xtalloc_strdup (parser, " "); }
Carl Worth0a93cbb2010-05-13 10:29:07 -0700266;
267
268word:
Carl Worth9f62a7e2010-05-13 07:38:29 -0700269 IDENTIFIER { $$ = $1; }
Carl Worthfcbbb462010-05-13 09:36:23 -0700270| FUNC_MACRO { $$ = $1; }
271| OBJ_MACRO { $$ = $1; }
Carl Worth9f62a7e2010-05-13 07:38:29 -0700272| TOKEN { $$ = $1; }
Carl Worth33cc4002010-05-12 12:17:10 -0700273;
274
275%%
276
Carl Worth610053b2010-05-14 10:05:11 -0700277string_list_t *
278_string_list_create (void *ctx)
Carl Worth33cc4002010-05-12 12:17:10 -0700279{
Carl Worth610053b2010-05-14 10:05:11 -0700280 string_list_t *list;
Carl Worth33cc4002010-05-12 12:17:10 -0700281
Carl Worth610053b2010-05-14 10:05:11 -0700282 list = xtalloc (ctx, string_list_t);
Carl Worth33cc4002010-05-12 12:17:10 -0700283 list->head = NULL;
284 list->tail = NULL;
285
286 return list;
Carl Worth0b27b5f2010-05-10 16:16:06 -0700287}
Carl Worth0b27b5f2010-05-10 16:16:06 -0700288
Carl Worth33cc4002010-05-12 12:17:10 -0700289void
Carl Worth610053b2010-05-14 10:05:11 -0700290_string_list_append_list (string_list_t *list, string_list_t *tail)
Carl Worthfcbbb462010-05-13 09:36:23 -0700291{
292 if (list->head == NULL) {
293 list->head = tail->head;
294 } else {
295 list->tail->next = tail->head;
296 }
297
298 list->tail = tail->tail;
299}
300
301void
Carl Worth610053b2010-05-14 10:05:11 -0700302_string_list_append_item (string_list_t *list, const char *str)
Carl Worth33cc4002010-05-12 12:17:10 -0700303{
Carl Worth610053b2010-05-14 10:05:11 -0700304 string_node_t *node;
Carl Worth3a37b872010-05-10 11:44:09 -0700305
Carl Worth610053b2010-05-14 10:05:11 -0700306 node = xtalloc (list, string_node_t);
Carl Worth5070a202010-05-12 12:45:33 -0700307 node->str = xtalloc_strdup (node, str);
Carl Worth33cc4002010-05-12 12:17:10 -0700308
309 node->next = NULL;
310
311 if (list->head == NULL) {
312 list->head = node;
313 } else {
314 list->tail->next = node;
315 }
316
317 list->tail = node;
318}
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700319
320int
Carl Worth610053b2010-05-14 10:05:11 -0700321_string_list_contains (string_list_t *list, const char *member, int *index)
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700322{
Carl Worth610053b2010-05-14 10:05:11 -0700323 string_node_t *node;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700324 int i;
325
326 if (list == NULL)
327 return 0;
328
329 for (i = 0, node = list->head; node; i++, node = node->next) {
330 if (strcmp (node->str, member) == 0) {
331 *index = i;
332 return 1;
333 }
334 }
335
336 return 0;
337}
338
339int
Carl Worth610053b2010-05-14 10:05:11 -0700340_string_list_length (string_list_t *list)
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700341{
342 int length = 0;
Carl Worth610053b2010-05-14 10:05:11 -0700343 string_node_t *node;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700344
345 if (list == NULL)
346 return 0;
347
348 for (node = list->head; node; node = node->next)
349 length++;
350
351 return length;
352}
353
Carl Worth2be8be02010-05-14 10:31:43 -0700354void
355_print_string_list (string_list_t *list)
356{
357 string_node_t *node;
358
359 if (list == NULL)
360 return;
361
362 for (node = list->head; node; node = node->next)
363 printf ("%s", node->str);
364}
365
Carl Worth8f6a8282010-05-14 10:44:19 -0700366argument_list_t *
367_argument_list_create (void *ctx)
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700368{
Carl Worth8f6a8282010-05-14 10:44:19 -0700369 argument_list_t *list;
370
371 list = xtalloc (ctx, argument_list_t);
372 list->head = NULL;
373 list->tail = NULL;
374
375 return list;
376}
377
378void
379_argument_list_append (argument_list_t *list, string_list_t *argument)
380{
381 argument_node_t *node;
382
383 if (argument == NULL || argument->head == NULL)
384 return;
385
386 node = xtalloc (list, argument_node_t);
387 node->argument = argument;
388
389 node->next = NULL;
390
391 if (list->head == NULL) {
392 list->head = node;
393 } else {
394 list->tail->next = node;
395 }
396
397 list->tail = node;
398}
399
400int
401_argument_list_length (argument_list_t *list)
402{
403 int length = 0;
404 argument_node_t *node;
405
406 if (list == NULL)
407 return 0;
408
409 for (node = list->head; node; node = node->next)
410 length++;
411
412 return length;
413}
414
415string_list_t *
416_argument_list_member_at (argument_list_t *list, int index)
417{
418 argument_node_t *node;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700419 int i;
420
421 if (list == NULL)
422 return NULL;
423
424 node = list->head;
425 for (i = 0; i < index; i++) {
426 node = node->next;
427 if (node == NULL)
428 break;
429 }
430
431 if (node)
Carl Worth8f6a8282010-05-14 10:44:19 -0700432 return node->argument;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700433
434 return NULL;
435}
Carl Worth33cc4002010-05-12 12:17:10 -0700436
Carl Worth3a37b872010-05-10 11:44:09 -0700437void
Carl Wortha1e32bc2010-05-10 13:17:25 -0700438yyerror (void *scanner, const char *error)
Carl Worth3a37b872010-05-10 11:44:09 -0700439{
440 fprintf (stderr, "Parse error: %s\n", error);
441}
Carl Worth0b27b5f2010-05-10 16:16:06 -0700442
Carl Worth33cc4002010-05-12 12:17:10 -0700443glcpp_parser_t *
444glcpp_parser_create (void)
Carl Worth0b27b5f2010-05-10 16:16:06 -0700445{
Carl Worth33cc4002010-05-12 12:17:10 -0700446 glcpp_parser_t *parser;
447
Carl Worth5070a202010-05-12 12:45:33 -0700448 parser = xtalloc (NULL, glcpp_parser_t);
Carl Worth33cc4002010-05-12 12:17:10 -0700449
Carl Worth5070a202010-05-12 12:45:33 -0700450 yylex_init_extra (parser, &parser->scanner);
Carl Worth0b27b5f2010-05-10 16:16:06 -0700451 parser->defines = hash_table_ctor (32, hash_table_string_hash,
452 hash_table_string_compare);
Carl Worth33cc4002010-05-12 12:17:10 -0700453
454 return parser;
Carl Worth0b27b5f2010-05-10 16:16:06 -0700455}
456
457int
458glcpp_parser_parse (glcpp_parser_t *parser)
459{
460 return yyparse (parser);
461}
462
463void
Carl Worth33cc4002010-05-12 12:17:10 -0700464glcpp_parser_destroy (glcpp_parser_t *parser)
Carl Worth0b27b5f2010-05-10 16:16:06 -0700465{
466 yylex_destroy (parser->scanner);
467 hash_table_dtor (parser->defines);
Carl Worth33cc4002010-05-12 12:17:10 -0700468 talloc_free (parser);
Carl Worth0b27b5f2010-05-10 16:16:06 -0700469}
Carl Worthc6d5af32010-05-11 12:30:09 -0700470
Carl Worthfcbbb462010-05-13 09:36:23 -0700471macro_type_t
472glcpp_parser_macro_type (glcpp_parser_t *parser, const char *identifier)
Carl Worth9f62a7e2010-05-13 07:38:29 -0700473{
Carl Worthfcbbb462010-05-13 09:36:23 -0700474 macro_t *macro;
475
476 macro = hash_table_find (parser->defines, identifier);
477
478 if (macro == NULL)
479 return MACRO_TYPE_UNDEFINED;
480
481 if (macro->is_function)
482 return MACRO_TYPE_FUNCTION;
483 else
484 return MACRO_TYPE_OBJECT;
Carl Worth9f62a7e2010-05-13 07:38:29 -0700485}
486
Carl Worth33cc4002010-05-12 12:17:10 -0700487void
Carl Worthfcbbb462010-05-13 09:36:23 -0700488_define_object_macro (glcpp_parser_t *parser,
489 const char *identifier,
Carl Worthc5e98552010-05-14 10:12:21 -0700490 string_list_t *replacements)
Carl Worthfcbbb462010-05-13 09:36:23 -0700491{
492 macro_t *macro;
493
494 macro = xtalloc (parser, macro_t);
495
496 macro->is_function = 0;
Carl Worthc5e98552010-05-14 10:12:21 -0700497 macro->parameters = NULL;
498 macro->replacements = talloc_steal (macro, replacements);
Carl Worthfcbbb462010-05-13 09:36:23 -0700499
500 hash_table_insert (parser->defines, macro, identifier);
501}
502
503void
504_define_function_macro (glcpp_parser_t *parser,
505 const char *identifier,
Carl Worthc5e98552010-05-14 10:12:21 -0700506 string_list_t *parameters,
507 string_list_t *replacements)
Carl Worthfcbbb462010-05-13 09:36:23 -0700508{
509 macro_t *macro;
510
511 macro = xtalloc (parser, macro_t);
512
513 macro->is_function = 1;
Carl Worthc5e98552010-05-14 10:12:21 -0700514 macro->parameters = talloc_steal (macro, parameters);
515 macro->replacements = talloc_steal (macro, replacements);
Carl Worthfcbbb462010-05-13 09:36:23 -0700516
517 hash_table_insert (parser->defines, macro, identifier);
518}
519
Carl Worth2be8be02010-05-14 10:31:43 -0700520static string_list_t *
521_expand_macro_recursive (glcpp_parser_t *parser,
522 const char *token,
523 const char *orig,
524 string_list_t *parameters,
Carl Worth8f6a8282010-05-14 10:44:19 -0700525 argument_list_t *arguments);
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700526
Carl Worth2be8be02010-05-14 10:31:43 -0700527static string_list_t *
528_expand_string_list_recursive (glcpp_parser_t *parser,
529 string_list_t *list,
530 const char *orig,
531 string_list_t *parameters,
Carl Worth8f6a8282010-05-14 10:44:19 -0700532 argument_list_t *arguments)
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700533{
Carl Worth2be8be02010-05-14 10:31:43 -0700534 string_list_t *result;
535 string_list_t *child;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700536 const char *token;
Carl Worth610053b2010-05-14 10:05:11 -0700537 string_node_t *node;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700538 int index;
539
Carl Worth2be8be02010-05-14 10:31:43 -0700540 result = _string_list_create (parser);
541
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700542 for (node = list->head ; node ; node = node->next) {
543 token = node->str;
544
545 if (strcmp (token, orig) == 0) {
Carl Worth2be8be02010-05-14 10:31:43 -0700546 _string_list_append_item (result, token);
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700547 continue;
548 }
549
Carl Worth610053b2010-05-14 10:05:11 -0700550 if (_string_list_contains (parameters, token, &index)) {
Carl Worth8f6a8282010-05-14 10:44:19 -0700551 string_list_t *argument;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700552
Carl Worth8f6a8282010-05-14 10:44:19 -0700553 argument = _argument_list_member_at (arguments, index);
554 child = _expand_string_list_recursive (parser, argument,
555 orig, NULL, NULL);
Carl Worth2be8be02010-05-14 10:31:43 -0700556 _string_list_append_list (result, child);
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700557 } else {
Carl Worth2be8be02010-05-14 10:31:43 -0700558 child = _expand_macro_recursive (parser, token,
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700559 orig, parameters,
560 arguments);
Carl Worth2be8be02010-05-14 10:31:43 -0700561 _string_list_append_list (result, child);
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700562 }
563 }
Carl Worth2be8be02010-05-14 10:31:43 -0700564
565 return result;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700566}
567
568
Carl Worth2be8be02010-05-14 10:31:43 -0700569static string_list_t *
570_expand_macro_recursive (glcpp_parser_t *parser,
571 const char *token,
572 const char *orig,
573 string_list_t *parameters,
Carl Worth8f6a8282010-05-14 10:44:19 -0700574 argument_list_t *arguments)
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700575{
576 macro_t *macro;
Carl Worthc5e98552010-05-14 10:12:21 -0700577 string_list_t *replacements;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700578
579 macro = hash_table_find (parser->defines, token);
580 if (macro == NULL) {
Carl Worth2be8be02010-05-14 10:31:43 -0700581 string_list_t *result;
582
583 result = _string_list_create (parser);
584 _string_list_append_item (result, token);
585 return result;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700586 }
587
Carl Worthc5e98552010-05-14 10:12:21 -0700588 replacements = macro->replacements;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700589
Carl Worth2be8be02010-05-14 10:31:43 -0700590 return _expand_string_list_recursive (parser, replacements,
591 orig, parameters, arguments);
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700592}
593
Carl Worth2be8be02010-05-14 10:31:43 -0700594string_list_t *
595_expand_object_macro (glcpp_parser_t *parser, const char *identifier)
Carl Worth33cc4002010-05-12 12:17:10 -0700596{
Carl Worthfcbbb462010-05-13 09:36:23 -0700597 macro_t *macro;
Carl Worth33cc4002010-05-12 12:17:10 -0700598
Carl Worthfcbbb462010-05-13 09:36:23 -0700599 macro = hash_table_find (parser->defines, identifier);
600 assert (! macro->is_function);
601
Carl Worth2be8be02010-05-14 10:31:43 -0700602 return _expand_macro_recursive (parser, identifier, identifier,
603 NULL, NULL);
Carl Worthfcbbb462010-05-13 09:36:23 -0700604}
605
Carl Worth2be8be02010-05-14 10:31:43 -0700606string_list_t *
607_expand_function_macro (glcpp_parser_t *parser,
608 const char *identifier,
Carl Worth8f6a8282010-05-14 10:44:19 -0700609 argument_list_t *arguments)
Carl Worthfcbbb462010-05-13 09:36:23 -0700610{
Carl Worth2be8be02010-05-14 10:31:43 -0700611 string_list_t *result;
Carl Worthfcbbb462010-05-13 09:36:23 -0700612 macro_t *macro;
613
Carl Worth2be8be02010-05-14 10:31:43 -0700614 result = _string_list_create (parser);
615
Carl Worthfcbbb462010-05-13 09:36:23 -0700616 macro = hash_table_find (parser->defines, identifier);
617 assert (macro->is_function);
618
Carl Worth8f6a8282010-05-14 10:44:19 -0700619 if (_argument_list_length (arguments) !=
Carl Worth2be8be02010-05-14 10:31:43 -0700620 _string_list_length (macro->parameters))
621 {
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700622 fprintf (stderr,
623 "Error: macro %s invoked with %d arguments (expected %d)\n",
624 identifier,
Carl Worth8f6a8282010-05-14 10:44:19 -0700625 _argument_list_length (arguments),
Carl Worthc5e98552010-05-14 10:12:21 -0700626 _string_list_length (macro->parameters));
Carl Worth2be8be02010-05-14 10:31:43 -0700627 return NULL;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700628 }
Carl Worthfcbbb462010-05-13 09:36:23 -0700629
Carl Worth2be8be02010-05-14 10:31:43 -0700630 return _expand_macro_recursive (parser, identifier, identifier,
631 macro->parameters, arguments);
Carl Worth33cc4002010-05-12 12:17:10 -0700632}