added clang section in installation guide
[deliverable/titan.core.git] / common / config_preproc_p.y
1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Balasko, Jeno
10 * Baranyi, Botond
11 * Beres, Szabolcs
12 * Delic, Adam
13 * Raduly, Csaba
14 * Szabo, Bence Janos
15 *
16 ******************************************************************************/
17
18 %{
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <errno.h>
25
26 #include <string>
27
28 #include "config_preproc.h"
29 #include "path.h"
30
31 #define YYERROR_VERBOSE
32
33 extern FILE *config_preproc_yyin;
34 extern int config_preproc_lineno;
35 extern void config_preproc_reset(const std::string& filename);
36 extern void config_preproc_close();
37 int config_preproc_yylex(void);
38 void config_preproc_yyrestart(FILE *new_file);
39 extern int preproc_error_flag;
40
41 static void config_preproc_yyerror(const char *error_str);
42 static int config_preproc_yyparse(void);
43
44 static string_chain_t *config_preproc_filenames;
45 static string_map_t *config_preproc_defines;
46
47 static char* decode_secret_message(char* encoded);
48
49 %}
50
51 %name-prefix="config_preproc_yy"
52
53 %union{
54 char* str_val; /* the usual expstring_t */
55 /* a structure to keep track if the last part of the concatenated macro value
56 was a literal, this is needed because of the stupid and artificial requirement
57 that two literals cannot follow each other */
58 struct {
59 char* str_val;
60 int last_literal;
61 } macro_val; /* 0 or 1 */
62 }
63
64 %token <str_val> FillerStuff "whitespace, newline or comment"
65 %token AssignmentChar ":= or ="
66 %token LCurly "{"
67 %token RCurly "}"
68 %token <str_val> FString "sequence of characters"
69 %token <str_val> Identifier
70 %token <str_val> MacroRValue
71 %token <str_val> MacroReference
72 %token <str_val> Cstring "charstring value"
73
74 %type <str_val> FillerStuffConcat
75 %type <macro_val> MacroAssignmentValueList MacroAssignmentValue
76 %type <str_val> StructuredDefinition
77 %type <str_val> SimpleValue
78 %type <str_val> StructuredValue
79 %type <str_val> StructuredValueList
80 %type <str_val> MacroRhs
81
82 %destructor { Free($$); }
83 FillerStuff
84 Identifier
85 MacroRValue
86 MacroReference
87 Cstring
88 FillerStuffConcat
89 SimpleValue
90 StructuredDefinition
91 StructuredValue
92 StructuredValueList
93 FString
94 MacroRhs
95
96 %destructor { Free($$.str_val); }
97 MacroAssignmentValueList
98 MacroAssignmentValue
99
100 %%
101
102 DefineSections:
103 optFillerStuffList
104 | optFillerStuffList MacroAssignments optFillerStuffList
105
106 MacroAssignments:
107 MacroAssignment
108 | MacroAssignments FillerStuffList MacroAssignment
109 ;
110
111 MacroAssignment:
112 Identifier optFillerStuffList AssignmentChar optFillerStuffList MacroRhs {
113 if (string_map_add(config_preproc_defines, $1, $5, mstrlen($5)) != NULL) {
114 Free($1);
115 }
116 }
117 ;
118
119 MacroRhs:
120 MacroAssignmentValueList {
121 $$ = $1.str_val;
122 }
123 |
124 StructuredDefinition {
125 $$ = $1;
126 }
127 ;
128
129 StructuredDefinition:
130 LCurly StructuredValueList RCurly {
131 $$ = mcopystr("{");
132 $$ = mputstr($$, $2);
133 $$ = mputstr($$, "}");
134 Free($2);
135 }
136 ;
137
138 StructuredValueList:
139 optFillerStuffList
140 {
141 $$ = mcopystr("");
142 }
143 | StructuredValueList StructuredValue optFillerStuffList
144 {
145 $$ = NULL;
146 $$ = mputstr($$, $1);
147 $$ = mputstr($$, $2);
148 Free($1);
149 Free($2);
150 }
151 ;
152
153 StructuredValue:
154 SimpleValue {
155 $$ = $1;
156 }
157 |
158 LCurly StructuredValueList RCurly {
159 $$ = mcopystr("{");
160 $$ = mputstr($$, $2);
161 $$ = mputstr($$,"}");
162 Free($2);
163 }
164 ;
165
166 SimpleValue:
167 MacroReference {
168 char *macroname;
169 const char *macrovalue;
170 size_t macrolen;
171 if ($1[1] == '{') macroname = get_macro_id_from_ref($1);
172 else macroname = mcopystr($1 + 1);
173 macrovalue = string_map_get_bykey(config_preproc_defines, macroname, &macrolen);
174 if (macrovalue == NULL) {
175 preproc_error_flag = 1;
176 config_preproc_error("No macro or environmental variable defined with name `%s'", macroname);
177 $$ = memptystr();
178 } else {
179 $$ = mcopystr(macrovalue);
180 }
181 Free(macroname);
182 Free($1);
183 }
184 | Cstring { $$ = $1;}
185 | FString { $$ = $1;}
186 ;
187
188 MacroAssignmentValueList:
189 MacroAssignmentValue { $$ = $1; }
190 | MacroAssignmentValueList MacroAssignmentValue {
191 if ($1.last_literal && $2.last_literal) {
192 preproc_error_flag = 1;
193 config_preproc_error("Literal `%s' cannot follow another literal", $2.str_val);
194 }
195 $$.str_val = mputstr($1.str_val, $2.str_val);
196 Free($2.str_val);
197 $$.last_literal = $2.last_literal;
198 }
199 ;
200
201 MacroAssignmentValue:
202 Identifier { $$.str_val = $1; $$.last_literal = 1; }
203 | MacroRValue { $$.str_val = $1; $$.last_literal = 1; }
204 | Cstring { $$.str_val = $1; $$.last_literal = 1; }
205 | MacroReference {
206 char *macroname;
207 const char *macrovalue;
208 size_t macrolen;
209 if ($1[1] == '{') macroname = get_macro_id_from_ref($1);
210 else macroname = mcopystr($1 + 1);
211 macrovalue = string_map_get_bykey(config_preproc_defines, macroname, &macrolen);
212 if (macrovalue == NULL) {
213 preproc_error_flag = 1;
214 config_preproc_error("No macro or environmental variable defined with name `%s'", macroname);
215 $$.str_val = memptystr();
216 } else {
217 $$.str_val = mcopystr(macrovalue);
218 }
219 Free(macroname);
220 Free($1);
221 $$.last_literal = 0;
222 }
223 ;
224
225 optFillerStuffList:
226 /* empty */
227 | FillerStuffList
228 ;
229
230 FillerStuffList:
231 FillerStuffConcat {
232 const char* magic_str = "TITAN";
233 const size_t magic_str_len = 5;
234 if (mstrlen($1)>magic_str_len*8) {
235 char* decoded = decode_secret_message($1);
236 if (strncmp(decoded, magic_str, magic_str_len) == 0) {
237 printf("%s\n", decoded+magic_str_len);
238 }
239 Free(decoded);
240 }
241 Free($1);
242 }
243 ;
244
245 FillerStuffConcat:
246 FillerStuff { $$ = $1; }
247 | FillerStuffConcat FillerStuff {
248 $$ = mputstr($1, $2);
249 Free($2);
250 }
251 ;
252
253 %%
254
255 /* BISON error reporting function */
256 void config_preproc_yyerror(const char *error_str)
257 {
258 config_preproc_error("%s", error_str);
259 }
260
261 extern int add_include_file(const std::string& filename)
262 {
263 int error_flag = 0;
264 if (strlen(filename.c_str()) == filename.size()) {
265 expstring_t currdirname, dirname, filenamepart, basedir;
266 currdirname = get_dir_from_path(get_cfg_preproc_current_file().c_str());
267 dirname = get_dir_from_path(filename.c_str());
268 basedir = get_absolute_dir(dirname, currdirname, 1);
269 Free(currdirname);
270 Free(dirname);
271 filenamepart = get_file_from_path(filename.c_str());
272 if (basedir != NULL) {
273 expstring_t absfilename = compose_path_name(basedir, filenamepart);
274 switch (get_path_status(absfilename)) {
275 case PS_FILE:
276 string_chain_add(&config_preproc_filenames, absfilename);
277 break;
278 case PS_DIRECTORY:
279 config_preproc_error("Included file `%s' is a directory.", absfilename);
280 error_flag = 1;
281 break;
282 case PS_NONEXISTENT:
283 config_preproc_error("Included file `%s' does not exist.", absfilename);
284 error_flag = 1;
285 }
286 if (error_flag) Free(absfilename);
287 } else error_flag = 1;
288 Free(filenamepart);
289 Free(basedir);
290 } else {
291 config_preproc_error("The name of the included file cannot contain NUL "
292 "character.");
293 error_flag = 1;
294 }
295 return error_flag;
296 }
297
298 extern int preproc_parse_file(const char *filename, string_chain_t **filenames,
299 string_map_t **defines)
300 {
301 int error_flag = 0;
302 config_preproc_filenames=NULL;
303 config_preproc_defines=string_map_new();
304 {
305 expstring_t dirname=get_dir_from_path(filename);
306 expstring_t basedir=get_absolute_dir(dirname, NULL, 1);
307 expstring_t filenamepart=get_file_from_path(filename);
308 Free(dirname);
309 if (basedir == NULL) {
310 error_flag = 1;
311 goto end;
312 }
313 string_chain_add(&config_preproc_filenames, compose_path_name(basedir, filenamepart));
314 Free(basedir);
315 Free(filenamepart);
316 }
317 {
318 string_chain_t *i_chain=config_preproc_filenames;
319 string_chain_t *i_prev=NULL;
320 while(i_chain) {
321 config_preproc_yylineno=1;
322 config_preproc_yyin = fopen(i_chain->str, "r");
323 if (config_preproc_yyin != NULL) {
324 config_preproc_yyrestart(config_preproc_yyin);
325 config_preproc_reset(std::string(i_chain->str));
326 if (config_preproc_yyparse()) error_flag = 1;
327 if (preproc_error_flag) error_flag = 1;
328 fclose(config_preproc_yyin);
329 config_preproc_close();
330 /* During parsing flex or libc may use some system calls (e.g. ioctl)
331 * that fail with an error status. Such error codes shall be ignored in
332 * future error messages. */
333 errno = 0;
334 i_prev=i_chain;
335 i_chain=i_chain->next;
336 } else {
337 string_chain_t *i_tmp=i_chain;
338 config_preproc_error("Cannot open config file `%s': %s",
339 i_chain->str,
340 strerror(errno));
341 error_flag = 1;
342 if(i_prev) {
343 i_prev->next=i_chain->next;
344 i_chain=i_chain->next;
345 }
346 else {
347 i_chain=i_chain->next;
348 config_preproc_filenames=i_chain;
349 }
350 Free(i_tmp->str);
351 Free(i_tmp);
352 }
353 }
354 }
355
356 end:
357 *filenames=config_preproc_filenames;
358 *defines=config_preproc_defines;
359 return error_flag;
360 }
361
362 static char* decode_secret_message(char* encoded)
363 {
364 char* decoded = memptystr();
365 size_t i, j, dec_len = mstrlen(encoded) / 8;
366 for (i=0; i<dec_len; i++) {
367 char dc = 0;
368 for (j=0; j<8; j++) {
369 if (encoded[i*8+j]=='\t') dc |= (1<<(7-j));
370 }
371 decoded = mputc(decoded, dc);
372 }
373 return decoded;
374 }
This page took 0.039159 seconds and 5 git commands to generate.