Merge pull request #83 from eadrkir/master
[deliverable/titan.core.git] / core / config_process.y
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 *
10 * Baji, Laszlo
11 * Balasko, Jeno
12 * Baranyi, Botond
13 * Beres, Szabolcs
14 * Delic, Adam
15 * Forstner, Matyas
16 * Kovacs, Ferenc
17 * Pandi, Krisztian
18 * Raduly, Csaba
19 * Szabados, Kristof
20 * Szabo, Bence Janos
21 * Szabo, Janos Zoltan – initial implementation
22 * Szalai, Gabor
23 * Zalanyi, Balazs Andor
24 *
25 ******************************************************************************/
26 %{
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <stdarg.h>
32 #include <ctype.h>
33 #include <errno.h>
34
35 #include <openssl/bn.h>
36
37 #include "../common/config_preproc.h"
38
39 #include "Param_Types.hh"
40 #include "Integer.hh"
41 #include "Float.hh"
42 #include "Boolean.hh"
43 #include "Objid.hh"
44 #include "Verdicttype.hh"
45 #include "Bitstring.hh"
46 #include "Hexstring.hh"
47 #include "Octetstring.hh"
48 #include "Charstring.hh"
49 #include "Universal_charstring.hh"
50
51 #include "Module_list.hh"
52 #include "Port.hh"
53 #include "Runtime.hh"
54
55 #include "LoggingBits.hh"
56 #include "LoggingParam.hh"
57
58 #include "Profiler.hh"
59 #include "Debugger.hh"
60 #include "DebugCommands.hh"
61
62 #define YYERROR_VERBOSE
63
64 #include "config_process.lex.hh"
65
66 extern void reset_config_process_lex(const char* fname);
67 extern void config_process_close();
68 extern int config_process_get_current_line();
69 extern std::string get_cfg_process_current_file();
70
71 static int config_process_parse();
72 static void check_duplicate_option(const char *section_name,
73 const char *option_name, boolean& option_flag);
74 static void check_ignored_section(const char *section_name);
75 static void set_param(Module_Param& module_param);
76 static unsigned char char_to_hexdigit_(char c);
77
78 static boolean error_flag = FALSE;
79
80 static Module_Param* parsed_module_param = NULL;
81 static char * parsing_error_messages = NULL;
82
83 /*
84 For detecting duplicate entries in the config file. Start out as FALSE,
85 set to TRUE bycheck_duplicate_option().
86 Exception: duplication of parameters that can be component specific is checked
87 by set_xxx(), these start out as TRUE.
88 */
89 static boolean file_name_set = FALSE,
90 file_mask_set = TRUE,
91 console_mask_set = TRUE,
92 timestamp_format_set = FALSE,
93 source_info_format_set = FALSE,
94 append_file_set = FALSE,
95 log_event_types_set = FALSE,
96 log_entity_name_set = FALSE,
97 begin_controlpart_command_set = FALSE,
98 end_controlpart_command_set = FALSE,
99 begin_testcase_command_set = FALSE,
100 end_testcase_command_set = FALSE,
101 log_file_size_set = TRUE,
102 log_file_number_set = TRUE,
103 log_disk_full_action_set = TRUE,
104 matching_verbosity_set = FALSE,
105 logger_plugins_set = FALSE,
106 plugin_specific_set = FALSE;
107
108 int execute_list_len = 0;
109 execute_list_item *execute_list = NULL;
110
111 string_map_t *config_defines;
112
113 %}
114
115 %union{
116 char *str_val;
117 int_val_t *int_val;
118 int int_native;
119 unsigned int uint_val;
120 double float_val;
121 boolean bool_val;
122 param_objid_t objid_val;
123 verdicttype verdict_val;
124 param_bitstring_t bitstring_val;
125 param_hexstring_t hexstring_val;
126 param_charstring_t charstring_val;
127 param_octetstring_t octetstring_val;
128 universal_char universal_char_val;
129 param_universal_charstring_t universal_charstring_val;
130 Module_Param::operation_type_t param_optype_val;
131 Vector<Module_Param*>* module_param_list;
132 Module_Param* module_param_val;
133 Module_Param_Length_Restriction* module_param_length_restriction;
134 Vector<char*>* name_vector;
135 component_id_t comp_id;
136 execute_list_item execute_item_val;
137 TTCN_Logger::emergency_logging_behaviour_t emergency_logging_behaviour_value;
138 TTCN_Logger::timestamp_format_t timestamp_value;
139 TTCN_Logger::source_info_format_t source_info_value;
140 TTCN_Logger::log_event_types_t log_event_types_value;
141 TTCN_Logger::disk_full_action_t disk_full_action_value;
142 TTCN_Logger::matching_verbosity_t matching_verbosity_value;
143 TTCN_Logger::Severity logseverity_val;
144 Logging_Bits logoptions_val;
145
146 logging_plugin_t *logging_plugins;
147 logging_param_t logging_params;
148 logging_setting_t logging_param_line;
149 struct {
150 size_t nElements;
151 const char **elements;
152 } uid_list;
153 }
154
155 %token ModuleParametersKeyword
156 %token LoggingKeyword
157 %token ProfilerKeyword
158 %token TestportParametersKeyword
159 %token ExecuteKeyword
160 %token ExternalCommandsKeyword
161 %token GroupsKeyword
162 %token ComponentsKeyword
163 %token MainControllerKeyword
164 %token IncludeKeyword
165 %token DefineKeyword
166
167 %token Detailed
168 %token Compact
169 %token ObjIdKeyword "objid"
170 %token CharKeyword "char"
171 %token ControlKeyword "control"
172 %token MTCKeyword "mtc"
173 %token SystemKeyword "system"
174 %token NULLKeyword "NULL"
175 %token nullKeyword "null"
176 %token OmitKeyword "omit"
177 %token ComplementKeyword "complement"
178 %token DotDot ".."
179 %token SupersetKeyword "superset"
180 %token SubsetKeyword "subset"
181 %token PatternKeyword "pattern"
182 %token PermutationKeyword "permutation"
183 %token LengthKeyword "length"
184 %token IfpresentKeyword "ifpresent"
185 %token InfinityKeyword "infinity"
186 %token AssignmentChar ":= or ="
187 %token ConcatChar "&="
188 %token LogFile "LogFile or FileName"
189 %token EmergencyLogging
190 %token EmergencyLoggingBehaviour
191 %token EmergencyLoggingMask
192 %token EmergencyLoggingForFailVerdict
193 %token BufferAll
194 %token BufferMasked
195 %token FileMask
196 %token ConsoleMask
197 %token TimestampFormat
198 %token ConsoleTimestampFormat
199 %token SourceInfoFormat "LogSourceInfo or SourceInfoFormat"
200 %token AppendFile
201 %token LogEventTypes
202 %token LogEntityName
203 %token BeginControlPart
204 %token EndControlPart
205 %token BeginTestCase
206 %token EndTestCase
207 %token <str_val> Identifier
208 %token <str_val> ASN1LowerIdentifier "ASN.1 identifier beginning with a lowercase letter"
209 %token <int_val> Number MPNumber "integer value"
210 %token <float_val> Float MPFloat "float value"
211 %token <bool_val> BooleanValue "true or false"
212 %token <verdict_val> VerdictValue
213 %token <bitstring_val> Bstring "bit string value"
214 %token <hexstring_val> Hstring "hex string value"
215 %token <octetstring_val> Ostring "octet string value"
216 %token <str_val> BstringMatch "bit string template"
217 %token <str_val> HstringMatch "hex string template"
218 %token <str_val> OstringMatch "octet string template"
219 %token <charstring_val> Cstring MPCstring "charstring value"
220 %token <str_val> UIDval
221 %token DNSName "hostname"
222 /* a single bit */
223 %token <logseverity_val> LoggingBit
224 /* a collection of bits */
225 %token <logseverity_val> LoggingBitCollection
226 %token SubCategories
227 %token <emergency_logging_behaviour_value> EmergencyLoggingBehaviourValue "BufferAll or BufferMasked"
228 %token <timestamp_value> TimestampValue "Time, Datetime or Seconds"
229 %token <source_info_value> SourceInfoValue "None, Single or Stack"
230 %token <bool_val> YesNo "yes or no"
231 %token LocalAddress
232 %token TCPPort
233 %token KillTimer
234 %token NumHCs
235 %token UnixSocketEnabled
236 %token YesToken "yes"
237 %token NoToken "no"
238 %token LogFileSize
239 %token LogFileNumber
240 %token DiskFullAction
241 %token MatchingHints
242 %token LoggerPlugins
243 %token Error
244 %token Stop
245 %token Retry
246 %token Delete
247 %token TtcnStringParsingKeyword
248 %token DisableProfilerKeyword "DisableProfiler"
249 %token DisableCoverageKeyword "DisableCoverage"
250 %token DatabaseFileKeyword "DatabaseFile"
251 %token AggregateDataKeyword "AggregateData"
252 %token StatisticsFileKeyword "StatisticsFile"
253 %token DisableStatisticsKeyword "DisableStatistics"
254 %token StatisticsFilterKeyword "StatisticsFilter"
255 %token StartAutomaticallyKeyword "StartAutomatically"
256 %token NetLineTimesKeyword "NetLineTimes"
257 %token NetFunctionTimesKeyword "NetFunctionTimes"
258 %token <uint_val> ProfilerStatsFlag "profiler statistics filter"
259
260 %type <int_val> IntegerValue
261 %type <float_val> FloatValue
262 %type <objid_val> ObjIdValue ObjIdComponentList
263 %type <int_val> ObjIdComponent NumberForm NameAndNumberForm
264
265 %type <universal_charstring_val> UniversalCharstringValue UniversalCharstringFragment
266 %type <universal_char_val> Quadruple
267 %type <uid_list> USI UIDlike
268
269 %type <str_val> LoggerPluginId
270 %type <logging_plugins> LoggerPlugin LoggerPluginList
271 %type <logging_params> LoggingParam
272 %type <logging_param_line> LoggingParamLines
273 %type <str_val> LogFileName StringValue
274 /* a collection of bits */
275 %type <logoptions_val> LoggingBitmask
276 %type <logoptions_val> LoggingBitOrCollection
277 %type <source_info_value> SourceInfoSetting
278 %type <bool_val> YesNoOrBoolean
279 %type <log_event_types_value> LogEventTypesValue
280 %type <disk_full_action_value> DiskFullActionValue
281 %type <str_val> Command
282 %type <matching_verbosity_value> VerbosityValue
283 %type <comp_id> ComponentId
284 %type <str_val> TestportName ArrayRef TestportParameterName
285 TestportParameterValue
286
287 %type <execute_item_val> ExecuteItem
288
289 %type <bitstring_val> BitstringValue
290 %type <hexstring_val> HexstringValue
291 %type <octetstring_val> OctetstringValue
292
293 %type <name_vector> ParameterName ParameterNameSegment
294 %type <param_optype_val> ParamOpType
295 %type <str_val> FieldName
296 %type <module_param_val> ParameterValue SimpleParameterValue ParameterValueOrNotUsedSymbol
297 FieldValue ArrayItem IndexItem IndexItemList FieldValueList ArrayItemList CompoundValue IntegerRange FloatRange StringRange
298 ParameterExpression ParameterReference
299 %type <module_param_list> TemplateItemList
300 %type <module_param_length_restriction> LengthMatch
301 %type <str_val> PatternChunk
302 %type <int_native> IndexItemIndex LengthBound
303 %type <uint_val> ProfilerStatsFlags
304
305 %destructor { Free($$); }
306 ArrayRef
307 ASN1LowerIdentifier
308 Command
309 FieldName
310 Identifier
311 LogFileName
312 StringValue
313 TestportName
314 TestportParameterName
315 TestportParameterValue
316 PatternChunk
317 BstringMatch
318 HstringMatch
319 OstringMatch
320
321 %destructor { Free($$.components_ptr); }
322 ObjIdComponentList
323 ObjIdValue
324
325 %destructor { Free($$.bits_ptr); }
326 Bstring
327 BitstringValue
328
329 %destructor { Free($$.nibbles_ptr); }
330 Hstring
331 HexstringValue
332
333 %destructor { Free($$.octets_ptr); }
334 Ostring
335 OctetstringValue
336
337 %destructor { Free($$.chars_ptr); }
338 Cstring
339 MPCstring
340
341 %destructor { Free($$.uchars_ptr); }
342 UniversalCharstringFragment
343 UniversalCharstringValue
344
345 %destructor { if ($$.id_selector == COMPONENT_ID_NAME) Free($$.id_name); }
346 ComponentId
347
348 %destructor { Free($$.module_name); Free($$.testcase_name); }
349 ExecuteItem
350
351 %destructor { delete $$; }
352 IntegerValue
353 NameAndNumberForm
354 Number
355 MPNumber
356 NumberForm
357 ObjIdComponent
358 ParameterValue
359 SimpleParameterValue
360 ParameterValueOrNotUsedSymbol
361 ArrayItemList
362 FieldValueList
363 IndexItemList
364 CompoundValue
365 ArrayItem
366 FieldValue
367 IndexItem
368 IntegerRange
369 FloatRange
370 StringRange
371 ParameterExpression
372 ParameterReference
373
374 %destructor { delete $$; }
375 LengthMatch
376
377 %destructor { for(size_t i=0; i<$$->size(); i++) { delete $$->at(i); } delete $$; }
378 TemplateItemList
379
380 %destructor { for(size_t i=0; i<$$->size(); i++) { Free($$->at(i)); } delete $$; }
381 ParameterName
382 ParameterNameSegment
383
384 %left '&' /* to avoid shift/reduce conflicts */
385 %left '+' '-'
386 %left '*' '/'
387 %left UnarySign
388
389 %expect 1
390
391 /*
392 1 conflict:
393 When seeing a '*' token after a module parameter expression the parser cannot
394 decide whether the token is a multiplication operator (shift) or it refers to
395 all modules in the next module parameter (reduce).
396 */
397 %%
398
399 GrammarRoot:
400 ConfigFile
401 {
402 if (Ttcn_String_Parsing::happening() || Debugger_Value_Parsing::happening()) {
403 config_process_error("Config file cannot be parsed as ttcn string");
404 }
405 }
406 | TtcnStringParsingKeyword ParameterValue
407 {
408 parsed_module_param = $2;
409 }
410 ;
411
412 ConfigFile:
413 /* empty */
414 | ConfigFile Section
415 ;
416
417 Section:
418 ModuleParametersSection
419 | LoggingSection
420 | ProfilerSection
421 | TestportParametersSection
422 | ExecuteSection
423 | ExternalCommandsSection
424 | GroupsSection
425 | ComponentsSection
426 | MainControllerSection
427 | IncludeSection
428 | DefineSection
429 ;
430
431 ModuleParametersSection:
432 ModuleParametersKeyword ModuleParameters
433 ;
434
435 ModuleParameters:
436 /* empty */
437 | ModuleParameters ModuleParameter optSemiColon
438 ;
439
440 ModuleParameter:
441 ParameterName ParamOpType ParameterValue
442 {
443 Module_Param* mp = $3;
444 mp->set_id(new Module_Param_Name(*$1));
445 mp->set_operation_type($2);
446 set_param(*mp);
447 delete mp;
448 delete $1;
449 }
450 ;
451
452 ParameterName:
453 ParameterNameSegment { $$ = $1; }
454 | '*' '.' ParameterNameSegment { $$ = $3; }
455 ;
456
457 ParameterNameSegment:
458 ParameterNameSegment '.' Identifier
459 {
460 $$ = $1;
461 $$->push_back($3);
462 }
463 | ParameterNameSegment IndexItemIndex
464 {
465 $$ = $1;
466 $$->push_back(mprintf("%d", $2));
467 }
468 | Identifier
469 {
470 $$ = new Vector<char*>();
471 $$->push_back($1);
472 }
473 ;
474
475 ParameterValue:
476 ParameterExpression
477 {
478 $$ = $1;
479 }
480 | ParameterExpression LengthMatch
481 {
482 $$ = $1;
483 $$->set_length_restriction($2);
484 }
485 | ParameterExpression IfpresentKeyword
486 {
487 $$ = $1;
488 $$->set_ifpresent();
489 }
490 | ParameterExpression LengthMatch IfpresentKeyword
491 {
492 $$ = $1;
493 $$->set_length_restriction($2);
494 $$->set_ifpresent();
495 }
496 ;
497
498 LengthMatch:
499 LengthKeyword '(' LengthBound ')'
500 {
501 $$ = new Module_Param_Length_Restriction();
502 $$->set_single((size_t)$3);
503 }
504 | LengthKeyword '(' LengthBound DotDot LengthBound ')'
505 {
506 if ($3>$5) {
507 config_process_error("invalid length restriction: lower bound > upper bound");
508 }
509 $$ = new Module_Param_Length_Restriction();
510 $$->set_min((size_t)$3);
511 $$->set_max((size_t)$5);
512 }
513 | LengthKeyword '(' LengthBound DotDot InfinityKeyword ')'
514 {
515 $$ = new Module_Param_Length_Restriction();
516 $$->set_min((size_t)$3);
517 }
518 ;
519
520 LengthBound:
521 ParameterExpression
522 {
523 $1->set_id(new Module_Param_CustomName(mcopystr("length bound")));
524 INTEGER tmp;
525 tmp.set_param(*$1);
526 if (!tmp.get_val().is_native()) {
527 config_process_error("bignum length restriction bound.");
528 $$ = 0;
529 } else if (tmp.get_val().is_negative()) {
530 config_process_error("negative length restriction bound.");
531 $$ = 0;
532 } else {
533 $$ = tmp;
534 }
535 delete $1;
536 }
537 ;
538
539 // one global rule for expressions in module parameters
540 // the expression's result will be calculated by set_param()
541 ParameterExpression:
542 SimpleParameterValue { $$ = $1; }
543 | ParameterReference { $$ = $1; }
544 | '(' ParameterExpression ')' { $$ = $2; }
545 | '+' ParameterExpression %prec UnarySign { $$ = $2; }
546 | '-' ParameterExpression %prec UnarySign { $$ = new Module_Param_Expression($2); }
547 | ParameterExpression '+' ParameterExpression
548 {
549 $$ = new Module_Param_Expression(Module_Param::EXPR_ADD, $1, $3);
550 }
551 | ParameterExpression '-' ParameterExpression
552 {
553 $$ = new Module_Param_Expression(Module_Param::EXPR_SUBTRACT, $1, $3);
554 }
555 | ParameterExpression '*' ParameterExpression
556 {
557 $$ = new Module_Param_Expression(Module_Param::EXPR_MULTIPLY, $1, $3);
558 }
559 | ParameterExpression '/' ParameterExpression
560 {
561 $$ = new Module_Param_Expression(Module_Param::EXPR_DIVIDE, $1, $3);
562 }
563 | ParameterExpression '&' ParameterExpression
564 {
565 $$ = new Module_Param_Expression(Module_Param::EXPR_CONCATENATE, $1, $3);
566 }
567 ;
568
569 ParameterReference:
570 // enumerated values are also treated as references by the parser,
571 // these will be sorted out later during set_param()
572 ParameterNameSegment
573 {
574 $$ = new Module_Param_Reference(new Module_Param_Name(*$1));
575 }
576 ;
577
578 SimpleParameterValue:
579 MPNumber
580 {
581 $$ = new Module_Param_Integer($1);
582 }
583 | MPFloat
584 {
585 $$ = new Module_Param_Float($1);
586 }
587 | BooleanValue
588 {
589 $$ = new Module_Param_Boolean($1);
590 }
591 | ObjIdValue
592 {
593 $$ = new Module_Param_Objid($1.n_components, $1.components_ptr);
594 }
595 | VerdictValue
596 {
597 $$ = new Module_Param_Verdict($1);
598 }
599 | BitstringValue
600 {
601 $$ = new Module_Param_Bitstring($1.n_bits, $1.bits_ptr);
602 }
603 | HexstringValue
604 {
605 $$ = new Module_Param_Hexstring($1.n_nibbles, $1.nibbles_ptr);
606 }
607 | OctetstringValue
608 {
609 $$ = new Module_Param_Octetstring($1.n_octets, $1.octets_ptr);
610 }
611 | MPCstring
612 {
613 $$ = new Module_Param_Charstring($1.n_chars, $1.chars_ptr);
614 }
615 | UniversalCharstringValue
616 {
617 $$ = new Module_Param_Universal_Charstring($1.n_uchars, $1.uchars_ptr);
618 }
619 | OmitKeyword
620 {
621 $$ = new Module_Param_Omit();
622 }
623 | NULLKeyword
624 {
625 $$ = new Module_Param_Asn_Null();
626 }
627 | nullKeyword
628 {
629 $$ = new Module_Param_Ttcn_Null();
630 }
631 | MTCKeyword
632 {
633 $$ = new Module_Param_Ttcn_mtc();
634 }
635 | SystemKeyword
636 {
637 $$ = new Module_Param_Ttcn_system();
638 }
639 | '?'
640 {
641 $$ = new Module_Param_Any();
642 }
643 | '*'
644 {
645 $$ = new Module_Param_AnyOrNone();
646 }
647 | IntegerRange
648 {
649 $$ = $1;
650 }
651 | FloatRange
652 {
653 $$ = $1;
654 }
655 | StringRange
656 {
657 $$ = $1;
658 }
659 | PatternKeyword PatternChunk
660 {
661 $$ = new Module_Param_Pattern($2);
662 }
663 | BstringMatch
664 {
665 // conversion
666 int n_chars = (int)mstrlen($1);
667 unsigned char* chars_ptr = (unsigned char*)Malloc(n_chars*sizeof(unsigned char));
668 for (int i=0; i<n_chars; i++) {
669 switch ($1[i]) {
670 case '0':
671 chars_ptr[i] = 0;
672 break;
673 case '1':
674 chars_ptr[i] = 1;
675 break;
676 case '?':
677 chars_ptr[i] = 2;
678 break;
679 case '*':
680 chars_ptr[i] = 3;
681 break;
682 default:
683 chars_ptr[i] = 0;
684 config_process_error_f("Invalid char (%c) in bitstring template", $1[i]);
685 }
686 }
687 Free($1);
688 $$ = new Module_Param_Bitstring_Template(n_chars, chars_ptr);
689 }
690 | HstringMatch
691 {
692 int n_chars = (int)mstrlen($1);
693 unsigned char* chars_ptr = (unsigned char*)Malloc(n_chars*sizeof(unsigned char));
694 for (int i=0; i<n_chars; i++) {
695 if ($1[i]=='?') chars_ptr[i] = 16;
696 else if ($1[i]=='*') chars_ptr[i] = 17;
697 else chars_ptr[i] = char_to_hexdigit_($1[i]);
698 }
699 Free($1);
700 $$ = new Module_Param_Hexstring_Template(n_chars, chars_ptr);
701 }
702 | OstringMatch
703 {
704 Vector<unsigned short> octet_vec;
705 int str_len = (int)mstrlen($1);
706 for (int i=0; i<str_len; i++) {
707 unsigned short num;
708 if ($1[i]=='?') num = 256;
709 else if ($1[i]=='*') num = 257;
710 else {
711 // first digit
712 num = 16 * char_to_hexdigit_($1[i]);
713 i++;
714 if (i>=str_len) config_process_error("Unexpected end of octetstring pattern");
715 // second digit
716 num += char_to_hexdigit_($1[i]);
717 }
718 octet_vec.push_back(num);
719 }
720 Free($1);
721 int n_chars = (int)octet_vec.size();
722 unsigned short* chars_ptr = (unsigned short*)Malloc(n_chars*sizeof(unsigned short));
723 for (int i=0; i<n_chars; i++) chars_ptr[i] = octet_vec[i];
724 $$ = new Module_Param_Octetstring_Template(n_chars, chars_ptr);
725 }
726 | CompoundValue
727 {
728 $$ = $1;
729 }
730 ;
731
732 PatternChunk:
733 MPCstring
734 {
735 $$ = mcopystr($1.chars_ptr);
736 Free($1.chars_ptr);
737 }
738 | Quadruple
739 {
740 $$ = mprintf("\\q{%d,%d,%d,%d}", $1.uc_group, $1.uc_plane, $1.uc_row, $1.uc_cell);
741 }
742 ;
743
744 IntegerRange:
745 '(' '-' InfinityKeyword DotDot MPNumber ')'
746 {
747 $$ = new Module_Param_IntRange(NULL, $5);
748 }
749 | '(' MPNumber DotDot MPNumber ')'
750 {
751 $$ = new Module_Param_IntRange($2, $4);
752 }
753 | '(' MPNumber DotDot InfinityKeyword ')'
754 {
755 $$ = new Module_Param_IntRange($2, NULL);
756 }
757 ;
758
759 FloatRange:
760 '(' '-' InfinityKeyword DotDot MPFloat ')'
761 {
762 $$ = new Module_Param_FloatRange(0.0, false, $5, true);
763 }
764 | '(' MPFloat DotDot MPFloat ')'
765 {
766 $$ = new Module_Param_FloatRange($2, true, $4, true);
767 }
768 | '(' MPFloat DotDot InfinityKeyword ')'
769 {
770 $$ = new Module_Param_FloatRange($2, true, 0.0, false);
771 }
772 ;
773
774 StringRange:
775 '(' UniversalCharstringFragment DotDot UniversalCharstringFragment ')'
776 {
777 universal_char lower; lower.uc_group=lower.uc_plane=lower.uc_row=lower.uc_cell=0;
778 universal_char upper; upper.uc_group=upper.uc_plane=upper.uc_row=upper.uc_cell=0;
779 if ($2.n_uchars!=1) {
780 config_process_error("Lower bound of char range must be 1 character only");
781 } else if ($4.n_uchars!=1) {
782 config_process_error("Upper bound of char range must be 1 character only");
783 } else {
784 lower = *($2.uchars_ptr);
785 upper = *($4.uchars_ptr);
786 if (upper<lower) {
787 config_process_error("Lower bound is larger than upper bound in the char range");
788 lower = upper;
789 }
790 }
791 Free($2.uchars_ptr);
792 Free($4.uchars_ptr);
793 $$ = new Module_Param_StringRange(lower, upper);
794 }
795 ;
796
797 // integers outside of the [MODULE_PARAMETERS] section
798 IntegerValue:
799 Number { $$ = $1; }
800 | '(' IntegerValue ')' { $$ = $2; }
801 | '+' IntegerValue %prec UnarySign { $$ = $2; }
802 | '-' IntegerValue %prec UnarySign
803 {
804 INTEGER op1;
805 op1.set_val(*$2);
806 $$ = new int_val_t((-op1).get_val());
807 delete $2;
808 }
809 | IntegerValue '+' IntegerValue
810 {
811 INTEGER op1, op2;
812 op1.set_val(*$1);
813 op2.set_val(*$3);
814 $$ = new int_val_t((op1 + op2).get_val());
815 delete $1;
816 delete $3;
817 }
818 | IntegerValue '-' IntegerValue
819 {
820 INTEGER op1, op2;
821 op1.set_val(*$1);
822 op2.set_val(*$3);
823 $$ = new int_val_t((op1 - op2).get_val());
824 delete $1;
825 delete $3;
826 }
827 | IntegerValue '*' IntegerValue
828 {
829 INTEGER op1, op2;
830 op1.set_val(*$1);
831 op2.set_val(*$3);
832 $$ = new int_val_t((op1 * op2).get_val());
833 delete $1;
834 delete $3;
835 }
836 | IntegerValue '/' IntegerValue
837 {
838 if (*$3 == 0) {
839 config_process_error("Integer division by zero.");
840 $$ = new int_val_t((RInt)0);
841 delete $1;
842 delete $3;
843 } else {
844 INTEGER op1, op2;
845 op1.set_val(*$1);
846 op2.set_val(*$3);
847 $$ = new int_val_t((op1 / op2).get_val());
848 delete $1;
849 delete $3;
850 }
851 }
852 ;
853
854 // floats outside of the [MODULE_PARAMETERS] section
855 FloatValue:
856 Float { $$ = $1; }
857 | '(' FloatValue ')' { $$ = $2; }
858 | '+' FloatValue %prec UnarySign { $$ = $2; }
859 | '-' FloatValue %prec UnarySign { $$ = -$2; }
860 | FloatValue '+' FloatValue { $$ = $1 + $3; }
861 | FloatValue '-' FloatValue { $$ = $1 - $3; }
862 | FloatValue '*' FloatValue { $$ = $1 * $3; }
863 | FloatValue '/' FloatValue
864 {
865 if ($3 == 0.0) {
866 config_process_error("Floating point division by zero.");
867 $$ = 0.0;
868 } else $$ = $1 / $3;
869 }
870 ;
871
872 ObjIdValue:
873 ObjIdKeyword '{' ObjIdComponentList '}' { $$ = $3; }
874 ;
875
876 ObjIdComponentList:
877 ObjIdComponent
878 {
879 $$.n_components = 1;
880 $$.components_ptr = (int *)Malloc(sizeof(int));
881 $$.components_ptr[0] = $1->get_val();
882 delete $1;
883 }
884 | ObjIdComponentList ObjIdComponent
885 {
886 $$.n_components = $1.n_components + 1;
887 $$.components_ptr = (int *)Realloc($1.components_ptr,
888 $$.n_components * sizeof(int));
889 $$.components_ptr[$$.n_components - 1] = $2->get_val();
890 delete $2;
891 }
892 ;
893
894 ObjIdComponent:
895 NumberForm { $$ = $1; }
896 | NameAndNumberForm { $$ = $1; }
897 ;
898
899 NumberForm:
900 MPNumber { $$ = $1; }
901 ;
902
903 NameAndNumberForm:
904 Identifier '(' MPNumber ')'
905 {
906 Free($1);
907 $$ = $3;
908 }
909 ;
910
911 BitstringValue:
912 Bstring { $$ = $1; }
913 ;
914
915 HexstringValue:
916 Hstring { $$ = $1; }
917 ;
918
919 OctetstringValue:
920 Ostring { $$ = $1; }
921 ;
922
923 UniversalCharstringValue:
924 Quadruple
925 {
926 $$.n_uchars = 1;
927 $$.uchars_ptr = (universal_char*)Malloc(sizeof(universal_char));
928 $$.uchars_ptr[0] = $1;
929 }
930 | USI
931 {
932 $$.n_uchars = $1.nElements;
933 $$.uchars_ptr = (universal_char*)Malloc($$.n_uchars * sizeof(universal_char));
934 for (int i = 0; i < $$.n_uchars; ++i) {
935 size_t offset = 1; //Always starts with u or U
936 offset = $1.elements[i][1] == '+' ? offset + 1 : offset; //Optional '+'
937
938 char* p;
939 unsigned long int_val = strtoul($1.elements[i] + offset, &p, 16);
940 if(*p != 0) {
941 //Error, should not happen
942 config_process_error_f("Invalid hexadecimal string %s.", $1.elements[i] + offset);
943 }
944
945 //Fill in the quadruple
946 $$.uchars_ptr[i].uc_group = (int_val >> 24) & 0xFF;
947 $$.uchars_ptr[i].uc_plane = (int_val >> 16) & 0xFF;
948 $$.uchars_ptr[i].uc_row = (int_val >> 8) & 0xFF;
949 $$.uchars_ptr[i].uc_cell = int_val & 0xFF;
950
951 Free((char*)$1.elements[i]);
952 }
953 Free($1.elements);
954 }
955 ;
956
957 UniversalCharstringFragment:
958 MPCstring
959 {
960 $$.n_uchars = $1.n_chars;
961 $$.uchars_ptr = (universal_char*)
962 Malloc($$.n_uchars * sizeof(universal_char));
963 for (int i = 0; i < $1.n_chars; i++) {
964 $$.uchars_ptr[i].uc_group = 0;
965 $$.uchars_ptr[i].uc_plane = 0;
966 $$.uchars_ptr[i].uc_row = 0;
967 $$.uchars_ptr[i].uc_cell = $1.chars_ptr[i];
968 }
969 Free($1.chars_ptr);
970 }
971 | Quadruple
972 {
973 $$.n_uchars = 1;
974 $$.uchars_ptr = (universal_char*)Malloc(sizeof(universal_char));
975 $$.uchars_ptr[0] = $1;
976 }
977 ;
978
979 Quadruple:
980 CharKeyword '(' ParameterExpression ',' ParameterExpression ','
981 ParameterExpression ',' ParameterExpression ')'
982 {
983 $3->set_id(new Module_Param_CustomName(mcopystr("quadruple group")));
984 $5->set_id(new Module_Param_CustomName(mcopystr("quadruple plane")));
985 $7->set_id(new Module_Param_CustomName(mcopystr("quadruple row")));
986 $9->set_id(new Module_Param_CustomName(mcopystr("quadruple cell")));
987 INTEGER g, p, r, c;
988 g.set_param(*$3);
989 p.set_param(*$5);
990 r.set_param(*$7);
991 c.set_param(*$9);
992 if (g < 0 || g > 127) {
993 char *s = g.get_val().as_string();
994 config_process_error_f("The first number of quadruple (group) must be "
995 "within the range 0 .. 127 instead of %s.", s);
996 Free(s);
997 $$.uc_group = g < 0 ? 0 : 127;
998 } else {
999 $$.uc_group = g;
1000 }
1001 if (p < 0 || p > 255) {
1002 char *s = p.get_val().as_string();
1003 config_process_error_f("The second number of quadruple (plane) must be "
1004 "within the range 0 .. 255 instead of %s.", s);
1005 Free(s);
1006 $$.uc_plane = p < 0 ? 0 : 255;
1007 } else {
1008 $$.uc_plane = p;
1009 }
1010 if (r < 0 || r > 255) {
1011 char *s = r.get_val().as_string();
1012 config_process_error_f("The third number of quadruple (row) must be "
1013 "within the range 0 .. 255 instead of %s.", s);
1014 Free(s);
1015 $$.uc_row = r < 0 ? 0 : 255;
1016 } else {
1017 $$.uc_row = r;
1018 }
1019 if (c < 0 || c > 255) {
1020 char *s = c.get_val().as_string();
1021 config_process_error_f("The fourth number of quadruple (cell) must be "
1022 "within the range 0 .. 255 instead of %s.", s);
1023 Free(s);
1024 $$.uc_cell = c < 0 ? 0 : 255;
1025 } else {
1026 $$.uc_cell = c;
1027 }
1028 delete $3;
1029 delete $5;
1030 delete $7;
1031 delete $9;
1032 }
1033 ;
1034
1035 USI:
1036 CharKeyword '(' UIDlike ')'
1037 {
1038 $$ = $3;
1039 }
1040 ;
1041
1042 UIDlike:
1043 UIDval
1044 {
1045 $$.nElements = 1;
1046 $$.elements = (const char**)
1047 Malloc($$.nElements * sizeof(*$$.elements));
1048 $$.elements[$$.nElements-1] = $1;
1049 }
1050 | UIDlike ',' UIDval {
1051 $$.nElements = $1.nElements + 1;
1052 $$.elements = (const char**)
1053 Realloc($1.elements, ($$.nElements) * sizeof(*$1.elements));
1054 $$.elements[$$.nElements-1] = $3;
1055 }
1056 ;
1057
1058 // character strings outside of the [MODULE_PARAMETERS] section
1059 StringValue:
1060 Cstring
1061 {
1062 $$ = mcopystr($1.chars_ptr);
1063 Free($1.chars_ptr);
1064 }
1065 | StringValue '&' Cstring
1066 {
1067 $$ = mputstr($1, $3.chars_ptr);
1068 Free($3.chars_ptr);
1069 }
1070 ;
1071
1072 CompoundValue:
1073 '{' '}'
1074 {
1075 $$ = new Module_Param_Value_List();
1076 }
1077 | '{' FieldValueList '}'
1078 {
1079 $$ = $2;
1080 }
1081 | '{' ArrayItemList '}'
1082 {
1083 $$ = $2;
1084 }
1085 | '{' IndexItemList '}'
1086 {
1087 $$ = $2;
1088 }
1089 | '(' ParameterValue ',' TemplateItemList ')' /* at least 2 elements to avoid shift/reduce conflicts with the ParameterExpression rule */
1090 {
1091 $$ = new Module_Param_List_Template();
1092 $2->set_id(new Module_Param_Index($$->get_size(),false));
1093 $$->add_elem($2);
1094 $$->add_list_with_implicit_ids($4);
1095 delete $4;
1096 }
1097 | ComplementKeyword '(' TemplateItemList ')'
1098 {
1099 $$ = new Module_Param_ComplementList_Template();
1100 $$->add_list_with_implicit_ids($3);
1101 delete $3;
1102 }
1103 | SupersetKeyword '(' TemplateItemList ')'
1104 {
1105 $$ = new Module_Param_Superset_Template();
1106 $$->add_list_with_implicit_ids($3);
1107 delete $3;
1108 }
1109 | SubsetKeyword '(' TemplateItemList ')'
1110 {
1111 $$ = new Module_Param_Subset_Template();
1112 $$->add_list_with_implicit_ids($3);
1113 delete $3;
1114 }
1115 ;
1116
1117 ParameterValueOrNotUsedSymbol:
1118 ParameterValue
1119 {
1120 $$ = $1;
1121 }
1122 | '-'
1123 {
1124 $$ = new Module_Param_NotUsed();
1125 }
1126 ;
1127
1128 TemplateItemList:
1129 ParameterValue
1130 {
1131 $$ = new Vector<Module_Param*>();
1132 $$->push_back($1);
1133 }
1134 | TemplateItemList ',' ParameterValue
1135 {
1136 $$ = $1;
1137 $$->push_back($3);
1138 }
1139 ;
1140
1141 FieldValueList:
1142 FieldValue
1143 {
1144 $$ = new Module_Param_Assignment_List();
1145 $$->add_elem($1);
1146 }
1147 | FieldValueList ',' FieldValue
1148 {
1149 $$ = $1;
1150 $$->add_elem($3);
1151 }
1152 ;
1153
1154 FieldValue:
1155 FieldName AssignmentChar ParameterValueOrNotUsedSymbol
1156 {
1157 $$ = $3;
1158 $$->set_id(new Module_Param_FieldName($1));
1159 }
1160 ;
1161
1162 FieldName:
1163 Identifier
1164 {
1165 $$ = $1;
1166 }
1167 | ASN1LowerIdentifier
1168 {
1169 $$ = $1;
1170 }
1171 ;
1172
1173 ArrayItemList:
1174 ArrayItem
1175 {
1176 $$ = new Module_Param_Value_List();
1177 $1->set_id(new Module_Param_Index($$->get_size(),false));
1178 $$->add_elem($1);
1179 }
1180 | ArrayItemList ',' ArrayItem
1181 {
1182 $$ = $1;
1183 $3->set_id(new Module_Param_Index($$->get_size(),false));
1184 $$->add_elem($3);
1185 }
1186 ;
1187
1188 ArrayItem:
1189 ParameterValueOrNotUsedSymbol
1190 {
1191 $$ = $1;
1192 }
1193 | PermutationKeyword '(' TemplateItemList ')'
1194 {
1195 $$ = new Module_Param_Permutation_Template();
1196 $$->add_list_with_implicit_ids($3);
1197 delete $3;
1198 }
1199 ;
1200
1201 IndexItemList:
1202 IndexItem
1203 {
1204 $$ = new Module_Param_Indexed_List();
1205 $$->add_elem($1);
1206 }
1207 | IndexItemList ',' IndexItem
1208 {
1209 $$ = $1;
1210 $$->add_elem($3);
1211 }
1212 ;
1213
1214 IndexItem:
1215 IndexItemIndex AssignmentChar ParameterValue
1216 {
1217 $$ = $3;
1218 $$->set_id(new Module_Param_Index((size_t)$1,true));
1219 }
1220 ;
1221
1222 IndexItemIndex:
1223 '[' ParameterExpression ']'
1224 {
1225 $2->set_id(new Module_Param_CustomName(mcopystr("array index")));
1226 INTEGER tmp;
1227 tmp.set_param(*$2);
1228 if (!tmp.get_val().is_native()) {
1229 config_process_error("bignum index."); // todo
1230 }
1231 if (tmp.get_val().is_negative()) {
1232 config_process_error("negative index."); // todo
1233 }
1234 $$ = tmp;
1235 delete $2;
1236 }
1237 ;
1238
1239 /*************** [LOGGING] section *********************************/
1240
1241 LoggingSection:
1242 LoggingKeyword LoggingParamList
1243 ;
1244
1245 LoggingParamList:
1246 /* empty */
1247 | LoggingParamList LoggingParamLines optSemiColon
1248 {
1249 // Centralized duplication handling for `[LOGGING]'.
1250 if ($2.logparam.log_param_selection != LP_UNKNOWN && TTCN_Logger::add_parameter($2)) {
1251 switch ($2.logparam.log_param_selection) {
1252 case LP_FILEMASK:
1253 check_duplicate_option("LOGGING", "FileMask", file_mask_set);
1254 break;
1255 case LP_CONSOLEMASK:
1256 check_duplicate_option("LOGGING", "ConsoleMask", console_mask_set);
1257 break;
1258 case LP_LOGFILESIZE:
1259 check_duplicate_option("LOGGING", "LogFileSize", log_file_size_set);
1260 break;
1261 case LP_LOGFILENUMBER:
1262 check_duplicate_option("LOGGING", "LogFileNumber", log_file_number_set);
1263 break;
1264 case LP_DISKFULLACTION:
1265 check_duplicate_option("LOGGING", "DiskFullAction", log_disk_full_action_set);
1266 break;
1267 case LP_LOGFILE:
1268 check_duplicate_option("LOGGING", "LogFile", file_name_set);
1269 break;
1270 case LP_TIMESTAMPFORMAT:
1271 check_duplicate_option("LOGGING", "TimeStampFormat", timestamp_format_set);
1272 break;
1273 case LP_SOURCEINFOFORMAT:
1274 check_duplicate_option("LOGGING", "SourceInfoFormat", source_info_format_set);
1275 break;
1276 case LP_APPENDFILE:
1277 check_duplicate_option("LOGGING", "AppendFile", append_file_set);
1278 break;
1279 case LP_LOGEVENTTYPES:
1280 check_duplicate_option("LOGGING", "LogEventTypes", log_event_types_set);
1281 break;
1282 case LP_LOGENTITYNAME:
1283 check_duplicate_option("LOGGING", "LogEntityName", log_entity_name_set);
1284 break;
1285 case LP_MATCHINGHINTS:
1286 check_duplicate_option("LOGGING", "MatchingVerbosity", matching_verbosity_set);
1287 break;
1288 case LP_PLUGIN_SPECIFIC:
1289 // It would be an overkill to check for the infinite number of custom parameters...
1290 check_duplicate_option("LOGGING", "PluginSpecific", plugin_specific_set);
1291 break;
1292 default:
1293 break;
1294 }
1295 }
1296 }
1297 ;
1298
1299 LoggingParamLines:
1300 LoggingParam
1301 {
1302 $$.component.id_selector = COMPONENT_ID_ALL;
1303 $$.component.id_name = NULL;
1304 $$.plugin_id = NULL;
1305 $$.logparam = $1;
1306 }
1307 | ComponentId '.' LoggingParam
1308 {
1309 $$.component = $1;
1310 $$.plugin_id = NULL;
1311 $$.logparam = $3;
1312 }
1313 | ComponentId '.' LoggerPluginId '.' LoggingParam
1314 {
1315 $$.component = $1;
1316 $$.plugin_id = $3;
1317 $$.logparam = $5;
1318 }
1319 | LoggerPlugins AssignmentChar '{' LoggerPluginList '}'
1320 {
1321 check_duplicate_option("LOGGING", "LoggerPlugins", logger_plugins_set);
1322 component_id_t comp;
1323 comp.id_selector = COMPONENT_ID_ALL;
1324 comp.id_name = NULL;
1325 logging_plugin_t *plugin = $4;
1326 while (plugin != NULL) {
1327 // `identifier' and `filename' are reused. Various checks and
1328 // validations must be done in the logger itself (e.g. looking for
1329 // duplicate options).
1330 TTCN_Logger::register_plugin(comp, plugin->identifier, plugin->filename);
1331 logging_plugin_t *tmp = plugin;
1332 plugin = tmp->next;
1333 Free(tmp);
1334 }
1335 $$.logparam.log_param_selection = LP_UNKNOWN;
1336 }
1337 | ComponentId '.' LoggerPlugins AssignmentChar '{' LoggerPluginList '}'
1338 {
1339 check_duplicate_option("LOGGING", "LoggerPlugins", logger_plugins_set);
1340 logging_plugin_t *plugin = $6;
1341 while (plugin != NULL) {
1342 TTCN_Logger::register_plugin($1, plugin->identifier, plugin->filename);
1343 logging_plugin_t *tmp = plugin;
1344 plugin = tmp->next;
1345 Free(tmp);
1346 }
1347 // Component names shall be duplicated in `register_plugin()'.
1348 if ($1.id_selector == COMPONENT_ID_NAME)
1349 Free($1.id_name);
1350 $$.logparam.log_param_selection = LP_UNKNOWN;
1351 }
1352 ;
1353
1354 LoggerPluginList:
1355 LoggerPlugin
1356 {
1357 $$ = $1;
1358 }
1359 | LoggerPluginList ',' LoggerPlugin
1360 {
1361 $$ = $3;
1362 $$->next = $1;
1363 }
1364 ;
1365
1366 LoggerPlugin:
1367 Identifier
1368 {
1369 $$ = (logging_plugin_t *)Malloc(sizeof(logging_plugin_t));
1370 $$->identifier = $1;
1371 $$->filename = NULL;
1372 $$->next = NULL;
1373 }
1374 | Identifier AssignmentChar StringValue
1375 {
1376 $$ = (logging_plugin_t *)Malloc(sizeof(logging_plugin_t));
1377 $$->identifier = $1;
1378 $$->filename = $3;
1379 $$->next = NULL;
1380 }
1381 ;
1382
1383 LoggerPluginId:
1384 '*' { $$ = mcopystr("*"); }
1385 | Identifier { $$ = $1; }
1386 ;
1387
1388 LoggingParam:
1389 FileMask AssignmentChar LoggingBitmask
1390 {
1391 $$.log_param_selection = LP_FILEMASK;
1392 $$.logoptions_val = $3;
1393 }
1394 | ConsoleMask AssignmentChar LoggingBitmask
1395 {
1396 $$.log_param_selection = LP_CONSOLEMASK;
1397 $$.logoptions_val = $3;
1398 }
1399 | LogFileSize AssignmentChar Number
1400 {
1401 $$.log_param_selection = LP_LOGFILESIZE;
1402 $$.int_val = (int)$3->get_val();
1403 delete $3;
1404 }
1405 | EmergencyLogging AssignmentChar Number
1406 {
1407 $$.log_param_selection = LP_EMERGENCY;
1408 $$.int_val = (int)$3->get_val();
1409 delete $3;
1410 }
1411 | EmergencyLoggingBehaviour AssignmentChar EmergencyLoggingBehaviourValue
1412 {
1413 $$.log_param_selection = LP_EMERGENCYBEHAVIOR;
1414 $$.emergency_logging_behaviour_value = $3;
1415 }
1416 | EmergencyLoggingMask AssignmentChar LoggingBitmask
1417 {
1418 $$.log_param_selection = LP_EMERGENCYMASK;
1419 $$.logoptions_val = $3;
1420 }
1421 | EmergencyLoggingForFailVerdict AssignmentChar YesNoOrBoolean
1422 {
1423 $$.log_param_selection = LP_EMERGENCYFORFAIL;
1424 $$.bool_val = $3;
1425 }
1426 | LogFileNumber AssignmentChar Number
1427 {
1428 $$.log_param_selection = LP_LOGFILENUMBER;
1429 $$.int_val = (int)$3->get_val();
1430 delete $3;
1431 }
1432 | DiskFullAction AssignmentChar DiskFullActionValue
1433 {
1434 $$.log_param_selection = LP_DISKFULLACTION;
1435 $$.disk_full_action_value = $3;
1436 }
1437 | LogFile AssignmentChar LogFileName
1438 {
1439 $$.log_param_selection = LP_LOGFILE;
1440 $$.str_val = $3;
1441 }
1442 | TimestampFormat AssignmentChar TimestampValue
1443 {
1444 $$.log_param_selection = LP_TIMESTAMPFORMAT;
1445 $$.timestamp_value = $3;
1446 }
1447 | ConsoleTimestampFormat AssignmentChar TimestampValue
1448 {
1449 $$.log_param_selection = LP_UNKNOWN;
1450 }
1451 | SourceInfoFormat AssignmentChar SourceInfoSetting
1452 {
1453 $$.log_param_selection = LP_SOURCEINFOFORMAT;
1454 $$.source_info_value = $3;
1455 }
1456 | AppendFile AssignmentChar YesNoOrBoolean
1457 {
1458 $$.log_param_selection = LP_APPENDFILE;
1459 $$.bool_val = $3;
1460 }
1461 | LogEventTypes AssignmentChar LogEventTypesValue
1462 {
1463 $$.log_param_selection = LP_LOGEVENTTYPES;
1464 $$.log_event_types_value = $3;
1465 }
1466 | LogEntityName AssignmentChar YesNoOrBoolean
1467 {
1468 $$.log_param_selection = LP_LOGENTITYNAME;
1469 $$.bool_val = $3;
1470 }
1471 | MatchingHints AssignmentChar VerbosityValue
1472 {
1473 $$.log_param_selection = LP_MATCHINGHINTS;
1474 $$.matching_verbosity_value = $3;
1475 }
1476 | Identifier AssignmentChar StringValue
1477 {
1478 $$.log_param_selection = LP_PLUGIN_SPECIFIC;
1479 $$.param_name = $1;
1480 $$.str_val = $3;
1481 }
1482 ;
1483
1484 VerbosityValue:
1485 Compact { $$ = TTCN_Logger::VERBOSITY_COMPACT; }
1486 | Detailed { $$ = TTCN_Logger::VERBOSITY_FULL; }
1487 ;
1488
1489 DiskFullActionValue:
1490 Error { $$.type = TTCN_Logger::DISKFULL_ERROR; }
1491 | Stop { $$.type = TTCN_Logger::DISKFULL_STOP; }
1492 | Retry
1493 {
1494 $$.type = TTCN_Logger::DISKFULL_RETRY;
1495 $$.retry_interval = 30; /* default retry interval */
1496 }
1497 | Retry '(' Number ')'
1498 {
1499 $$.type = TTCN_Logger::DISKFULL_RETRY;
1500 $$.retry_interval = (size_t)$3->get_val();
1501 delete $3;
1502 }
1503 | Delete { $$.type = TTCN_Logger::DISKFULL_DELETE; }
1504 ;
1505
1506 LogFileName:
1507 StringValue { $$ = $1; }
1508 ;
1509
1510 LoggingBitOrCollection:
1511 LoggingBit
1512 {
1513 $$.clear();
1514 $$.add_sev($1);
1515 }
1516 | LoggingBitCollection
1517 {
1518 $$.clear();
1519 switch($1)
1520 {
1521 case TTCN_Logger::ACTION_UNQUALIFIED:
1522 $$.add_sev(TTCN_Logger::ACTION_UNQUALIFIED);
1523 break;
1524 case TTCN_Logger::DEFAULTOP_UNQUALIFIED:
1525 $$.add_sev(TTCN_Logger::DEFAULTOP_ACTIVATE);
1526 $$.add_sev(TTCN_Logger::DEFAULTOP_DEACTIVATE);
1527 $$.add_sev(TTCN_Logger::DEFAULTOP_EXIT);
1528 $$.add_sev(TTCN_Logger::DEFAULTOP_UNQUALIFIED);
1529 break;
1530 case TTCN_Logger::ERROR_UNQUALIFIED:
1531 $$.add_sev(TTCN_Logger::ERROR_UNQUALIFIED);
1532 break;
1533 case TTCN_Logger::EXECUTOR_UNQUALIFIED:
1534 $$.add_sev(TTCN_Logger::EXECUTOR_RUNTIME);
1535 $$.add_sev(TTCN_Logger::EXECUTOR_CONFIGDATA);
1536 $$.add_sev(TTCN_Logger::EXECUTOR_EXTCOMMAND);
1537 $$.add_sev(TTCN_Logger::EXECUTOR_COMPONENT);
1538 $$.add_sev(TTCN_Logger::EXECUTOR_LOGOPTIONS);
1539 $$.add_sev(TTCN_Logger::EXECUTOR_UNQUALIFIED);
1540 break;
1541 case TTCN_Logger::FUNCTION_UNQUALIFIED:
1542 $$.add_sev(TTCN_Logger::FUNCTION_RND);
1543 $$.add_sev(TTCN_Logger::FUNCTION_UNQUALIFIED);
1544 break;
1545 case TTCN_Logger::PARALLEL_UNQUALIFIED:
1546 $$.add_sev(TTCN_Logger::PARALLEL_PTC);
1547 $$.add_sev(TTCN_Logger::PARALLEL_PORTCONN);
1548 $$.add_sev(TTCN_Logger::PARALLEL_PORTMAP);
1549 $$.add_sev(TTCN_Logger::PARALLEL_UNQUALIFIED);
1550 break;
1551 case TTCN_Logger::PORTEVENT_UNQUALIFIED:
1552 $$.add_sev(TTCN_Logger::PORTEVENT_PQUEUE);
1553 $$.add_sev(TTCN_Logger::PORTEVENT_MQUEUE);
1554 $$.add_sev(TTCN_Logger::PORTEVENT_STATE);
1555 $$.add_sev(TTCN_Logger::PORTEVENT_PMIN);
1556 $$.add_sev(TTCN_Logger::PORTEVENT_PMOUT);
1557 $$.add_sev(TTCN_Logger::PORTEVENT_PCIN);
1558 $$.add_sev(TTCN_Logger::PORTEVENT_PCOUT);
1559 $$.add_sev(TTCN_Logger::PORTEVENT_MMRECV);
1560 $$.add_sev(TTCN_Logger::PORTEVENT_MMSEND);
1561 $$.add_sev(TTCN_Logger::PORTEVENT_MCRECV);
1562 $$.add_sev(TTCN_Logger::PORTEVENT_MCSEND);
1563 $$.add_sev(TTCN_Logger::PORTEVENT_DUALRECV);
1564 $$.add_sev(TTCN_Logger::PORTEVENT_DUALSEND);
1565 $$.add_sev(TTCN_Logger::PORTEVENT_UNQUALIFIED);
1566 break;
1567 case TTCN_Logger::TESTCASE_UNQUALIFIED:
1568 $$.add_sev(TTCN_Logger::TESTCASE_START);
1569 $$.add_sev(TTCN_Logger::TESTCASE_FINISH);
1570 $$.add_sev(TTCN_Logger::TESTCASE_UNQUALIFIED);
1571 break;
1572 case TTCN_Logger::TIMEROP_UNQUALIFIED:
1573 $$.add_sev(TTCN_Logger::TIMEROP_READ);
1574 $$.add_sev(TTCN_Logger::TIMEROP_START);
1575 $$.add_sev(TTCN_Logger::TIMEROP_GUARD);
1576 $$.add_sev(TTCN_Logger::TIMEROP_STOP);
1577 $$.add_sev(TTCN_Logger::TIMEROP_TIMEOUT);
1578 $$.add_sev(TTCN_Logger::TIMEROP_UNQUALIFIED);
1579 break;
1580 case TTCN_Logger::USER_UNQUALIFIED:
1581 $$.add_sev(TTCN_Logger::USER_UNQUALIFIED);
1582 break;
1583 case TTCN_Logger::STATISTICS_UNQUALIFIED:
1584 $$.add_sev(TTCN_Logger::STATISTICS_VERDICT);
1585 $$.add_sev(TTCN_Logger::STATISTICS_UNQUALIFIED);
1586 break;
1587 case TTCN_Logger::VERDICTOP_UNQUALIFIED:
1588 $$.add_sev(TTCN_Logger::VERDICTOP_GETVERDICT);
1589 $$.add_sev(TTCN_Logger::VERDICTOP_SETVERDICT);
1590 $$.add_sev(TTCN_Logger::VERDICTOP_FINAL);
1591 $$.add_sev(TTCN_Logger::VERDICTOP_UNQUALIFIED);
1592 break;
1593 case TTCN_Logger::WARNING_UNQUALIFIED:
1594 $$.add_sev(TTCN_Logger::WARNING_UNQUALIFIED);
1595 break;
1596 case TTCN_Logger::MATCHING_UNQUALIFIED:
1597 $$.add_sev(TTCN_Logger::MATCHING_DONE);
1598 $$.add_sev(TTCN_Logger::MATCHING_TIMEOUT);
1599 $$.add_sev(TTCN_Logger::MATCHING_PCSUCCESS);
1600 $$.add_sev(TTCN_Logger::MATCHING_PCUNSUCC);
1601 $$.add_sev(TTCN_Logger::MATCHING_PMSUCCESS);
1602 $$.add_sev(TTCN_Logger::MATCHING_PMUNSUCC);
1603 $$.add_sev(TTCN_Logger::MATCHING_MCSUCCESS);
1604 $$.add_sev(TTCN_Logger::MATCHING_MCUNSUCC);
1605 $$.add_sev(TTCN_Logger::MATCHING_MMSUCCESS);
1606 $$.add_sev(TTCN_Logger::MATCHING_MMUNSUCC);
1607 $$.add_sev(TTCN_Logger::MATCHING_PROBLEM);
1608 $$.add_sev(TTCN_Logger::MATCHING_UNQUALIFIED);
1609 break;
1610 case TTCN_Logger::DEBUG_UNQUALIFIED:
1611 $$.add_sev(TTCN_Logger::DEBUG_ENCDEC);
1612 $$.add_sev(TTCN_Logger::DEBUG_TESTPORT);
1613 $$.add_sev(TTCN_Logger::DEBUG_USER);
1614 $$.add_sev(TTCN_Logger::DEBUG_FRAMEWORK);
1615 $$.add_sev(TTCN_Logger::DEBUG_UNQUALIFIED);
1616 break;
1617 case TTCN_Logger::LOG_ALL_IMPORTANT:
1618 $$ = Logging_Bits::log_all;
1619 break;
1620 default:
1621 /* The lexer sent something the parser doesn't understand!
1622 Parser needs to be updated.
1623 */
1624 TTCN_Logger::log_str(TTCN_Logger::ERROR_UNQUALIFIED,
1625 "Internal error: unknown logbit from lexer.");
1626 break;
1627 } // switch
1628 }
1629 ;
1630
1631 LoggingBitmask:
1632 LoggingBitOrCollection
1633 {
1634 $$ = $1;
1635 }
1636 | LoggingBitmask '|' LoggingBitOrCollection
1637 {
1638 $$ = $1;
1639 $$.merge($3);
1640 }
1641 ;
1642
1643 SourceInfoSetting:
1644 SourceInfoValue { $$ = $1; }
1645 | YesNoOrBoolean
1646 {
1647 $$ = $1 ? TTCN_Logger::SINFO_SINGLE : TTCN_Logger::SINFO_NONE;
1648 }
1649 ;
1650
1651 YesNoOrBoolean:
1652 YesNo { $$ = $1; }
1653 | BooleanValue { $$ = $1; }
1654 ;
1655
1656 LogEventTypesValue:
1657 YesNoOrBoolean { $$ = $1 ? TTCN_Logger::LOGEVENTTYPES_YES :
1658 TTCN_Logger::LOGEVENTTYPES_NO; }
1659 | SubCategories { $$ = TTCN_Logger::LOGEVENTTYPES_SUBCATEGORIES; }
1660 | Detailed { $$ = TTCN_Logger::LOGEVENTTYPES_SUBCATEGORIES; }
1661 ;
1662
1663 /*********************** [PROFILER] ********************************/
1664
1665 ProfilerSection:
1666 ProfilerKeyword ProfilerSettings
1667 ;
1668
1669 ProfilerSettings:
1670 /* empty */
1671 | ProfilerSettings ProfilerSetting optSemiColon
1672 ;
1673
1674 ProfilerSetting:
1675 DisableProfilerSetting
1676 | DisableCoverageSetting
1677 | DatabaseFileSetting
1678 | AggregateDataSetting
1679 | StatisticsFileSetting
1680 | DisableStatisticsSetting
1681 | StatisticsFilterSetting
1682 | StartAutomaticallySetting
1683 | NetLineTimesSetting
1684 | NetFunctionTimesSetting
1685 ;
1686
1687 DisableProfilerSetting:
1688 DisableProfilerKeyword AssignmentChar BooleanValue {
1689 ttcn3_prof.set_disable_profiler($3);
1690 }
1691 ;
1692
1693 DisableCoverageSetting:
1694 DisableCoverageKeyword AssignmentChar BooleanValue {
1695 ttcn3_prof.set_disable_coverage($3);
1696 }
1697 ;
1698
1699 DatabaseFileSetting:
1700 DatabaseFileKeyword AssignmentChar StringValue {
1701 ttcn3_prof.set_database_filename($3);
1702 }
1703 ;
1704
1705 AggregateDataSetting:
1706 AggregateDataKeyword AssignmentChar BooleanValue {
1707 ttcn3_prof.set_aggregate_data($3);
1708 }
1709 ;
1710
1711 StatisticsFileSetting:
1712 StatisticsFileKeyword AssignmentChar StringValue {
1713 ttcn3_prof.set_stats_filename($3);
1714 }
1715 ;
1716
1717 DisableStatisticsSetting:
1718 DisableStatisticsKeyword AssignmentChar BooleanValue {
1719 ttcn3_prof.set_disable_stats($3);
1720 }
1721 ;
1722
1723 StatisticsFilterSetting:
1724 StatisticsFilterKeyword AssignmentChar ProfilerStatsFlags {
1725 ttcn3_prof.reset_stats_flags();
1726 ttcn3_prof.add_stats_flags($3);
1727 }
1728 | StatisticsFilterKeyword ConcatChar ProfilerStatsFlags {
1729 ttcn3_prof.add_stats_flags($3);
1730 }
1731 ;
1732
1733 ProfilerStatsFlags:
1734 ProfilerStatsFlag { $$ = $1; }
1735 | ProfilerStatsFlag '&' ProfilerStatsFlags { $$ = $1 | $3; }
1736 | ProfilerStatsFlag '|' ProfilerStatsFlags { $$ = $1 | $3; }
1737 ;
1738
1739 StartAutomaticallySetting:
1740 StartAutomaticallyKeyword AssignmentChar BooleanValue {
1741 if ($3) {
1742 ttcn3_prof.start();
1743 }
1744 else {
1745 ttcn3_prof.stop();
1746 }
1747 }
1748 ;
1749
1750 NetLineTimesSetting:
1751 NetLineTimesKeyword AssignmentChar BooleanValue {
1752 TTCN3_Stack_Depth::set_net_line_times($3);
1753 }
1754 ;
1755
1756 NetFunctionTimesSetting:
1757 NetFunctionTimesKeyword AssignmentChar BooleanValue {
1758 TTCN3_Stack_Depth::set_net_func_times($3);
1759 }
1760 ;
1761
1762
1763 /**************** [TESTPORT_PARAMETERS] ****************************/
1764
1765 TestportParametersSection:
1766 TestportParametersKeyword TestportParameterList
1767 ;
1768
1769 TestportParameterList:
1770 /* empty */
1771 | TestportParameterList TestportParameter optSemiColon
1772 ;
1773
1774 TestportParameter:
1775 ComponentId '.' TestportName '.' TestportParameterName AssignmentChar
1776 TestportParameterValue
1777 {
1778 PORT::add_parameter($1, $3, $5, $7);
1779 if ($1.id_selector == COMPONENT_ID_NAME) Free($1.id_name);
1780 Free($3);
1781 Free($5);
1782 Free($7);
1783 }
1784 ;
1785
1786 ComponentId:
1787 Identifier
1788 {
1789 $$.id_selector = COMPONENT_ID_NAME;
1790 $$.id_name = $1;
1791 }
1792 | Cstring
1793 {
1794 $$.id_selector = COMPONENT_ID_NAME;
1795 $$.id_name = $1.chars_ptr;
1796 }
1797 | Number
1798 {
1799 $$.id_selector = COMPONENT_ID_COMPREF;
1800 $$.id_compref = (component)$1->get_val();
1801 delete $1;
1802 }
1803 | MTCKeyword
1804 {
1805 $$.id_selector = COMPONENT_ID_COMPREF;
1806 $$.id_compref = MTC_COMPREF;
1807 }
1808 | '*'
1809 {
1810 $$.id_selector = COMPONENT_ID_ALL;
1811 $$.id_name = NULL;
1812 }
1813 | SystemKeyword
1814 {
1815 $$.id_selector = COMPONENT_ID_SYSTEM;
1816 $$.id_name = NULL;
1817 }
1818 ;
1819
1820 TestportName:
1821 Identifier { $$ = $1; }
1822 | Identifier ArrayRef
1823 {
1824 $$ = mputstr($1, $2);
1825 Free($2);
1826 }
1827 | '*' { $$ = NULL; }
1828 ;
1829
1830 ArrayRef:
1831 '[' IntegerValue ']'
1832 {
1833 char *s = $2->as_string();
1834 $$ = memptystr();
1835 $$ = mputc ($$, '[');
1836 $$ = mputstr($$, s);
1837 $$ = mputc ($$, ']');
1838 Free(s);
1839 delete $2;
1840 }
1841 | ArrayRef '[' IntegerValue ']'
1842 {
1843 char *s = $3->as_string();
1844 $$ = mputc ($1, '[');
1845 $$ = mputstr($$, s);
1846 $$ = mputc ($$, ']');
1847 Free(s);
1848 delete $3;
1849 }
1850 ;
1851
1852 TestportParameterName:
1853 Identifier { $$ = $1; }
1854 ;
1855
1856 TestportParameterValue:
1857 StringValue { $$ = $1; }
1858 ;
1859
1860 /****************** [EXECUTE] section *************/
1861
1862 ExecuteSection:
1863 ExecuteKeyword ExecuteList
1864 {
1865 if (!TTCN_Runtime::is_single()) config_process_error("Internal error: "
1866 "the Main Controller must not send section [EXECUTE] of the "
1867 "configuration file.");
1868 }
1869 ;
1870
1871 ExecuteList:
1872 /* empty */
1873 | ExecuteList ExecuteItem optSemiColon
1874 {
1875 if (TTCN_Runtime::is_single()) {
1876 execute_list = (execute_list_item *)Realloc(
1877 execute_list, (execute_list_len + 1) *
1878 sizeof(*execute_list));
1879 execute_list[execute_list_len++] = $2;
1880 } else {
1881 Free($2.module_name);
1882 Free($2.testcase_name);
1883 }
1884 }
1885 ;
1886
1887 ExecuteItem:
1888 Identifier
1889 {
1890 $$.module_name = $1;
1891 $$.testcase_name = NULL;
1892 }
1893 | Identifier '.' ControlKeyword
1894 {
1895 $$.module_name = $1;
1896 $$.testcase_name = NULL;
1897 }
1898 | Identifier '.' Identifier
1899 {
1900 $$.module_name = $1;
1901 $$.testcase_name = $3;
1902 }
1903 | Identifier '.' '*'
1904 {
1905 $$.module_name = $1;
1906 $$.testcase_name = mcopystr("*");
1907 }
1908 ;
1909
1910 /****************** [EXTERNAL_COMMANDS] section **********************/
1911
1912 ExternalCommandsSection:
1913 ExternalCommandsKeyword ExternalCommandList
1914 ;
1915
1916 ExternalCommandList:
1917 /* empty */
1918 | ExternalCommandList ExternalCommand optSemiColon
1919 ;
1920
1921 ExternalCommand:
1922 BeginControlPart AssignmentChar Command
1923 {
1924 check_duplicate_option("EXTERNAL_COMMANDS", "BeginControlPart",
1925 begin_controlpart_command_set);
1926
1927 TTCN_Runtime::set_begin_controlpart_command($3);
1928
1929 Free($3);
1930 }
1931 | EndControlPart AssignmentChar Command
1932 {
1933 check_duplicate_option("EXTERNAL_COMMANDS", "EndControlPart",
1934 end_controlpart_command_set);
1935
1936 TTCN_Runtime::set_end_controlpart_command($3);
1937
1938 Free($3);
1939 }
1940 | BeginTestCase AssignmentChar Command
1941 {
1942 check_duplicate_option("EXTERNAL_COMMANDS", "BeginTestCase",
1943 begin_testcase_command_set);
1944
1945 TTCN_Runtime::set_begin_testcase_command($3);
1946
1947 Free($3);
1948 }
1949 | EndTestCase AssignmentChar Command
1950 {
1951 check_duplicate_option("EXTERNAL_COMMANDS", "EndTestCase",
1952 end_testcase_command_set);
1953
1954 TTCN_Runtime::set_end_testcase_command($3);
1955
1956 Free($3);
1957 }
1958 ;
1959
1960 Command:
1961 StringValue { $$ = $1; }
1962 ;
1963
1964 /***************** [GROUPS] section *******************/
1965
1966 GroupsSection:
1967 GroupsKeyword GroupList
1968 {
1969 check_ignored_section("GROUPS");
1970 }
1971 ;
1972
1973 GroupList:
1974 /* empty */
1975 | GroupList Group optSemiColon
1976 ;
1977
1978 Group:
1979 GroupName AssignmentChar GroupMembers
1980 ;
1981
1982 GroupName:
1983 Identifier { Free($1); }
1984 ;
1985
1986 GroupMembers:
1987 '*'
1988 | seqGroupMember
1989 ;
1990
1991 seqGroupMember:
1992 HostName
1993 | seqGroupMember ',' HostName
1994 ;
1995
1996 HostName:
1997 DNSName
1998 | Identifier { Free($1); }
1999 ;
2000
2001 /******************** [COMPONENTS] section *******************/
2002 ComponentsSection:
2003 ComponentsKeyword ComponentList
2004 {
2005 check_ignored_section("COMPONENTS");
2006 }
2007 ;
2008
2009 ComponentList:
2010 /* empty */
2011 | ComponentList ComponentItem optSemiColon
2012 ;
2013
2014 ComponentItem:
2015 ComponentName AssignmentChar ComponentLocation
2016 ;
2017
2018 ComponentName:
2019 Identifier { Free($1); }
2020 | '*'
2021 ;
2022
2023 ComponentLocation:
2024 Identifier { Free($1); }
2025 | DNSName
2026 ;
2027
2028 /****************** [MAIN_CONTROLLER] section *********************/
2029 MainControllerSection:
2030 MainControllerKeyword MCParameterList
2031 {
2032 check_ignored_section("MAIN_CONTROLLER");
2033 }
2034 ;
2035
2036 MCParameterList:
2037 /* empty */
2038 | MCParameterList MCParameter optSemiColon
2039 ;
2040
2041 MCParameter:
2042 LocalAddress AssignmentChar HostName { }
2043 | TCPPort AssignmentChar IntegerValue { delete $3; }
2044 | KillTimer AssignmentChar KillTimerValue { }
2045 | NumHCs AssignmentChar IntegerValue { delete $3; }
2046 | UnixSocketEnabled AssignmentChar YesToken {}
2047 | UnixSocketEnabled AssignmentChar NoToken {}
2048 | UnixSocketEnabled AssignmentChar HostName {}
2049 ;
2050
2051 KillTimerValue:
2052 FloatValue { }
2053 | IntegerValue { delete $1; }
2054 ;
2055
2056 /****************** [INCLUDE] section *********************/
2057 IncludeSection:
2058 IncludeKeyword IncludeFiles
2059 {
2060 if(!TTCN_Runtime::is_single())
2061 config_process_error
2062 ("Internal error: the Main Controller must not send section [INCLUDE]"
2063 " of the configuration file.");
2064 }
2065 ;
2066
2067 IncludeFiles:
2068 /* empty */
2069 | IncludeFiles IncludeFile
2070 ;
2071
2072 IncludeFile:
2073 Cstring { Free($1.chars_ptr); }
2074 ;
2075
2076 /****************** [DEFINE] section *********************/
2077 DefineSection:
2078 DefineKeyword
2079 {
2080 if(!TTCN_Runtime::is_single())
2081 config_process_error
2082 ("Internal error: the Main Controller must not send section [DEFINE]"
2083 " of the configuration file.");
2084 }
2085 ;
2086
2087 /*********************************************************/
2088
2089 ParamOpType:
2090 AssignmentChar
2091 {
2092 $$ = Module_Param::OT_ASSIGN;
2093 }
2094 |
2095 ConcatChar
2096 {
2097 $$ = Module_Param::OT_CONCAT;
2098 }
2099 ;
2100
2101 optSemiColon:
2102 /* empty */
2103 | ';'
2104 ;
2105
2106 %%
2107
2108 static void reset_configuration_options()
2109 {
2110 /* Section [MODULE_PARAMETERS */
2111 /** \todo reset module parameters to their default values */
2112 /* Section [LOGGING] */
2113 TTCN_Logger::close_file();
2114 TTCN_Logger::reset_configuration();
2115 file_name_set = FALSE;
2116 file_mask_set = TRUE;
2117 console_mask_set = TRUE;
2118 timestamp_format_set = FALSE;
2119 source_info_format_set = FALSE;
2120 append_file_set = FALSE;
2121 log_event_types_set = FALSE;
2122 log_entity_name_set = FALSE;
2123 /* Section [TESTPORT_PARAMETERS] */
2124 PORT::clear_parameters();
2125 /* Section [EXTERNAL_COMMANDS] */
2126
2127 TTCN_Runtime::clear_external_commands();
2128
2129 begin_controlpart_command_set = FALSE;
2130 end_controlpart_command_set = FALSE;
2131 begin_testcase_command_set = FALSE;
2132 end_testcase_command_set = FALSE;
2133 }
2134
2135 Module_Param* process_config_string2ttcn(const char* mp_str, bool is_component)
2136 {
2137 if (parsed_module_param!=NULL || parsing_error_messages!=NULL) TTCN_error("Internal error: previously parsed ttcn string was not cleared.");
2138 // add the hidden keyword
2139 std::string mp_string = (is_component) ? std::string("$#&&&(#TTCNSTRINGPARSING_COMPONENT$#&&^#% ") + mp_str
2140 : std::string("$#&&&(#TTCNSTRINGPARSING$#&&^#% ") + mp_str;
2141 struct yy_buffer_state *flex_buffer = config_process__scan_bytes(mp_string.c_str(), (int)mp_string.size());
2142 if (flex_buffer == NULL) TTCN_error("Internal error: flex buffer creation failed.");
2143 reset_config_process_lex(NULL);
2144 error_flag = FALSE;
2145 try {
2146 Ttcn_String_Parsing ttcn_string_parsing;
2147 if (config_process_parse()) error_flag = TRUE;
2148 } catch (const TC_Error& TC_error) {
2149 if (parsed_module_param!=NULL) { delete parsed_module_param; parsed_module_param = NULL; }
2150 error_flag = TRUE;
2151 }
2152 config_process_close();
2153 config_process_lex_destroy();
2154
2155 if (error_flag || parsing_error_messages!=NULL) {
2156 delete parsed_module_param;
2157 parsed_module_param = NULL;
2158 char* pem = parsing_error_messages!=NULL ? parsing_error_messages : mcopystr("Unknown parsing error");
2159 parsing_error_messages = NULL;
2160 TTCN_error_begin("%s", pem);
2161 Free(pem);
2162 TTCN_error_end();
2163 return NULL;
2164 } else {
2165 if (parsed_module_param==NULL) TTCN_error("Internal error: could not parse ttcn string.");
2166 Module_Param* ret_val = parsed_module_param;
2167 parsed_module_param = NULL;
2168 return ret_val;
2169 }
2170 }
2171
2172 Module_Param* process_config_debugger_value(const char* mp_str)
2173 {
2174 if (parsed_module_param != NULL || parsing_error_messages != NULL) {
2175 ttcn3_debugger.print(DRET_NOTIFICATION,
2176 "Internal error: previously parsed TTCN string was not cleared.");
2177 return NULL;
2178 }
2179 // add the hidden keyword
2180 std::string mp_string = std::string("$#&&&(#TTCNSTRINGPARSING$#&&^#% ") + mp_str;
2181 struct yy_buffer_state *flex_buffer = config_process__scan_bytes(mp_string.c_str(), (int)mp_string.size());
2182 if (flex_buffer == NULL) {
2183 ttcn3_debugger.print(DRET_NOTIFICATION, "Internal error: flex buffer creation failed.");
2184 return NULL;
2185 }
2186 reset_config_process_lex(NULL);
2187 error_flag = FALSE;
2188 try {
2189 Debugger_Value_Parsing debugger_value_parsing;
2190 if (config_process_parse()) {
2191 error_flag = TRUE;
2192 }
2193 }
2194 catch (const TC_Error& TC_error) {
2195 if (parsed_module_param != NULL) {
2196 delete parsed_module_param;
2197 parsed_module_param = NULL;
2198 }
2199 error_flag = TRUE;
2200 }
2201 config_process_close();
2202 config_process_lex_destroy();
2203
2204 if (error_flag || parsing_error_messages != NULL) {
2205 delete parsed_module_param;
2206 parsed_module_param = NULL;
2207 char* pem = parsing_error_messages != NULL ? parsing_error_messages :
2208 mcopystr("Unknown parsing error");
2209 parsing_error_messages = NULL;
2210 ttcn3_debugger.print(DRET_NOTIFICATION, "%s", pem);
2211 Free(pem);
2212 return NULL;
2213 }
2214 else {
2215 if (parsed_module_param == NULL) {
2216 ttcn3_debugger.print(DRET_NOTIFICATION, "Internal error: could not parse TTCN string.");
2217 return NULL;
2218 }
2219 Module_Param* ret_val = parsed_module_param;
2220 parsed_module_param = NULL;
2221 return ret_val;
2222 }
2223 }
2224
2225 boolean process_config_string(const char *config_string, int string_len)
2226 {
2227 error_flag = FALSE;
2228
2229 struct yy_buffer_state *flex_buffer =
2230 config_process__scan_bytes(config_string, string_len);
2231 if (flex_buffer == NULL) {
2232 TTCN_Logger::log_str(TTCN_Logger::ERROR_UNQUALIFIED,
2233 "Internal error: flex buffer creation failed.");
2234 return FALSE;
2235 }
2236
2237 try {
2238 reset_configuration_options();
2239 reset_config_process_lex(NULL);
2240
2241 if (config_process_parse()) error_flag = TRUE;
2242
2243 } catch (const TC_Error& TC_error) {
2244 error_flag = TRUE;
2245 }
2246
2247 config_process_close();
2248 config_process_lex_destroy();
2249
2250 return !error_flag;
2251 }
2252
2253
2254 boolean process_config_file(const char *file_name)
2255 {
2256 error_flag = FALSE;
2257 string_chain_t *filenames=NULL;
2258
2259 reset_configuration_options();
2260
2261 if(preproc_parse_file(file_name, &filenames, &config_defines))
2262 error_flag=TRUE;
2263
2264 while(filenames) {
2265 char *fn=string_chain_cut(&filenames);
2266 reset_config_process_lex(fn);
2267 /* The lexer can modify config_process_in
2268 * when it's input buffer is changed */
2269 config_process_in = fopen(fn, "r");
2270 FILE* tmp_cfg = config_process_in;
2271 if (config_process_in != NULL) {
2272 try {
2273 if(config_process_parse()) error_flag=TRUE;
2274 } catch (const TC_Error& TC_error) {
2275 error_flag=TRUE;
2276 }
2277 fclose(tmp_cfg);
2278 config_process_close();
2279 config_process_lex_destroy();
2280 } else {
2281 TTCN_Logger::begin_event(TTCN_Logger::ERROR_UNQUALIFIED);
2282 TTCN_Logger::log_event("Cannot open configuration file: %s", fn);
2283 TTCN_Logger::OS_error();
2284 TTCN_Logger::end_event();
2285 error_flag=TRUE;
2286 }
2287 /* During parsing flex or libc may use some system calls (e.g. ioctl)
2288 * that fail with an error status. Such error codes shall be ignored in
2289 * future error messages. */
2290 errno = 0;
2291
2292 Free(fn);
2293 }
2294
2295 string_map_free(config_defines);
2296 config_defines = NULL;
2297
2298 return !error_flag;
2299 }
2300
2301 void config_process_error_f(const char *error_str, ...)
2302 {
2303 if (Ttcn_String_Parsing::happening() || Debugger_Value_Parsing::happening()) {
2304 va_list p_var;
2305 va_start(p_var, error_str);
2306 char* error_msg_str = mprintf_va_list(error_str, p_var);
2307 va_end(p_var);
2308 if (parsing_error_messages!=NULL) parsing_error_messages = mputc(parsing_error_messages, '\n');
2309 if (Debugger_Value_Parsing::happening()) {
2310 parsing_error_messages = mputprintf(parsing_error_messages,
2311 "Parse error at or before token `%s': %s", config_process_text, error_msg_str);
2312 }
2313 else { // Ttcn_String_Parsing::happening()
2314 parsing_error_messages = mputprintf(parsing_error_messages,
2315 "Parse error in line %d, at or before token `%s': %s", config_process_get_current_line(), config_process_text, error_msg_str);
2316 }
2317 Free(error_msg_str);
2318 error_flag = TRUE;
2319 return;
2320 }
2321 TTCN_Logger::begin_event(TTCN_Logger::ERROR_UNQUALIFIED);
2322 if (!get_cfg_process_current_file().empty()) {
2323 TTCN_Logger::log_event("Parse error in configuration file `%s': in line %d, "
2324 "at or before token `%s': ",
2325 get_cfg_process_current_file().c_str(), config_process_get_current_line(),
2326 config_process_text
2327 );
2328 } else {
2329 TTCN_Logger::log_event("Parse error while reading configuration "
2330 "information: in line %d, at or before token `%s': ",
2331 config_process_get_current_line(), config_process_text);
2332 }
2333 va_list pvar;
2334 va_start(pvar, error_str);
2335 TTCN_Logger::log_event_va_list(error_str, pvar);
2336 va_end(pvar);
2337 TTCN_Logger::end_event();
2338 error_flag = TRUE;
2339 }
2340
2341 void config_process_error(const char *error_str)
2342 {
2343 config_process_error_f("%s", error_str);
2344 }
2345
2346 void config_preproc_error(const char *error_str, ...)
2347 {
2348 TTCN_Logger::begin_event(TTCN_Logger::ERROR_UNQUALIFIED);
2349 TTCN_Logger::log_event("Parse error while pre-processing configuration"
2350 " file `%s': in line %d: ",
2351 get_cfg_preproc_current_file().c_str(),
2352 config_preproc_yylineno);
2353 va_list pvar;
2354 va_start(pvar, error_str);
2355 TTCN_Logger::log_event_va_list(error_str, pvar);
2356 va_end(pvar);
2357 TTCN_Logger::end_event();
2358 error_flag = TRUE;
2359 }
2360
2361 void path_error(const char *fmt, ...)
2362 {
2363 va_list parameters;
2364 fprintf(stderr, "File error: ");
2365 va_start(parameters, fmt);
2366 vfprintf(stderr, fmt, parameters);
2367 va_end(parameters);
2368 fprintf(stderr, "\n");
2369 }
2370
2371 static void check_duplicate_option(const char *section_name,
2372 const char *option_name, boolean& option_flag)
2373 {
2374 if (option_flag) {
2375 TTCN_warning("Option `%s' was given more than once in section [%s] of the "
2376 "configuration file.", option_name, section_name);
2377 } else option_flag = TRUE;
2378 }
2379
2380 static void check_ignored_section(const char *section_name)
2381 {
2382 if (TTCN_Runtime::is_single()) TTCN_warning("Section [%s] of "
2383 "configuration file is ignored in single mode.", section_name);
2384 else config_process_error_f("Internal error: the Main Controller must not "
2385 "send section [%s] of the configuration file.", section_name);
2386 }
2387
2388 static void set_param(Module_Param& param)
2389 {
2390 try {
2391 Module_List::set_param(param);
2392 }
2393 catch (const TC_Error& TC_error) {
2394 error_flag = TRUE;
2395 }
2396 }
2397
2398 unsigned char char_to_hexdigit_(char c)
2399 {
2400 if (c >= '0' && c <= '9') return c - '0';
2401 else if (c >= 'A' && c <= 'F') return c - 'A' + 10;
2402 else if (c >= 'a' && c <= 'f') return c - 'a' + 10;
2403 else {
2404 config_process_error_f("char_to_hexdigit_(): invalid argument: %c", c);
2405 return 0; // to avoid warning
2406 }
2407 }
This page took 0.078355 seconds and 5 git commands to generate.