Sync with 5.2.0
[deliverable/titan.core.git] / common / config_preproc_la.l
CommitLineData
970ed795
EL
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 ******************************************************************************/
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
138<SC_module_parameters,SC_testport_parameters>
139{
140 "["{NUMBER}"]" ;
141 "["[^\r\n\[\]]*{MACRO_REFERENCE_INT}{WS}[^\r\n\[\]]*"]" ;
142}
143
144"["{WS}LOGGING{WS}"]" BEGIN(INITIAL);
af710487 145"["{WS}PROFILER{WS}"]" BEGIN(INITIAL);
970ed795
EL
146"["{WS}EXECUTE{WS}"]" BEGIN(INITIAL);
147"["{WS}EXTERNAL_COMMANDS{WS}"]" BEGIN(INITIAL);
148"["{WS}GROUPS{WS}"]" BEGIN(INITIAL);
149"["{WS}COMPONENTS{WS}"]" BEGIN(INITIAL);
150"["{WS}MAIN_CONTROLLER{WS}"]" BEGIN(INITIAL);
151
152"["[^\r\n\[\]]*"]" {
153 preproc_error_flag = 1;
154 config_preproc_error("Invalid section name `%s'", yytext);
155}
156
157\" {
158 caller_state = YY_START;
159 BEGIN(SC_cstring);
160 cstring.clear();
161
162 if (caller_state == SC_define_structured) {
163 cstring += '"';
164 }
165}
166
167<SC_cstring>
168{
169\"\" cstring += '"';
170
171\" {
172 /* end of the string */
173 BEGIN(caller_state);
174 switch (YY_START) {
175 case SC_define_structured:
176 cstring += '"';
177 /* No break */
178 case SC_define:
179 config_preproc_yylval.str_val = mcopystrn(cstring.c_str(), cstring.size());
180 cstring.clear();
181 return Cstring;
182 case SC_include:
183 if (add_include_file(cstring)) preproc_error_flag = 1;
184 cstring.clear();
185 break;
186 case SC_ordered_include:
187 {
188 std::string error_msg = switch_lexer(include_chain, cstring,
189 YY_CURRENT_BUFFER, yy_create_buffer, yy_switch_to_buffer, yylineno,
190 YY_BUF_SIZE);
191 if (error_msg.empty()) {
192 BEGIN(INITIAL);
193 } else {
194 preproc_error_flag = 1;
195 config_preproc_error(error_msg.c_str());
196 }
197 }
198 /* no break */
199 default:
200 cstring.clear();
201 } /* switch */
202} /* end of string */
203
204\\[\\'"?] cstring += yytext[1]; /* backslash-quoted \ or " or ' or ? */
205\\{NEWLINE} yylineno++;
206\\a cstring += '\a';
207\\b cstring += '\b';
208\\f cstring += '\f';
209\\n cstring += '\n';
210\\r cstring += '\r';
211\\t cstring += '\t';
212\\v cstring += '\v';
213
214\\[0-7]{1,3} {
215 unsigned int c;
216 sscanf(yytext + 1, "%o", &c);
217 /* do not report error in case of invalid octal escape sequences */
218 if (c <= 255) cstring += c;
219 else preproc_error_flag = 1;
220}
221
222\\x{HEX}{1,2} {
223 unsigned int c;
224 sscanf(yytext + 2, "%x", &c);
225 cstring += c;
226}
227
228\\(x[^\\\"]|.) preproc_error_flag = 1;
229
230{NEWLINE} {
231 cstring.append(yytext, yyleng);
232 yylineno++;
233}
234
235. { cstring += yytext[0]; }
236
237<<EOF>> {
238 preproc_error_flag = 1; /* unterminated string literal, error msg. in parser */
239 cstring.clear();
240 BEGIN(caller_state);
241 return EOF;
242}
243} /* SC_cstring */
244
245
246<SC_define>
247{
248
249{TTCN3IDENTIFIER} {
250 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
251 return Identifier;
252}
253
254":="|"=" { return AssignmentChar; }
255
256{MACRORVALUE} {
257 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
258 return MacroRValue;
259}
260
261{MACRO_REFERENCE} {
262 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
263 return MacroReference;
264}
265
266"{" {
267 ++paren_stack;
268 BEGIN(SC_define_structured);
269 return LCurly;
270}
271} /* SC_define */
272
273<SC_define_structured>
274{
275
276{MACRO_REFERENCE} {
277 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
278 return MacroReference;
279}
280
281"{" {
282 ++paren_stack;
283 return LCurly;
284}
285
286"}" {
287 if (paren_stack == 0) { /* We don't have any opened curly brackets. */
288 preproc_error_flag = 1;
289 config_preproc_error("Invalid structured definition.");
290 BEGIN(SC_define);
291 return RCurly;
292 }
293
294 --paren_stack;
295 if (paren_stack == 0) { /* The end of a structured definition. */
296 BEGIN(SC_define);
297 }
298 return RCurly;
299}
300
301\\\" { /* \" is handled separately in the structured definitions */
302 config_preproc_yylval.str_val = mcopystr("\"");
303 return FString;
304}
305
306\\. { /* Handle escaped characters */
307 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
308 return FString;
309}
310
311[^{}"\\$\n\r\t #/]+ { /* Anything except {,},\,$,#,/ and whitespace */
312 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
313 return FString;
314}
315
316"/" {
317 config_preproc_yylval.str_val = mcopystrn(yytext, yyleng);
318 return FString;
319}
320
321} /* SC_define_structured */
322
323<<EOF>> {
324 if (include_chain->size() > 1) { // The last fp is owned by the parser
325 yy_delete_buffer(YY_CURRENT_BUFFER);
326 fclose(include_chain->back().fp);
327 include_chain->pop_back();
328 yy_switch_to_buffer(include_chain->back().buffer_state);
329 BEGIN(SC_ordered_include);
330 } else {
331 return EOF;
332 }
333}
334
335. {
336 switch (YY_START) {
337 case SC_define:
338 case SC_define_structured:
339 preproc_error_flag = 1;
340 config_preproc_error("Invalid character in [DEFINE] section: '%c'.", yytext[0]);
341 break;
342 case SC_include:
343 case SC_ordered_include:
344 preproc_error_flag = 1;
345 config_preproc_error("Invalid character in [%s] section: '%c'.",
346 (YY_START==SC_include || YY_START==SC_ordered_include) ? "INCLUDE" : "ORDERED_INCLUDE",
347 yytext[0]);
348 default:
349 break;
350 }
351}
352
353
354%%
355
356void config_preproc_reset(const std::string& filename) {
357 if (!include_chain) {
358 include_chain = new std::deque<IncludeElem<YY_BUFFER_STATE> >();
359 } else {
360 include_chain->clear();
361 }
362
363 include_chain->push_back(IncludeElem<YY_BUFFER_STATE>(
364 filename, config_preproc_yyin));
365}
366
367void config_preproc_close() {
368 delete include_chain;
369 include_chain = NULL;
370}
371
This page took 0.100099 seconds and 5 git commands to generate.