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