1 /******************************************************************************
2 * Copyright (c) 2000-2015 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 ******************************************************************************/
19 #include "config_preproc.h"
22 #define YYERROR_VERBOSE
24 extern FILE *config_preproc_yyin;
25 extern int config_preproc_lineno;
26 extern void config_preproc_reset(const std::string& filename);
27 extern void config_preproc_close();
28 int config_preproc_yylex(void);
29 void config_preproc_yyrestart(FILE *new_file);
30 extern int preproc_error_flag;
32 static void config_preproc_yyerror(const char *error_str);
33 static int config_preproc_yyparse(void);
35 static string_chain_t *config_preproc_filenames;
36 static string_map_t *config_preproc_defines;
38 static char* decode_secret_message(char* encoded);
42 %name-prefix="config_preproc_yy"
45 char* str_val; /* the usual expstring_t */
46 /* a structure to keep track if the last part of the concatenated macro value
47 was a literal, this is needed because of the stupid and artificial requirement
48 that two literals cannot follow each other */
52 } macro_val; /* 0 or 1 */
55 %token <str_val> FillerStuff "whitespace, newline or comment"
56 %token AssignmentChar ":= or ="
59 %token <str_val> FString "sequence of characters"
60 %token <str_val> Identifier
61 %token <str_val> MacroRValue
62 %token <str_val> MacroReference
63 %token <str_val> Cstring "charstring value"
65 %type <str_val> FillerStuffConcat
66 %type <macro_val> MacroAssignmentValueList MacroAssignmentValue
67 %type <str_val> StructuredDefinition
68 %type <str_val> SimpleValue
69 %type <str_val> StructuredValue
70 %type <str_val> StructuredValueList
71 %type <str_val> MacroRhs
73 %destructor { Free($$); }
87 %destructor { Free($$.str_val); }
88 MacroAssignmentValueList
95 | optFillerStuffList MacroAssignments optFillerStuffList
99 | MacroAssignments FillerStuffList MacroAssignment
103 Identifier optFillerStuffList AssignmentChar optFillerStuffList MacroRhs {
104 if (string_map_add(config_preproc_defines, $1, $5, mstrlen($5)) != NULL) {
111 MacroAssignmentValueList {
115 StructuredDefinition {
120 StructuredDefinition:
121 LCurly StructuredValueList RCurly {
123 $$ = mputstr($$, $2);
124 $$ = mputstr($$, "}");
134 | StructuredValueList StructuredValue optFillerStuffList
137 $$ = mputstr($$, $1);
138 $$ = mputstr($$, $2);
149 LCurly StructuredValueList RCurly {
151 $$ = mputstr($$, $2);
152 $$ = mputstr($$,"}");
160 const char *macrovalue;
162 if ($1[1] == '{') macroname = get_macro_id_from_ref($1);
163 else macroname = mcopystr($1 + 1);
164 macrovalue = string_map_get_bykey(config_preproc_defines, macroname, ¯olen);
165 if (macrovalue == NULL) {
166 preproc_error_flag = 1;
167 config_preproc_error("No macro or environmental variable defined with name `%s'", macroname);
170 $$ = mcopystr(macrovalue);
175 | Cstring { $$ = $1;}
176 | FString { $$ = $1;}
179 MacroAssignmentValueList:
180 MacroAssignmentValue { $$ = $1; }
181 | MacroAssignmentValueList MacroAssignmentValue {
182 if ($1.last_literal && $2.last_literal) {
183 preproc_error_flag = 1;
184 config_preproc_error("Literal `%s' cannot follow another literal", $2.str_val);
186 $$.str_val = mputstr($1.str_val, $2.str_val);
188 $$.last_literal = $2.last_literal;
192 MacroAssignmentValue:
193 Identifier { $$.str_val = $1; $$.last_literal = 1; }
194 | MacroRValue { $$.str_val = $1; $$.last_literal = 1; }
195 | Cstring { $$.str_val = $1; $$.last_literal = 1; }
198 const char *macrovalue;
200 if ($1[1] == '{') macroname = get_macro_id_from_ref($1);
201 else macroname = mcopystr($1 + 1);
202 macrovalue = string_map_get_bykey(config_preproc_defines, macroname, ¯olen);
203 if (macrovalue == NULL) {
204 preproc_error_flag = 1;
205 config_preproc_error("No macro or environmental variable defined with name `%s'", macroname);
206 $$.str_val = memptystr();
208 $$.str_val = mcopystr(macrovalue);
223 const char* magic_str = "TITAN";
224 const size_t magic_str_len = 5;
225 if (mstrlen($1)>magic_str_len*8) {
226 char* decoded = decode_secret_message($1);
227 if (strncmp(decoded, magic_str, magic_str_len) == 0) {
228 printf("%s\n", decoded+magic_str_len);
237 FillerStuff { $$ = $1; }
238 | FillerStuffConcat FillerStuff {
239 $$ = mputstr($1, $2);
246 /* BISON error reporting function */
247 void config_preproc_yyerror(const char *error_str)
249 config_preproc_error("%s", error_str);
252 extern int add_include_file(const std::string& filename)
255 if (strlen(filename.c_str()) == filename.size()) {
256 expstring_t currdirname, dirname, filenamepart, basedir;
257 currdirname = get_dir_from_path(get_cfg_preproc_current_file().c_str());
258 dirname = get_dir_from_path(filename.c_str());
259 basedir = get_absolute_dir(dirname, currdirname, 1);
262 filenamepart = get_file_from_path(filename.c_str());
263 if (basedir != NULL) {
264 expstring_t absfilename = compose_path_name(basedir, filenamepart);
265 switch (get_path_status(absfilename)) {
267 string_chain_add(&config_preproc_filenames, absfilename);
270 config_preproc_error("Included file `%s' is a directory.", absfilename);
274 config_preproc_error("Included file `%s' does not exist.", absfilename);
277 if (error_flag) Free(absfilename);
278 } else error_flag = 1;
282 config_preproc_error("The name of the included file cannot contain NUL "
289 extern int preproc_parse_file(const char *filename, string_chain_t **filenames,
290 string_map_t **defines)
293 config_preproc_filenames=NULL;
294 config_preproc_defines=string_map_new();
296 expstring_t dirname=get_dir_from_path(filename);
297 expstring_t basedir=get_absolute_dir(dirname, NULL, 1);
298 expstring_t filenamepart=get_file_from_path(filename);
300 if (basedir == NULL) {
304 string_chain_add(&config_preproc_filenames, compose_path_name(basedir, filenamepart));
309 string_chain_t *i_chain=config_preproc_filenames;
310 string_chain_t *i_prev=NULL;
312 config_preproc_yylineno=1;
313 config_preproc_yyin = fopen(i_chain->str, "r");
314 if (config_preproc_yyin != NULL) {
315 config_preproc_yyrestart(config_preproc_yyin);
316 config_preproc_reset(std::string(i_chain->str));
317 if (config_preproc_yyparse()) error_flag = 1;
318 if (preproc_error_flag) error_flag = 1;
319 fclose(config_preproc_yyin);
320 config_preproc_close();
321 /* During parsing flex or libc may use some system calls (e.g. ioctl)
322 * that fail with an error status. Such error codes shall be ignored in
323 * future error messages. */
326 i_chain=i_chain->next;
328 string_chain_t *i_tmp=i_chain;
329 config_preproc_error("Cannot open config file `%s': %s",
334 i_prev->next=i_chain->next;
335 i_chain=i_chain->next;
338 i_chain=i_chain->next;
339 config_preproc_filenames=i_chain;
348 *filenames=config_preproc_filenames;
349 *defines=config_preproc_defines;
353 static char* decode_secret_message(char* encoded)
355 char* decoded = memptystr();
356 size_t i, j, dec_len = mstrlen(encoded) / 8;
357 for (i=0; i<dec_len; i++) {
359 for (j=0; j<8; j++) {
360 if (encoded[i*8+j]=='\t') dc |= (1<<(7-j));
362 decoded = mputc(decoded, dc);