blob: 959083578e7121edb34505e3fc56a165d01e677b [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 Worth420d05a2010-05-17 10:15:23 -070079void
80_string_list_push (string_list_t *list, const char *str);
81
82void
83_string_list_pop (string_list_t *list);
84
Carl Worthdcc2ecd2010-05-13 12:56:42 -070085int
Carl Worth610053b2010-05-14 10:05:11 -070086_string_list_contains (string_list_t *list, const char *member, int *index);
Carl Worthdcc2ecd2010-05-13 12:56:42 -070087
Carl Worthdcc2ecd2010-05-13 12:56:42 -070088int
Carl Worth610053b2010-05-14 10:05:11 -070089_string_list_length (string_list_t *list);
Carl Worthdcc2ecd2010-05-13 12:56:42 -070090
Carl Worth8f6a8282010-05-14 10:44:19 -070091argument_list_t *
92_argument_list_create (void *ctx);
93
94void
95_argument_list_append (argument_list_t *list, string_list_t *argument);
96
97int
98_argument_list_length (argument_list_t *list);
99
100string_list_t *
101_argument_list_member_at (argument_list_t *list, int index);
102
Carl Worth3a37b872010-05-10 11:44:09 -0700103%}
104
Carl Worth33cc4002010-05-12 12:17:10 -0700105%union {
106 char *str;
Carl Worth8f6a8282010-05-14 10:44:19 -0700107 string_list_t *string_list;
108 argument_list_t *argument_list;
Carl Worth33cc4002010-05-12 12:17:10 -0700109}
110
Carl Worth0b27b5f2010-05-10 16:16:06 -0700111%parse-param {glcpp_parser_t *parser}
Carl Worth38aa8352010-05-10 11:52:29 -0700112%lex-param {void *scanner}
113
Carl Worth0a93cbb2010-05-13 10:29:07 -0700114%token DEFINE FUNC_MACRO IDENTIFIER NEWLINE OBJ_MACRO SPACE TOKEN UNDEF
Carl Worth38bd27b2010-05-14 12:05:37 -0700115%type <str> FUNC_MACRO IDENTIFIER identifier_perhaps_macro OBJ_MACRO replacement_word TOKEN word
Carl Worth8f6a8282010-05-14 10:44:19 -0700116%type <string_list> argument macro parameter_list replacement_list
117%type <argument_list> argument_list
Carl Worth3a37b872010-05-10 11:44:09 -0700118
Carl Worth796e1f02010-05-17 12:45:16 -0700119/* Hard to remove shift/reduce conflicts documented as follows:
120 *
121 * 1. '(' after FUNC_MACRO name which is correctly resolved to shift
122 * to form macro invocation rather than reducing directly to
123 * content.
124 */
125%expect 1
126
Carl Worth3a37b872010-05-10 11:44:09 -0700127%%
128
Carl Worth33cc4002010-05-12 12:17:10 -0700129input:
130 /* empty */
Carl Worth8bcb6f12010-05-12 13:21:20 -0700131| input content
Carl Worth3a37b872010-05-10 11:44:09 -0700132;
133
Carl Worth04af1352010-05-14 10:17:38 -0700134 /* We do all printing at the content level */
Carl Worth33cc4002010-05-12 12:17:10 -0700135content:
Carl Worth9f62a7e2010-05-13 07:38:29 -0700136 IDENTIFIER {
137 printf ("%s", $1);
138 talloc_free ($1);
139 }
140| TOKEN {
141 printf ("%s", $1);
142 talloc_free ($1);
143 }
Carl Worthacf87bc2010-05-17 10:34:29 -0700144| FUNC_MACRO {
145 printf ("%s", $1);
146 talloc_free ($1);
147 }
Carl Worth2be8be02010-05-14 10:31:43 -0700148| macro {
149 _print_string_list ($1);
150 }
Carl Worth04af1352010-05-14 10:17:38 -0700151| directive_with_newline { printf ("\n"); }
Carl Worth0a93cbb2010-05-13 10:29:07 -0700152| NEWLINE { printf ("\n"); }
153| '(' { printf ("("); }
154| ')' { printf (")"); }
155| ',' { printf (","); }
Carl Worthcd27e642010-05-12 13:11:50 -0700156;
157
Carl Worthfcbbb462010-05-13 09:36:23 -0700158macro:
159 FUNC_MACRO '(' argument_list ')' {
Carl Worth2be8be02010-05-14 10:31:43 -0700160 $$ = _expand_function_macro (parser, $1, $3);
Carl Worthfcbbb462010-05-13 09:36:23 -0700161 }
162| OBJ_MACRO {
Carl Worth2be8be02010-05-14 10:31:43 -0700163 $$ = _expand_object_macro (parser, $1);
Carl Worthfcbbb462010-05-13 09:36:23 -0700164 talloc_free ($1);
165 }
166;
167
168argument_list:
Carl Worthac070e82010-05-14 11:33:00 -0700169 /* empty */ {
170 $$ = _argument_list_create (parser);
171 }
172| argument {
Carl Worth8f6a8282010-05-14 10:44:19 -0700173 $$ = _argument_list_create (parser);
174 _argument_list_append ($$, $1);
175 }
Carl Worthfcbbb462010-05-13 09:36:23 -0700176| argument_list ',' argument {
Carl Worth8f6a8282010-05-14 10:44:19 -0700177 _argument_list_append ($1, $3);
Carl Worthfcbbb462010-05-13 09:36:23 -0700178 $$ = $1;
179 }
180;
181
182argument:
Carl Worthac070e82010-05-14 11:33:00 -0700183 word {
Carl Worth610053b2010-05-14 10:05:11 -0700184 $$ = _string_list_create (parser);
Carl Worthac070e82010-05-14 11:33:00 -0700185 _string_list_append_item ($$, $1);
Carl Worthfcbbb462010-05-13 09:36:23 -0700186 }
Carl Worth38bd27b2010-05-14 12:05:37 -0700187| macro {
188 $$ = $1;
189 }
Carl Worth0a93cbb2010-05-13 10:29:07 -0700190| argument word {
Carl Worth610053b2010-05-14 10:05:11 -0700191 _string_list_append_item ($1, $2);
Carl Worthfcbbb462010-05-13 09:36:23 -0700192 talloc_free ($2);
Carl Worth3596bb12010-05-14 16:53:52 -0700193 $$ = $1;
Carl Worthfcbbb462010-05-13 09:36:23 -0700194 }
Carl Worth3596bb12010-05-14 16:53:52 -0700195| argument '(' argument ')' {
196 _string_list_append_item ($1, "(");
197 _string_list_append_list ($1, $3);
198 _string_list_append_item ($1, ")");
199 $$ = $1;
200 }
Carl Worthfcbbb462010-05-13 09:36:23 -0700201;
202
Carl Worthcd27e642010-05-12 13:11:50 -0700203directive_with_newline:
Carl Worth04af1352010-05-14 10:17:38 -0700204 directive NEWLINE
Carl Worth3a37b872010-05-10 11:44:09 -0700205;
206
Carl Worth33cc4002010-05-12 12:17:10 -0700207directive:
Carl Worth0a93cbb2010-05-13 10:29:07 -0700208 DEFINE IDENTIFIER {
Carl Worth610053b2010-05-14 10:05:11 -0700209 string_list_t *list = _string_list_create (parser);
Carl Worth0a93cbb2010-05-13 10:29:07 -0700210 _define_object_macro (parser, $2, list);
211 }
212| DEFINE IDENTIFIER SPACE replacement_list {
213 _define_object_macro (parser, $2, $4);
Carl Worthcd27e642010-05-12 13:11:50 -0700214 }
Carl Worth48b94da2010-05-13 10:46:29 -0700215| DEFINE IDENTIFIER '(' parameter_list ')' {
Carl Worth610053b2010-05-14 10:05:11 -0700216 string_list_t *list = _string_list_create (parser);
Carl Worth48b94da2010-05-13 10:46:29 -0700217 _define_function_macro (parser, $2, $4, list);
218 }
Carl Worth81f01432010-05-14 17:08:45 -0700219| DEFINE IDENTIFIER '(' parameter_list ')' replacement_list {
220 _define_function_macro (parser, $2, $4, $6);
Carl Worthfcbbb462010-05-13 09:36:23 -0700221 }
222| UNDEF FUNC_MACRO {
Carl Worth610053b2010-05-14 10:05:11 -0700223 string_list_t *replacement = hash_table_find (parser->defines, $2);
Carl Worthfcbbb462010-05-13 09:36:23 -0700224 if (replacement) {
225 /* XXX: Need hash table to support a real way
226 * to remove an element rather than prefixing
227 * a new node with data of NULL like this. */
228 hash_table_insert (parser->defines, NULL, $2);
229 talloc_free (replacement);
230 }
231 talloc_free ($2);
232 }
233| UNDEF OBJ_MACRO {
Carl Worth610053b2010-05-14 10:05:11 -0700234 string_list_t *replacement = hash_table_find (parser->defines, $2);
Carl Worthcd27e642010-05-12 13:11:50 -0700235 if (replacement) {
236 /* XXX: Need hash table to support a real way
237 * to remove an element rather than prefixing
238 * a new node with data of NULL like this. */
239 hash_table_insert (parser->defines, NULL, $2);
240 talloc_free (replacement);
241 }
242 talloc_free ($2);
Carl Worth33cc4002010-05-12 12:17:10 -0700243 }
244;
245
246replacement_list:
Carl Worth38bd27b2010-05-14 12:05:37 -0700247 replacement_word {
Carl Worth610053b2010-05-14 10:05:11 -0700248 $$ = _string_list_create (parser);
249 _string_list_append_item ($$, $1);
Carl Worth48b94da2010-05-13 10:46:29 -0700250 talloc_free ($1);
Carl Worth33cc4002010-05-12 12:17:10 -0700251 }
Carl Worth38bd27b2010-05-14 12:05:37 -0700252| replacement_list replacement_word {
Carl Worth610053b2010-05-14 10:05:11 -0700253 _string_list_append_item ($1, $2);
Carl Worth5070a202010-05-12 12:45:33 -0700254 talloc_free ($2);
Carl Worth33cc4002010-05-12 12:17:10 -0700255 $$ = $1;
256 }
257;
258
Carl Worth38bd27b2010-05-14 12:05:37 -0700259replacement_word:
260 word { $$ = $1; }
261| FUNC_MACRO { $$ = $1; }
262| OBJ_MACRO { $$ = $1; }
263| '(' { $$ = xtalloc_strdup (parser, "("); }
264| ')' { $$ = xtalloc_strdup (parser, ")"); }
265| ',' { $$ = xtalloc_strdup (parser, ","); }
Carl Worth38bd27b2010-05-14 12:05:37 -0700266;
267
Carl Worthfcbbb462010-05-13 09:36:23 -0700268parameter_list:
269 /* empty */ {
Carl Worth610053b2010-05-14 10:05:11 -0700270 $$ = _string_list_create (parser);
Carl Worthfcbbb462010-05-13 09:36:23 -0700271 }
Carl Worth7f9aa362010-05-13 12:58:49 -0700272| identifier_perhaps_macro {
Carl Worth610053b2010-05-14 10:05:11 -0700273 $$ = _string_list_create (parser);
274 _string_list_append_item ($$, $1);
Carl Worthfcbbb462010-05-13 09:36:23 -0700275 talloc_free ($1);
276 }
Carl Worth7f9aa362010-05-13 12:58:49 -0700277| parameter_list ',' identifier_perhaps_macro {
Carl Worth610053b2010-05-14 10:05:11 -0700278 _string_list_append_item ($1, $3);
Carl Worthfcbbb462010-05-13 09:36:23 -0700279 talloc_free ($3);
280 $$ = $1;
281 }
282;
283
Carl Worth7f9aa362010-05-13 12:58:49 -0700284identifier_perhaps_macro:
285 IDENTIFIER { $$ = $1; }
286| FUNC_MACRO { $$ = $1; }
287| OBJ_MACRO { $$ = $1; }
288;
289
Carl Worth0a93cbb2010-05-13 10:29:07 -0700290word:
Carl Worth9f62a7e2010-05-13 07:38:29 -0700291 IDENTIFIER { $$ = $1; }
Carl Worth9f62a7e2010-05-13 07:38:29 -0700292| TOKEN { $$ = $1; }
Carl Worth33cc4002010-05-12 12:17:10 -0700293;
294
295%%
296
Carl Worth610053b2010-05-14 10:05:11 -0700297string_list_t *
298_string_list_create (void *ctx)
Carl Worth33cc4002010-05-12 12:17:10 -0700299{
Carl Worth610053b2010-05-14 10:05:11 -0700300 string_list_t *list;
Carl Worth33cc4002010-05-12 12:17:10 -0700301
Carl Worth610053b2010-05-14 10:05:11 -0700302 list = xtalloc (ctx, string_list_t);
Carl Worth33cc4002010-05-12 12:17:10 -0700303 list->head = NULL;
304 list->tail = NULL;
305
306 return list;
Carl Worth0b27b5f2010-05-10 16:16:06 -0700307}
Carl Worth0b27b5f2010-05-10 16:16:06 -0700308
Carl Worth33cc4002010-05-12 12:17:10 -0700309void
Carl Worth610053b2010-05-14 10:05:11 -0700310_string_list_append_list (string_list_t *list, string_list_t *tail)
Carl Worthfcbbb462010-05-13 09:36:23 -0700311{
312 if (list->head == NULL) {
313 list->head = tail->head;
314 } else {
315 list->tail->next = tail->head;
316 }
317
318 list->tail = tail->tail;
319}
320
321void
Carl Worth610053b2010-05-14 10:05:11 -0700322_string_list_append_item (string_list_t *list, const char *str)
Carl Worth33cc4002010-05-12 12:17:10 -0700323{
Carl Worth610053b2010-05-14 10:05:11 -0700324 string_node_t *node;
Carl Worth3a37b872010-05-10 11:44:09 -0700325
Carl Worth610053b2010-05-14 10:05:11 -0700326 node = xtalloc (list, string_node_t);
Carl Worth5070a202010-05-12 12:45:33 -0700327 node->str = xtalloc_strdup (node, str);
Carl Worth33cc4002010-05-12 12:17:10 -0700328
329 node->next = NULL;
330
331 if (list->head == NULL) {
332 list->head = node;
333 } else {
334 list->tail->next = node;
335 }
336
337 list->tail = node;
338}
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700339
Carl Worth420d05a2010-05-17 10:15:23 -0700340void
341_string_list_push (string_list_t *list, const char *str)
342{
343 string_node_t *node;
344
345 node = xtalloc (list, string_node_t);
346 node->str = xtalloc_strdup (node, str);
347
348 node->next = list->head;
349
350 if (list->tail == NULL) {
351 list->tail = node;
352 }
353
354 list->head = node;
355}
356
357void
358_string_list_pop (string_list_t *list)
359{
360 string_node_t *node;
361
362 node = list->head;
363
364 if (node == NULL) {
365 fprintf (stderr, "Internal error: _string_list_pop called on an empty list.\n");
366 exit (1);
367 }
368
369 list->head = node->next;
370
371 if (list->tail == node) {
372 assert (node->next == NULL);
373 list->tail = NULL;
374 }
375
376 talloc_free (node);
377}
378
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700379int
Carl Worth610053b2010-05-14 10:05:11 -0700380_string_list_contains (string_list_t *list, const char *member, int *index)
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700381{
Carl Worth610053b2010-05-14 10:05:11 -0700382 string_node_t *node;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700383 int i;
384
385 if (list == NULL)
386 return 0;
387
388 for (i = 0, node = list->head; node; i++, node = node->next) {
389 if (strcmp (node->str, member) == 0) {
Carl Worth420d05a2010-05-17 10:15:23 -0700390 if (index)
391 *index = i;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700392 return 1;
393 }
394 }
395
396 return 0;
397}
398
399int
Carl Worth610053b2010-05-14 10:05:11 -0700400_string_list_length (string_list_t *list)
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700401{
402 int length = 0;
Carl Worth610053b2010-05-14 10:05:11 -0700403 string_node_t *node;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700404
405 if (list == NULL)
406 return 0;
407
408 for (node = list->head; node; node = node->next)
409 length++;
410
411 return length;
412}
413
Carl Worth2be8be02010-05-14 10:31:43 -0700414void
415_print_string_list (string_list_t *list)
416{
417 string_node_t *node;
418
419 if (list == NULL)
420 return;
421
Carl Worth81f01432010-05-14 17:08:45 -0700422 for (node = list->head; node; node = node->next) {
Carl Worth2be8be02010-05-14 10:31:43 -0700423 printf ("%s", node->str);
Carl Worth81f01432010-05-14 17:08:45 -0700424 if (node->next)
425 printf (" ");
426 }
Carl Worth2be8be02010-05-14 10:31:43 -0700427}
428
Carl Worth8f6a8282010-05-14 10:44:19 -0700429argument_list_t *
430_argument_list_create (void *ctx)
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700431{
Carl Worth8f6a8282010-05-14 10:44:19 -0700432 argument_list_t *list;
433
434 list = xtalloc (ctx, argument_list_t);
435 list->head = NULL;
436 list->tail = NULL;
437
438 return list;
439}
440
441void
442_argument_list_append (argument_list_t *list, string_list_t *argument)
443{
444 argument_node_t *node;
445
446 if (argument == NULL || argument->head == NULL)
447 return;
448
449 node = xtalloc (list, argument_node_t);
450 node->argument = argument;
451
452 node->next = NULL;
453
454 if (list->head == NULL) {
455 list->head = node;
456 } else {
457 list->tail->next = node;
458 }
459
460 list->tail = node;
461}
462
463int
464_argument_list_length (argument_list_t *list)
465{
466 int length = 0;
467 argument_node_t *node;
468
469 if (list == NULL)
470 return 0;
471
472 for (node = list->head; node; node = node->next)
473 length++;
474
475 return length;
476}
477
478string_list_t *
479_argument_list_member_at (argument_list_t *list, int index)
480{
481 argument_node_t *node;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700482 int i;
483
484 if (list == NULL)
485 return NULL;
486
487 node = list->head;
488 for (i = 0; i < index; i++) {
489 node = node->next;
490 if (node == NULL)
491 break;
492 }
493
494 if (node)
Carl Worth8f6a8282010-05-14 10:44:19 -0700495 return node->argument;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700496
497 return NULL;
498}
Carl Worth33cc4002010-05-12 12:17:10 -0700499
Carl Worth3a37b872010-05-10 11:44:09 -0700500void
Carl Wortha1e32bc2010-05-10 13:17:25 -0700501yyerror (void *scanner, const char *error)
Carl Worth3a37b872010-05-10 11:44:09 -0700502{
503 fprintf (stderr, "Parse error: %s\n", error);
504}
Carl Worth0b27b5f2010-05-10 16:16:06 -0700505
Carl Worth33cc4002010-05-12 12:17:10 -0700506glcpp_parser_t *
507glcpp_parser_create (void)
Carl Worth0b27b5f2010-05-10 16:16:06 -0700508{
Carl Worth33cc4002010-05-12 12:17:10 -0700509 glcpp_parser_t *parser;
510
Carl Worth5070a202010-05-12 12:45:33 -0700511 parser = xtalloc (NULL, glcpp_parser_t);
Carl Worth33cc4002010-05-12 12:17:10 -0700512
Carl Worth5070a202010-05-12 12:45:33 -0700513 yylex_init_extra (parser, &parser->scanner);
Carl Worth0b27b5f2010-05-10 16:16:06 -0700514 parser->defines = hash_table_ctor (32, hash_table_string_hash,
515 hash_table_string_compare);
Carl Worth33cc4002010-05-12 12:17:10 -0700516
517 return parser;
Carl Worth0b27b5f2010-05-10 16:16:06 -0700518}
519
520int
521glcpp_parser_parse (glcpp_parser_t *parser)
522{
523 return yyparse (parser);
524}
525
526void
Carl Worth33cc4002010-05-12 12:17:10 -0700527glcpp_parser_destroy (glcpp_parser_t *parser)
Carl Worth0b27b5f2010-05-10 16:16:06 -0700528{
529 yylex_destroy (parser->scanner);
530 hash_table_dtor (parser->defines);
Carl Worth33cc4002010-05-12 12:17:10 -0700531 talloc_free (parser);
Carl Worth0b27b5f2010-05-10 16:16:06 -0700532}
Carl Worthc6d5af32010-05-11 12:30:09 -0700533
Carl Worthfcbbb462010-05-13 09:36:23 -0700534macro_type_t
535glcpp_parser_macro_type (glcpp_parser_t *parser, const char *identifier)
Carl Worth9f62a7e2010-05-13 07:38:29 -0700536{
Carl Worthfcbbb462010-05-13 09:36:23 -0700537 macro_t *macro;
538
539 macro = hash_table_find (parser->defines, identifier);
540
541 if (macro == NULL)
542 return MACRO_TYPE_UNDEFINED;
543
544 if (macro->is_function)
545 return MACRO_TYPE_FUNCTION;
546 else
547 return MACRO_TYPE_OBJECT;
Carl Worth9f62a7e2010-05-13 07:38:29 -0700548}
549
Carl Worth33cc4002010-05-12 12:17:10 -0700550void
Carl Worthfcbbb462010-05-13 09:36:23 -0700551_define_object_macro (glcpp_parser_t *parser,
552 const char *identifier,
Carl Worthc5e98552010-05-14 10:12:21 -0700553 string_list_t *replacements)
Carl Worthfcbbb462010-05-13 09:36:23 -0700554{
555 macro_t *macro;
556
557 macro = xtalloc (parser, macro_t);
558
559 macro->is_function = 0;
Carl Worthc5e98552010-05-14 10:12:21 -0700560 macro->parameters = NULL;
561 macro->replacements = talloc_steal (macro, replacements);
Carl Worthfcbbb462010-05-13 09:36:23 -0700562
563 hash_table_insert (parser->defines, macro, identifier);
564}
565
566void
567_define_function_macro (glcpp_parser_t *parser,
568 const char *identifier,
Carl Worthc5e98552010-05-14 10:12:21 -0700569 string_list_t *parameters,
570 string_list_t *replacements)
Carl Worthfcbbb462010-05-13 09:36:23 -0700571{
572 macro_t *macro;
573
574 macro = xtalloc (parser, macro_t);
575
576 macro->is_function = 1;
Carl Worthc5e98552010-05-14 10:12:21 -0700577 macro->parameters = talloc_steal (macro, parameters);
578 macro->replacements = talloc_steal (macro, replacements);
Carl Worthfcbbb462010-05-13 09:36:23 -0700579
580 hash_table_insert (parser->defines, macro, identifier);
581}
582
Carl Worth2be8be02010-05-14 10:31:43 -0700583static string_list_t *
584_expand_macro_recursive (glcpp_parser_t *parser,
585 const char *token,
Carl Worth420d05a2010-05-17 10:15:23 -0700586 string_list_t *active,
Carl Worth2be8be02010-05-14 10:31:43 -0700587 string_list_t *parameters,
Carl Worth8f6a8282010-05-14 10:44:19 -0700588 argument_list_t *arguments);
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700589
Carl Worth2be8be02010-05-14 10:31:43 -0700590static string_list_t *
591_expand_string_list_recursive (glcpp_parser_t *parser,
592 string_list_t *list,
Carl Worth420d05a2010-05-17 10:15:23 -0700593 string_list_t *active,
Carl Worth2be8be02010-05-14 10:31:43 -0700594 string_list_t *parameters,
Carl Worth8f6a8282010-05-14 10:44:19 -0700595 argument_list_t *arguments)
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700596{
Carl Worth2be8be02010-05-14 10:31:43 -0700597 string_list_t *result;
598 string_list_t *child;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700599 const char *token;
Carl Worth610053b2010-05-14 10:05:11 -0700600 string_node_t *node;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700601 int index;
602
Carl Worth2be8be02010-05-14 10:31:43 -0700603 result = _string_list_create (parser);
604
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700605 for (node = list->head ; node ; node = node->next) {
606 token = node->str;
607
Carl Worth420d05a2010-05-17 10:15:23 -0700608 /* Don't expand this macro if it's on the active
609 * stack, (meaning we're already in the process of
610 * expanding it). */
611 if (_string_list_contains (active, token, NULL)) {
Carl Worth2be8be02010-05-14 10:31:43 -0700612 _string_list_append_item (result, token);
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700613 continue;
614 }
615
Carl Worth610053b2010-05-14 10:05:11 -0700616 if (_string_list_contains (parameters, token, &index)) {
Carl Worth8f6a8282010-05-14 10:44:19 -0700617 string_list_t *argument;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700618
Carl Worth8f6a8282010-05-14 10:44:19 -0700619 argument = _argument_list_member_at (arguments, index);
620 child = _expand_string_list_recursive (parser, argument,
Carl Worth420d05a2010-05-17 10:15:23 -0700621 active, NULL, NULL);
Carl Worth2be8be02010-05-14 10:31:43 -0700622 _string_list_append_list (result, child);
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700623 } else {
Carl Worth2be8be02010-05-14 10:31:43 -0700624 child = _expand_macro_recursive (parser, token,
Carl Worth420d05a2010-05-17 10:15:23 -0700625 active, parameters,
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700626 arguments);
Carl Worth2be8be02010-05-14 10:31:43 -0700627 _string_list_append_list (result, child);
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700628 }
629 }
Carl Worth2be8be02010-05-14 10:31:43 -0700630
631 return result;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700632}
633
634
Carl Worth2be8be02010-05-14 10:31:43 -0700635static string_list_t *
636_expand_macro_recursive (glcpp_parser_t *parser,
637 const char *token,
Carl Worth420d05a2010-05-17 10:15:23 -0700638 string_list_t *active,
Carl Worth2be8be02010-05-14 10:31:43 -0700639 string_list_t *parameters,
Carl Worth8f6a8282010-05-14 10:44:19 -0700640 argument_list_t *arguments)
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700641{
642 macro_t *macro;
Carl Worthc5e98552010-05-14 10:12:21 -0700643 string_list_t *replacements;
Carl Worth420d05a2010-05-17 10:15:23 -0700644 string_list_t *result;
645
646 if (active == NULL)
647 active = _string_list_create (NULL);
648
649 _string_list_push (active, token);
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700650
651 macro = hash_table_find (parser->defines, token);
652 if (macro == NULL) {
Carl Worth2be8be02010-05-14 10:31:43 -0700653 string_list_t *result;
654
655 result = _string_list_create (parser);
656 _string_list_append_item (result, token);
657 return result;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700658 }
659
Carl Worthc5e98552010-05-14 10:12:21 -0700660 replacements = macro->replacements;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700661
Carl Worth420d05a2010-05-17 10:15:23 -0700662 result = _expand_string_list_recursive (parser, replacements,
663 active, parameters, arguments);
664
665 _string_list_pop (active);
666 if (_string_list_length (active) == 0)
667 talloc_free (active);
668
669 return result;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700670}
671
Carl Worth2be8be02010-05-14 10:31:43 -0700672string_list_t *
673_expand_object_macro (glcpp_parser_t *parser, const char *identifier)
Carl Worth33cc4002010-05-12 12:17:10 -0700674{
Carl Worthfcbbb462010-05-13 09:36:23 -0700675 macro_t *macro;
Carl Worth33cc4002010-05-12 12:17:10 -0700676
Carl Worthfcbbb462010-05-13 09:36:23 -0700677 macro = hash_table_find (parser->defines, identifier);
678 assert (! macro->is_function);
679
Carl Worth420d05a2010-05-17 10:15:23 -0700680 return _expand_macro_recursive (parser, identifier, NULL,
Carl Worth2be8be02010-05-14 10:31:43 -0700681 NULL, NULL);
Carl Worthfcbbb462010-05-13 09:36:23 -0700682}
683
Carl Worth2be8be02010-05-14 10:31:43 -0700684string_list_t *
685_expand_function_macro (glcpp_parser_t *parser,
686 const char *identifier,
Carl Worth8f6a8282010-05-14 10:44:19 -0700687 argument_list_t *arguments)
Carl Worthfcbbb462010-05-13 09:36:23 -0700688{
Carl Worthfcbbb462010-05-13 09:36:23 -0700689 macro_t *macro;
690
691 macro = hash_table_find (parser->defines, identifier);
692 assert (macro->is_function);
693
Carl Worth8f6a8282010-05-14 10:44:19 -0700694 if (_argument_list_length (arguments) !=
Carl Worth2be8be02010-05-14 10:31:43 -0700695 _string_list_length (macro->parameters))
696 {
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700697 fprintf (stderr,
698 "Error: macro %s invoked with %d arguments (expected %d)\n",
699 identifier,
Carl Worth8f6a8282010-05-14 10:44:19 -0700700 _argument_list_length (arguments),
Carl Worthc5e98552010-05-14 10:12:21 -0700701 _string_list_length (macro->parameters));
Carl Worth2be8be02010-05-14 10:31:43 -0700702 return NULL;
Carl Worthdcc2ecd2010-05-13 12:56:42 -0700703 }
Carl Worthfcbbb462010-05-13 09:36:23 -0700704
Carl Worth420d05a2010-05-17 10:15:23 -0700705 return _expand_macro_recursive (parser, identifier, NULL,
Carl Worth2be8be02010-05-14 10:31:43 -0700706 macro->parameters, arguments);
Carl Worth33cc4002010-05-12 12:17:10 -0700707}