Update README.md
[deliverable/titan.core.git] / common / config_preproc_la.l
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 * Forstner, Matyas
14 * Kovacs, Ferenc
15 * Raduly, Csaba
16 * Szabo, Janos Zoltan – initial implementation
17 *
18 ******************************************************************************/
19
20 %option noyywrap
21 %option never-interactive
22 %option nounput
23 %option prefix="config_preproc_yy"
24
25 %{
26
27 #include <string.h>
28 #include <unistd.h>
29 #include <errno.h>
30
31 #include <deque>
32 #include <string>
33
34 #include "Path2.hh"
35 #include "cfg_process_utils.hh"
36
37 #include "config_preproc.h"
38 #include "path.h"
39 #include "config_preproc_p.tab.hh"
40
41 //#include "dbgnew.hh"
42
43 #define yylineno config_preproc_yylineno
44
45 extern int add_include_file(const std::string&);
46
47 /* If there are errors in the parsed define sections this value changes to 1.
48 flex and bison for preprocessing can set it to 1, sometimes without printing
49 the error message because strings and some other stuff is also parsed by the
50 actual configuration parser which prints errors */
51 int preproc_error_flag;
52
53 /* used to track the curly brackets in the define section */
54 static int paren_stack = 0;
55
56 static std::deque<IncludeElem<YY_BUFFER_STATE> >* include_chain = NULL;
57
58 std::string get_cfg_preproc_current_file() {
59 if (include_chain && !include_chain->empty()) {
60 return include_chain->back().get_full_path();
61 }
62 return std::string();
63 }
64
65 %}
66
67 WHITESPACE [ \t]
68 WS {WHITESPACE}*
69 NEWLINE \r|\n|\r\n
70 LINECOMMENT ("//"|"#")[^\r\n]*{NEWLINE}
71 NUMBER 0|([1-9][0-9]*)
72
73 TTCN3IDENTIFIER [A-Za-z][A-Za-z0-9_]*
74
75 HEX [0-9A-Fa-f]
76
77 MACRORVALUE ([0-9A-Za-z._-]+)|{IPV6}
78 IPV6 [0-9A-Fa-f:.]+(%[0-9A-Za-z]+)?
79
80 MACRO_REFERENCE \${TTCN3IDENTIFIER}|\$"{"{WS}{TTCN3IDENTIFIER}{WS}(","{WS}charstring{WS})?"}"
81 MACRO_REFERENCE_INT \$"{"{WS}{TTCN3IDENTIFIER}{WS}(","{WS}integer{WS})?"}"
82
83
84 %x SC_blockcomment SC_cstring
85 %s SC_include SC_define SC_define_structured SC_ordered_include
86 %s SC_module_parameters SC_testport_parameters
87
88 %%
89 /* valid in states SC_blockcomment, SC_cstring */
90 int caller_state = INITIAL;
91 /* valid in state SC_cstring */
92 std::string cstring;
93
94 preproc_error_flag = 0;
95
96 "/*" {
97 caller_state = YY_START;
98 BEGIN(SC_blockcomment);
99 }
100
101 <SC_blockcomment>
102 {
103 "*/" {
104 BEGIN(caller_state);
105 if (YY_START==SC_define || YY_START==SC_define_structured) {
106 config_preproc_yylval.str_val = NULL;
107 return FillerStuff;
108 }
109 }
110
111 {NEWLINE} yylineno++;
112
113 . /* do nothing */
114
115 <<EOF>> {
116 preproc_error_flag = 1; /* unterminated block comment, error msg. in parser */
117 BEGIN(caller_state);
118 }
119 } /* SC_blockcomment */
120
121 {WHITESPACE} {
122 if (YY_START==SC_define || YY_START==SC_define_structured) {
123 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng); return FillerStuff;
124 }
125 }
126
127 {NEWLINE}|{LINECOMMENT} {
128 yylineno++;
129 if (YY_START==SC_define || YY_START==SC_define_structured) {
130 config_preproc_yylval.str_val = NULL;
131 return FillerStuff;
132 }
133 }
134
135 /* Section delimiters */
136
137 "["{WS}INCLUDE{WS}"]" BEGIN(SC_include);
138
139 "["{WS}ORDERED_INCLUDE{WS}"]" {
140 caller_state = YY_START;
141 BEGIN(SC_ordered_include);
142 }
143
144 "["{WS}DEFINE{WS}"]" BEGIN(SC_define);
145
146 "["{WS}MODULE_PARAMETERS{WS}"]" BEGIN(SC_module_parameters);
147 "["{WS}TESTPORT_PARAMETERS{WS}"]" BEGIN(SC_testport_parameters);
148
149 <SC_testport_parameters>
150 {
151 "["{NUMBER}"]" ;
152 }
153
154 <SC_module_parameters>
155 {
156 "["[ \t0-9a-zA-Z+*/&-]*"]" ;
157 }
158
159 <SC_module_parameters,SC_testport_parameters>
160 {
161 "["[^\r\n\[\]]*{MACRO_REFERENCE_INT}{WS}[^\r\n\[\]]*"]" ;
162 }
163
164 "["{WS}LOGGING{WS}"]" BEGIN(INITIAL);
165 "["{WS}PROFILER{WS}"]" BEGIN(INITIAL);
166 "["{WS}EXECUTE{WS}"]" BEGIN(INITIAL);
167 "["{WS}EXTERNAL_COMMANDS{WS}"]" BEGIN(INITIAL);
168 "["{WS}GROUPS{WS}"]" BEGIN(INITIAL);
169 "["{WS}COMPONENTS{WS}"]" BEGIN(INITIAL);
170 "["{WS}MAIN_CONTROLLER{WS}"]" BEGIN(INITIAL);
171
172 "["[^\r\n\[\]]*"]" {
173 preproc_error_flag = 1;
174 config_preproc_error("Invalid section name `%s'", yytext);
175 }
176
177 \" {
178 caller_state = YY_START;
179 BEGIN(SC_cstring);
180 cstring.clear();
181
182 if (caller_state == SC_define_structured) {
183 cstring += '"';
184 }
185 }
186
187 <SC_cstring>
188 {
189 \"\" cstring += '"';
190
191 \" {
192 /* end of the string */
193 BEGIN(caller_state);
194 switch (YY_START) {
195 case SC_define_structured:
196 cstring += '"';
197 /* No break */
198 case SC_define:
199 config_preproc_yylval.str_val = mcopystrn(cstring.c_str(), cstring.size());
200 cstring.clear();
201 return Cstring;
202 case SC_include:
203 if (add_include_file(cstring)) preproc_error_flag = 1;
204 cstring.clear();
205 break;
206 case SC_ordered_include:
207 {
208 std::string error_msg = switch_lexer(include_chain, cstring,
209 YY_CURRENT_BUFFER, yy_create_buffer, yy_switch_to_buffer, yylineno,
210 YY_BUF_SIZE);
211 if (error_msg.empty()) {
212 BEGIN(INITIAL);
213 } else {
214 preproc_error_flag = 1;
215 config_preproc_error("%s", error_msg.c_str());
216 }
217 }
218 /* no break */
219 default:
220 cstring.clear();
221 } /* switch */
222 } /* end of string */
223
224 \\[\\'"?] cstring += yytext[1]; /* backslash-quoted \ or " or ' or ? */
225 \\{NEWLINE} yylineno++;
226 \\a cstring += '\a';
227 \\b cstring += '\b';
228 \\f cstring += '\f';
229 \\n cstring += '\n';
230 \\r cstring += '\r';
231 \\t cstring += '\t';
232 \\v cstring += '\v';
233
234 \\[0-7]{1,3} {
235 unsigned int c;
236 sscanf(yytext + 1, "%o", &c);
237 /* do not report error in case of invalid octal escape sequences */
238 if (c <= 255) cstring += c;
239 else preproc_error_flag = 1;
240 }
241
242 \\x{HEX}{1,2} {
243 unsigned int c;
244 sscanf(yytext + 2, "%x", &c);
245 cstring += c;
246 }
247
248 \\(x[^\\\"]|.) preproc_error_flag = 1;
249
250 {NEWLINE} {
251 cstring.append(yytext, yyleng);
252 yylineno++;
253 }
254
255 . { cstring += yytext[0]; }
256
257 <<EOF>> {
258 preproc_error_flag = 1; /* unterminated string literal, error msg. in parser */
259 cstring.clear();
260 BEGIN(caller_state);
261 return EOF;
262 }
263 } /* SC_cstring */
264
265
266 <SC_define>
267 {
268
269 {TTCN3IDENTIFIER} {
270 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
271 return Identifier;
272 }
273
274 ":="|"=" { return AssignmentChar; }
275
276 {MACRORVALUE} {
277 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
278 return MacroRValue;
279 }
280
281 {MACRO_REFERENCE} {
282 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
283 return MacroReference;
284 }
285
286 "{" {
287 ++paren_stack;
288 BEGIN(SC_define_structured);
289 return LCurly;
290 }
291 } /* SC_define */
292
293 <SC_define_structured>
294 {
295
296 {MACRO_REFERENCE} {
297 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
298 return MacroReference;
299 }
300
301 "{" {
302 ++paren_stack;
303 return LCurly;
304 }
305
306 "}" {
307 if (paren_stack == 0) { /* We don't have any opened curly brackets. */
308 preproc_error_flag = 1;
309 config_preproc_error("Invalid structured definition.");
310 BEGIN(SC_define);
311 return RCurly;
312 }
313
314 --paren_stack;
315 if (paren_stack == 0) { /* The end of a structured definition. */
316 BEGIN(SC_define);
317 }
318 return RCurly;
319 }
320
321 \\\" { /* \" is handled separately in the structured definitions */
322 config_preproc_yylval.str_val = mcopystr("\"");
323 return FString;
324 }
325
326 \\. { /* Handle escaped characters */
327 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
328 return FString;
329 }
330
331 [^{}"\\$\n\r\t #/]+ { /* Anything except {,},\,$,#,/ and whitespace */
332 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
333 return FString;
334 }
335
336 "/" {
337 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
338 return FString;
339 }
340
341 } /* SC_define_structured */
342
343 <<EOF>> {
344 if (include_chain->size() > 1) { // The last fp is owned by the parser
345 yy_delete_buffer(YY_CURRENT_BUFFER);
346 fclose(include_chain->back().fp);
347 include_chain->pop_back();
348 yy_switch_to_buffer(include_chain->back().buffer_state);
349 BEGIN(SC_ordered_include);
350 } else {
351 return EOF;
352 }
353 }
354
355 . {
356 switch (YY_START) {
357 case SC_define:
358 case SC_define_structured:
359 preproc_error_flag = 1;
360 config_preproc_error("Invalid character in [DEFINE] section: '%c'.", yytext[0]);
361 break;
362 case SC_include:
363 case SC_ordered_include:
364 preproc_error_flag = 1;
365 config_preproc_error("Invalid character in [%s] section: '%c'.",
366 (YY_START==SC_include || YY_START==SC_ordered_include) ? "INCLUDE" : "ORDERED_INCLUDE",
367 yytext[0]);
368 default:
369 break;
370 }
371 }
372
373
374 %%
375
376 void config_preproc_reset(const std::string& filename) {
377 if (!include_chain) {
378 include_chain = new std::deque<IncludeElem<YY_BUFFER_STATE> >();
379 } else {
380 include_chain->clear();
381 }
382
383 include_chain->push_back(IncludeElem<YY_BUFFER_STATE>(
384 filename, config_preproc_yyin));
385 }
386
387 void config_preproc_close() {
388 delete include_chain;
389 include_chain = NULL;
390 }
391
This page took 0.03972 seconds and 5 git commands to generate.