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
16 ******************************************************************************/
28 #include "config_preproc.h"
31 #define YYERROR_VERBOSE
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;
41 static void config_preproc_yyerror(const char *error_str);
42 static int config_preproc_yyparse(void);
44 static string_chain_t *config_preproc_filenames;
45 static string_map_t *config_preproc_defines;
47 static char* decode_secret_message(char* encoded);
51 %name-prefix="config_preproc_yy"
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 */
61 } macro_val; /* 0 or 1 */
64 %token <str_val> FillerStuff "whitespace, newline or comment"
65 %token AssignmentChar ":= or ="
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"
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
82 %destructor { Free($$); }
96 %destructor { Free($$.str_val); }
97 MacroAssignmentValueList
104 | optFillerStuffList MacroAssignments optFillerStuffList
108 | MacroAssignments FillerStuffList MacroAssignment
112 Identifier optFillerStuffList AssignmentChar optFillerStuffList MacroRhs {
113 if (string_map_add(config_preproc_defines, $1, $5, mstrlen($5)) != NULL) {
120 MacroAssignmentValueList {
124 StructuredDefinition {
129 StructuredDefinition:
130 LCurly StructuredValueList RCurly {
132 $$ = mputstr($$, $2);
133 $$ = mputstr($$, "}");
143 | StructuredValueList StructuredValue optFillerStuffList
146 $$ = mputstr($$, $1);
147 $$ = mputstr($$, $2);
158 LCurly StructuredValueList RCurly {
160 $$ = mputstr($$, $2);
161 $$ = mputstr($$,"}");
169 const char *macrovalue;
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, ¯olen);
174 if (macrovalue == NULL) {
175 preproc_error_flag = 1;
176 config_preproc_error("No macro or environmental variable defined with name `%s'", macroname);
179 $$ = mcopystr(macrovalue);
184 | Cstring { $$ = $1;}
185 | FString { $$ = $1;}
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);
195 $$.str_val = mputstr($1.str_val, $2.str_val);
197 $$.last_literal = $2.last_literal;
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; }
207 const char *macrovalue;
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, ¯olen);
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();
217 $$.str_val = mcopystr(macrovalue);
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);
246 FillerStuff { $$ = $1; }
247 | FillerStuffConcat FillerStuff {
248 $$ = mputstr($1, $2);
255 /* BISON error reporting function */
256 void config_preproc_yyerror(const char *error_str)
258 config_preproc_error("%s", error_str);
261 extern int add_include_file(const std::string& filename)
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);
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)) {
276 string_chain_add(&config_preproc_filenames, absfilename);
279 config_preproc_error("Included file `%s' is a directory.", absfilename);
283 config_preproc_error("Included file `%s' does not exist.", absfilename);
286 if (error_flag) Free(absfilename);
287 } else error_flag = 1;
291 config_preproc_error("The name of the included file cannot contain NUL "
298 extern int preproc_parse_file(const char *filename, string_chain_t **filenames,
299 string_map_t **defines)
302 config_preproc_filenames=NULL;
303 config_preproc_defines=string_map_new();
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);
309 if (basedir == NULL) {
313 string_chain_add(&config_preproc_filenames, compose_path_name(basedir, filenamepart));
318 string_chain_t *i_chain=config_preproc_filenames;
319 string_chain_t *i_prev=NULL;
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. */
335 i_chain=i_chain->next;
337 string_chain_t *i_tmp=i_chain;
338 config_preproc_error("Cannot open config file `%s': %s",
343 i_prev->next=i_chain->next;
344 i_chain=i_chain->next;
347 i_chain=i_chain->next;
348 config_preproc_filenames=i_chain;
357 *filenames=config_preproc_filenames;
358 *defines=config_preproc_defines;
362 static char* decode_secret_message(char* encoded)
364 char* decoded = memptystr();
365 size_t i, j, dec_len = mstrlen(encoded) / 8;
366 for (i=0; i<dec_len; i++) {
368 for (j=0; j<8; j++) {
369 if (encoded[i*8+j]=='\t') dc |= (1<<(7-j));
371 decoded = mputc(decoded, dc);