blob: 4d6475497bf9688a7b190f5a44f8ff4fd65f31f8 [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 Worth33cc4002010-05-12 12:17:10 -070027#include <talloc.h>
Carl Worth3a37b872010-05-10 11:44:09 -070028
Carl Wortha1e32bc2010-05-10 13:17:25 -070029#include "glcpp.h"
30
Carl Worth0b27b5f2010-05-10 16:16:06 -070031#define YYLEX_PARAM parser->scanner
Carl Worth3a37b872010-05-10 11:44:09 -070032
Carl Worth33cc4002010-05-12 12:17:10 -070033struct glcpp_parser {
34 yyscan_t scanner;
35 struct hash_table *defines;
36};
37
Carl Worth3a37b872010-05-10 11:44:09 -070038void
Carl Wortha1e32bc2010-05-10 13:17:25 -070039yyerror (void *scanner, const char *error);
Carl Worth3a37b872010-05-10 11:44:09 -070040
Carl Worth33cc4002010-05-12 12:17:10 -070041void
Carl Worth9f62a7e2010-05-13 07:38:29 -070042_print_expanded_macro (glcpp_parser_t *parser, const char *macro);
Carl Worth33cc4002010-05-12 12:17:10 -070043
44list_t *
45_list_create (void *ctx);
46
47void
48_list_append (list_t *list, const char *str);
Carl Worthc6d5af32010-05-11 12:30:09 -070049
Carl Worth3a37b872010-05-10 11:44:09 -070050%}
51
Carl Worth33cc4002010-05-12 12:17:10 -070052%union {
53 char *str;
54 list_t *list;
55}
56
Carl Worth0b27b5f2010-05-10 16:16:06 -070057%parse-param {glcpp_parser_t *parser}
Carl Worth38aa8352010-05-10 11:52:29 -070058%lex-param {void *scanner}
59
Carl Worth9f62a7e2010-05-13 07:38:29 -070060%token DEFINE IDENTIFIER MACRO NEWLINE TOKEN UNDEF
61%type <str> IDENTIFIER MACRO TOKEN string
Carl Worth33cc4002010-05-12 12:17:10 -070062%type <list> replacement_list
Carl Worth3a37b872010-05-10 11:44:09 -070063
64%%
65
Carl Worth33cc4002010-05-12 12:17:10 -070066input:
67 /* empty */
Carl Worth8bcb6f12010-05-12 13:21:20 -070068| input content
Carl Worth3a37b872010-05-10 11:44:09 -070069;
70
Carl Worth33cc4002010-05-12 12:17:10 -070071content:
Carl Worth9f62a7e2010-05-13 07:38:29 -070072 IDENTIFIER {
73 printf ("%s", $1);
74 talloc_free ($1);
75 }
76| TOKEN {
77 printf ("%s", $1);
78 talloc_free ($1);
79 }
80| MACRO {
81 _print_expanded_macro (parser, $1);
Carl Worth5070a202010-05-12 12:45:33 -070082 talloc_free ($1);
Carl Worth33cc4002010-05-12 12:17:10 -070083 }
Carl Worthcd27e642010-05-12 13:11:50 -070084| directive_with_newline
Carl Worth012295f2010-05-12 13:19:23 -070085| NEWLINE {
86 printf ("\n");
87 }
Carl Worthcd27e642010-05-12 13:11:50 -070088;
89
90directive_with_newline:
91 directive NEWLINE {
92 printf ("\n");
93 }
Carl Worth3a37b872010-05-10 11:44:09 -070094;
95
Carl Worth33cc4002010-05-12 12:17:10 -070096directive:
Carl Worthcd27e642010-05-12 13:11:50 -070097 DEFINE IDENTIFIER replacement_list {
Carl Worth5070a202010-05-12 12:45:33 -070098 talloc_steal ($3, $2);
99 hash_table_insert (parser->defines, $3, $2);
Carl Worthcd27e642010-05-12 13:11:50 -0700100 }
Carl Worth9f62a7e2010-05-13 07:38:29 -0700101| UNDEF MACRO {
Carl Worthcd27e642010-05-12 13:11:50 -0700102 list_t *replacement = hash_table_find (parser->defines, $2);
103 if (replacement) {
104 /* XXX: Need hash table to support a real way
105 * to remove an element rather than prefixing
106 * a new node with data of NULL like this. */
107 hash_table_insert (parser->defines, NULL, $2);
108 talloc_free (replacement);
109 }
110 talloc_free ($2);
Carl Worth33cc4002010-05-12 12:17:10 -0700111 }
112;
113
114replacement_list:
115 /* empty */ {
116 $$ = _list_create (parser);
117 }
118
Carl Worth9f62a7e2010-05-13 07:38:29 -0700119| replacement_list string {
Carl Worth33cc4002010-05-12 12:17:10 -0700120 _list_append ($1, $2);
Carl Worth5070a202010-05-12 12:45:33 -0700121 talloc_free ($2);
Carl Worth33cc4002010-05-12 12:17:10 -0700122 $$ = $1;
123 }
124;
125
Carl Worth9f62a7e2010-05-13 07:38:29 -0700126string:
127 IDENTIFIER { $$ = $1; }
128| MACRO { $$ = $1; }
129| TOKEN { $$ = $1; }
Carl Worth33cc4002010-05-12 12:17:10 -0700130;
131
132%%
133
134list_t *
135_list_create (void *ctx)
136{
137 list_t *list;
138
Carl Worth5070a202010-05-12 12:45:33 -0700139 list = xtalloc (ctx, list_t);
Carl Worth33cc4002010-05-12 12:17:10 -0700140 list->head = NULL;
141 list->tail = NULL;
142
143 return list;
Carl Worth0b27b5f2010-05-10 16:16:06 -0700144}
Carl Worth0b27b5f2010-05-10 16:16:06 -0700145
Carl Worth33cc4002010-05-12 12:17:10 -0700146void
147_list_append (list_t *list, const char *str)
148{
149 node_t *node;
Carl Worth3a37b872010-05-10 11:44:09 -0700150
Carl Worth5070a202010-05-12 12:45:33 -0700151 node = xtalloc (list, node_t);
152 node->str = xtalloc_strdup (node, str);
Carl Worth33cc4002010-05-12 12:17:10 -0700153
154 node->next = NULL;
155
156 if (list->head == NULL) {
157 list->head = node;
158 } else {
159 list->tail->next = node;
160 }
161
162 list->tail = node;
163}
164
Carl Worth3a37b872010-05-10 11:44:09 -0700165void
Carl Wortha1e32bc2010-05-10 13:17:25 -0700166yyerror (void *scanner, const char *error)
Carl Worth3a37b872010-05-10 11:44:09 -0700167{
168 fprintf (stderr, "Parse error: %s\n", error);
169}
Carl Worth0b27b5f2010-05-10 16:16:06 -0700170
Carl Worth33cc4002010-05-12 12:17:10 -0700171glcpp_parser_t *
172glcpp_parser_create (void)
Carl Worth0b27b5f2010-05-10 16:16:06 -0700173{
Carl Worth33cc4002010-05-12 12:17:10 -0700174 glcpp_parser_t *parser;
175
Carl Worth5070a202010-05-12 12:45:33 -0700176 parser = xtalloc (NULL, glcpp_parser_t);
Carl Worth33cc4002010-05-12 12:17:10 -0700177
Carl Worth5070a202010-05-12 12:45:33 -0700178 yylex_init_extra (parser, &parser->scanner);
Carl Worth0b27b5f2010-05-10 16:16:06 -0700179 parser->defines = hash_table_ctor (32, hash_table_string_hash,
180 hash_table_string_compare);
Carl Worth33cc4002010-05-12 12:17:10 -0700181
182 return parser;
Carl Worth0b27b5f2010-05-10 16:16:06 -0700183}
184
185int
186glcpp_parser_parse (glcpp_parser_t *parser)
187{
188 return yyparse (parser);
189}
190
191void
Carl Worth33cc4002010-05-12 12:17:10 -0700192glcpp_parser_destroy (glcpp_parser_t *parser)
Carl Worth0b27b5f2010-05-10 16:16:06 -0700193{
194 yylex_destroy (parser->scanner);
195 hash_table_dtor (parser->defines);
Carl Worth33cc4002010-05-12 12:17:10 -0700196 talloc_free (parser);
Carl Worth0b27b5f2010-05-10 16:16:06 -0700197}
Carl Worthc6d5af32010-05-11 12:30:09 -0700198
Carl Worth9f62a7e2010-05-13 07:38:29 -0700199int
200glcpp_parser_macro_defined (glcpp_parser_t *parser, const char *identifier)
201{
202 return (hash_table_find (parser->defines, identifier) != NULL);
203}
204
Carl Worth33cc4002010-05-12 12:17:10 -0700205static void
Carl Worth9f62a7e2010-05-13 07:38:29 -0700206_print_expanded_macro_recursive (glcpp_parser_t *parser,
207 const char *token,
208 const char *orig,
209 int *first)
Carl Worthc6d5af32010-05-11 12:30:09 -0700210{
Carl Worth33cc4002010-05-12 12:17:10 -0700211 list_t *replacement;
212 node_t *node;
Carl Worthc6d5af32010-05-11 12:30:09 -0700213
Carl Worth33cc4002010-05-12 12:17:10 -0700214 replacement = hash_table_find (parser->defines, token);
215 if (replacement == NULL) {
216 printf ("%s%s", *first ? "" : " ", token);
217 *first = 0;
218 } else {
219 for (node = replacement->head ; node ; node = node->next) {
220 token = node->str;
221 if (strcmp (token, orig) == 0) {
222 printf ("%s%s", *first ? "" : " ", token);
223 *first = 0;
224 } else {
Carl Worth9f62a7e2010-05-13 07:38:29 -0700225 _print_expanded_macro_recursive (parser,
226 token, orig,
227 first);
Carl Worth33cc4002010-05-12 12:17:10 -0700228 }
229 }
Carl Worthc6d5af32010-05-11 12:30:09 -0700230 }
Carl Worthc6d5af32010-05-11 12:30:09 -0700231}
232
Carl Worth33cc4002010-05-12 12:17:10 -0700233void
Carl Worth9f62a7e2010-05-13 07:38:29 -0700234_print_expanded_macro (glcpp_parser_t *parser, const char *macro)
Carl Worth33cc4002010-05-12 12:17:10 -0700235{
236 int first = 1;
237
Carl Worth9f62a7e2010-05-13 07:38:29 -0700238 _print_expanded_macro_recursive (parser, macro, macro, &first);
Carl Worth33cc4002010-05-12 12:17:10 -0700239}