1 /******************************************************************************
2 * Copyright (c) 2000-2014 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 ******************************************************************************/
10 %option never-interactive
12 %option prefix="config_preproc_yy"
24 #include "cfg_process_utils.hh"
26 #include "config_preproc.h"
28 #include "config_preproc_p.tab.hh"
30 //#include "dbgnew.hh"
32 #define yylineno config_preproc_yylineno
34 extern int add_include_file(const std::string&);
36 /* If there are errors in the parsed define sections this value changes to 1.
37 flex and bison for preprocessing can set it to 1, sometimes without printing
38 the error message because strings and some other stuff is also parsed by the
39 actual configuration parser which prints errors */
40 int preproc_error_flag;
42 /* used to track the curly brackets in the define section */
43 static int paren_stack = 0;
45 static std::deque<IncludeElem<YY_BUFFER_STATE> >* include_chain = NULL;
47 std::string get_cfg_preproc_current_file() {
48 if (include_chain && !include_chain->empty()) {
49 return include_chain->back().get_full_path();
59 LINECOMMENT ("//"|"#")[^\r\n]*{NEWLINE}
60 NUMBER 0|([1-9][0-9]*)
62 TTCN3IDENTIFIER [A-Za-z][A-Za-z0-9_]*
66 MACRORVALUE ([0-9A-Za-z._-]+)|{IPV6}
67 IPV6 [0-9A-Fa-f:.]+(%[0-9A-Za-z]+)?
69 MACRO_REFERENCE \${TTCN3IDENTIFIER}|\$"{"{WS}{TTCN3IDENTIFIER}{WS}(","{WS}charstring{WS})?"}"
70 MACRO_REFERENCE_INT \$"{"{WS}{TTCN3IDENTIFIER}{WS}(","{WS}integer{WS})?"}"
73 %x SC_blockcomment SC_cstring
74 %s SC_include SC_define SC_define_structured SC_ordered_include
75 %s SC_module_parameters SC_testport_parameters
78 /* valid in states SC_blockcomment, SC_cstring */
79 int caller_state = INITIAL;
80 /* valid in state SC_cstring */
83 preproc_error_flag = 0;
86 caller_state = YY_START;
87 BEGIN(SC_blockcomment);
94 if (YY_START==SC_define || YY_START==SC_define_structured) {
95 config_preproc_yylval.str_val = NULL;
100 {NEWLINE} yylineno++;
105 preproc_error_flag = 1; /* unterminated block comment, error msg. in parser */
108 } /* SC_blockcomment */
111 if (YY_START==SC_define || YY_START==SC_define_structured) {
112 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng); return FillerStuff;
116 {NEWLINE}|{LINECOMMENT} {
118 if (YY_START==SC_define || YY_START==SC_define_structured) {
119 config_preproc_yylval.str_val = NULL;
124 /* Section delimiters */
126 "["{WS}INCLUDE{WS}"]" BEGIN(SC_include);
128 "["{WS}ORDERED_INCLUDE{WS}"]" {
129 caller_state = YY_START;
130 BEGIN(SC_ordered_include);
133 "["{WS}DEFINE{WS}"]" BEGIN(SC_define);
135 "["{WS}MODULE_PARAMETERS{WS}"]" BEGIN(SC_module_parameters);
136 "["{WS}TESTPORT_PARAMETERS{WS}"]" BEGIN(SC_testport_parameters);
138 <SC_module_parameters,SC_testport_parameters>
141 "["[^\r\n\[\]]*{MACRO_REFERENCE_INT}{WS}[^\r\n\[\]]*"]" ;
144 "["{WS}LOGGING{WS}"]" BEGIN(INITIAL);
145 "["{WS}EXECUTE{WS}"]" BEGIN(INITIAL);
146 "["{WS}EXTERNAL_COMMANDS{WS}"]" BEGIN(INITIAL);
147 "["{WS}GROUPS{WS}"]" BEGIN(INITIAL);
148 "["{WS}COMPONENTS{WS}"]" BEGIN(INITIAL);
149 "["{WS}MAIN_CONTROLLER{WS}"]" BEGIN(INITIAL);
152 preproc_error_flag = 1;
153 config_preproc_error("Invalid section name `%s'", yytext);
157 caller_state = YY_START;
161 if (caller_state == SC_define_structured) {
171 /* end of the string */
174 case SC_define_structured:
178 config_preproc_yylval.str_val = mcopystrn(cstring.c_str(), cstring.size());
182 if (add_include_file(cstring)) preproc_error_flag = 1;
185 case SC_ordered_include:
187 std::string error_msg = switch_lexer(include_chain, cstring,
188 YY_CURRENT_BUFFER, yy_create_buffer, yy_switch_to_buffer, yylineno,
190 if (error_msg.empty()) {
193 preproc_error_flag = 1;
194 config_preproc_error(error_msg.c_str());
201 } /* end of string */
203 \\[\\'"?] cstring += yytext[1]; /* backslash-quoted \ or " or ' or ? */
204 \\{NEWLINE} yylineno++;
215 sscanf(yytext + 1, "%o", &c);
216 /* do not report error in case of invalid octal escape sequences */
217 if (c <= 255) cstring += c;
218 else preproc_error_flag = 1;
223 sscanf(yytext + 2, "%x", &c);
227 \\(x[^\\\"]|.) preproc_error_flag = 1;
230 cstring.append(yytext, yyleng);
234 . { cstring += yytext[0]; }
237 preproc_error_flag = 1; /* unterminated string literal, error msg. in parser */
249 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
253 ":="|"=" { return AssignmentChar; }
256 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
261 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
262 return MacroReference;
267 BEGIN(SC_define_structured);
272 <SC_define_structured>
276 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
277 return MacroReference;
286 if (paren_stack == 0) { /* We don't have any opened curly brackets. */
287 preproc_error_flag = 1;
288 config_preproc_error("Invalid structured definition.");
294 if (paren_stack == 0) { /* The end of a structured definition. */
300 \\\" { /* \" is handled separately in the structured definitions */
301 config_preproc_yylval.str_val = mcopystr("\"");
305 \\. { /* Handle escaped characters */
306 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
310 [^{}"\\$\n\r\t #/]+ { /* Anything except {,},\,$,#,/ and whitespace */
311 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
316 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
320 } /* SC_define_structured */
323 if (include_chain->size() > 1) { // The last fp is owned by the parser
324 yy_delete_buffer(YY_CURRENT_BUFFER);
325 fclose(include_chain->back().fp);
326 include_chain->pop_back();
327 yy_switch_to_buffer(include_chain->back().buffer_state);
328 BEGIN(SC_ordered_include);
337 case SC_define_structured:
338 preproc_error_flag = 1;
339 config_preproc_error("Invalid character in [DEFINE] section: '%c'.", yytext[0]);
342 case SC_ordered_include:
343 preproc_error_flag = 1;
344 config_preproc_error("Invalid character in [%s] section: '%c'.",
345 (YY_START==SC_include || YY_START==SC_ordered_include) ? "INCLUDE" : "ORDERED_INCLUDE",
355 void config_preproc_reset(const std::string& filename) {
356 if (!include_chain) {
357 include_chain = new std::deque<IncludeElem<YY_BUFFER_STATE> >();
359 include_chain->clear();
362 include_chain->push_back(IncludeElem<YY_BUFFER_STATE>(
363 filename, config_preproc_yyin));
366 void config_preproc_close() {
367 delete include_chain;
368 include_chain = NULL;