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
21 * Szabo, Janos Zoltan – initial implementation
23 * Zalanyi, Balazs Andor
25 ******************************************************************************/
35 #include <openssl/bn.h>
37 #include "../common/config_preproc.h"
39 #include "Param_Types.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"
51 #include "Module_list.hh"
55 #include "LoggingBits.hh"
56 #include "LoggingParam.hh"
58 #include "Profiler.hh"
59 #include "Debugger.hh"
60 #include "DebugCommands.hh"
62 #define YYERROR_VERBOSE
64 #include "config_process.lex.hh"
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();
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);
78 static boolean error_flag = FALSE;
80 static Module_Param* parsed_module_param = NULL;
81 static char * parsing_error_messages = NULL;
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.
89 static boolean file_name_set = FALSE,
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;
108 int execute_list_len = 0;
109 execute_list_item *execute_list = NULL;
111 string_map_t *config_defines;
119 unsigned int uint_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;
146 logging_plugin_t *logging_plugins;
147 logging_param_t logging_params;
148 logging_setting_t logging_param_line;
151 const char **elements;
155 %token ModuleParametersKeyword
156 %token LoggingKeyword
157 %token ProfilerKeyword
158 %token TestportParametersKeyword
159 %token ExecuteKeyword
160 %token ExternalCommandsKeyword
162 %token ComponentsKeyword
163 %token MainControllerKeyword
164 %token IncludeKeyword
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"
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
197 %token TimestampFormat
198 %token ConsoleTimestampFormat
199 %token SourceInfoFormat "LogSourceInfo or SourceInfoFormat"
203 %token BeginControlPart
204 %token EndControlPart
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"
223 %token <logseverity_val> LoggingBit
224 /* a collection of bits */
225 %token <logseverity_val> LoggingBitCollection
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"
235 %token UnixSocketEnabled
236 %token YesToken "yes"
240 %token DiskFullAction
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"
260 %type <int_val> IntegerValue
261 %type <float_val> FloatValue
262 %type <objid_val> ObjIdValue ObjIdComponentList
263 %type <int_val> ObjIdComponent NumberForm NameAndNumberForm
265 %type <universal_charstring_val> UniversalCharstringValue UniversalCharstringFragment
266 %type <universal_char_val> Quadruple
267 %type <uid_list> USI UIDlike
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
287 %type <execute_item_val> ExecuteItem
289 %type <bitstring_val> BitstringValue
290 %type <hexstring_val> HexstringValue
291 %type <octetstring_val> OctetstringValue
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
305 %destructor { Free($$); }
314 TestportParameterName
315 TestportParameterValue
321 %destructor { Free($$.components_ptr); }
325 %destructor { Free($$.bits_ptr); }
329 %destructor { Free($$.nibbles_ptr); }
333 %destructor { Free($$.octets_ptr); }
337 %destructor { Free($$.chars_ptr); }
341 %destructor { Free($$.uchars_ptr); }
342 UniversalCharstringFragment
343 UniversalCharstringValue
345 %destructor { if ($$.id_selector == COMPONENT_ID_NAME) Free($$.id_name); }
348 %destructor { Free($$.module_name); Free($$.testcase_name); }
351 %destructor { delete $$; }
360 ParameterValueOrNotUsedSymbol
374 %destructor { delete $$; }
377 %destructor { for(size_t i=0; i<$$->size(); i++) { delete $$->at(i); } delete $$; }
380 %destructor { for(size_t i=0; i<$$->size(); i++) { Free($$->at(i)); } delete $$; }
384 %left '&' /* to avoid shift/reduce conflicts */
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).
402 if (Ttcn_String_Parsing::happening() || Debugger_Value_Parsing::happening()) {
403 config_process_error("Config file cannot be parsed as ttcn string");
406 | TtcnStringParsingKeyword ParameterValue
408 parsed_module_param = $2;
418 ModuleParametersSection
421 | TestportParametersSection
423 | ExternalCommandsSection
426 | MainControllerSection
431 ModuleParametersSection:
432 ModuleParametersKeyword ModuleParameters
437 | ModuleParameters ModuleParameter optSemiColon
441 ParameterName ParamOpType ParameterValue
443 Module_Param* mp = $3;
444 mp->set_id(new Module_Param_Name(*$1));
445 mp->set_operation_type($2);
453 ParameterNameSegment { $$ = $1; }
454 | '*' '.' ParameterNameSegment { $$ = $3; }
457 ParameterNameSegment:
458 ParameterNameSegment '.' Identifier
463 | ParameterNameSegment IndexItemIndex
466 $$->push_back(mprintf("%d", $2));
470 $$ = new Vector<char*>();
480 | ParameterExpression LengthMatch
483 $$->set_length_restriction($2);
485 | ParameterExpression IfpresentKeyword
490 | ParameterExpression LengthMatch IfpresentKeyword
493 $$->set_length_restriction($2);
499 LengthKeyword '(' LengthBound ')'
501 $$ = new Module_Param_Length_Restriction();
502 $$->set_single((size_t)$3);
504 | LengthKeyword '(' LengthBound DotDot LengthBound ')'
507 config_process_error("invalid length restriction: lower bound > upper bound");
509 $$ = new Module_Param_Length_Restriction();
510 $$->set_min((size_t)$3);
511 $$->set_max((size_t)$5);
513 | LengthKeyword '(' LengthBound DotDot InfinityKeyword ')'
515 $$ = new Module_Param_Length_Restriction();
516 $$->set_min((size_t)$3);
523 $1->set_id(new Module_Param_CustomName(mcopystr("length bound")));
526 if (!tmp.get_val().is_native()) {
527 config_process_error("bignum length restriction bound.");
529 } else if (tmp.get_val().is_negative()) {
530 config_process_error("negative length restriction bound.");
539 // one global rule for expressions in module parameters
540 // the expression's result will be calculated by set_param()
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
549 $$ = new Module_Param_Expression(Module_Param::EXPR_ADD, $1, $3);
551 | ParameterExpression '-' ParameterExpression
553 $$ = new Module_Param_Expression(Module_Param::EXPR_SUBTRACT, $1, $3);
555 | ParameterExpression '*' ParameterExpression
557 $$ = new Module_Param_Expression(Module_Param::EXPR_MULTIPLY, $1, $3);
559 | ParameterExpression '/' ParameterExpression
561 $$ = new Module_Param_Expression(Module_Param::EXPR_DIVIDE, $1, $3);
563 | ParameterExpression '&' ParameterExpression
565 $$ = new Module_Param_Expression(Module_Param::EXPR_CONCATENATE, $1, $3);
570 // enumerated values are also treated as references by the parser,
571 // these will be sorted out later during set_param()
574 $$ = new Module_Param_Reference(new Module_Param_Name(*$1));
578 SimpleParameterValue:
581 $$ = new Module_Param_Integer($1);
585 $$ = new Module_Param_Float($1);
589 $$ = new Module_Param_Boolean($1);
593 $$ = new Module_Param_Objid($1.n_components, $1.components_ptr);
597 $$ = new Module_Param_Verdict($1);
601 $$ = new Module_Param_Bitstring($1.n_bits, $1.bits_ptr);
605 $$ = new Module_Param_Hexstring($1.n_nibbles, $1.nibbles_ptr);
609 $$ = new Module_Param_Octetstring($1.n_octets, $1.octets_ptr);
613 $$ = new Module_Param_Charstring($1.n_chars, $1.chars_ptr);
615 | UniversalCharstringValue
617 $$ = new Module_Param_Universal_Charstring($1.n_uchars, $1.uchars_ptr);
621 $$ = new Module_Param_Omit();
625 $$ = new Module_Param_Asn_Null();
629 $$ = new Module_Param_Ttcn_Null();
633 $$ = new Module_Param_Ttcn_mtc();
637 $$ = new Module_Param_Ttcn_system();
641 $$ = new Module_Param_Any();
645 $$ = new Module_Param_AnyOrNone();
659 | PatternKeyword PatternChunk
661 $$ = new Module_Param_Pattern($2);
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++) {
684 config_process_error_f("Invalid char (%c) in bitstring template", $1[i]);
688 $$ = new Module_Param_Bitstring_Template(n_chars, chars_ptr);
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]);
700 $$ = new Module_Param_Hexstring_Template(n_chars, chars_ptr);
704 Vector<unsigned short> octet_vec;
705 int str_len = (int)mstrlen($1);
706 for (int i=0; i<str_len; i++) {
708 if ($1[i]=='?') num = 256;
709 else if ($1[i]=='*') num = 257;
712 num = 16 * char_to_hexdigit_($1[i]);
714 if (i>=str_len) config_process_error("Unexpected end of octetstring pattern");
716 num += char_to_hexdigit_($1[i]);
718 octet_vec.push_back(num);
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);
735 $$ = mcopystr($1.chars_ptr);
740 $$ = mprintf("\\q{%d,%d,%d,%d}", $1.uc_group, $1.uc_plane, $1.uc_row, $1.uc_cell);
745 '(' '-' InfinityKeyword DotDot MPNumber ')'
747 $$ = new Module_Param_IntRange(NULL, $5);
749 | '(' MPNumber DotDot MPNumber ')'
751 $$ = new Module_Param_IntRange($2, $4);
753 | '(' MPNumber DotDot InfinityKeyword ')'
755 $$ = new Module_Param_IntRange($2, NULL);
760 '(' '-' InfinityKeyword DotDot MPFloat ')'
762 $$ = new Module_Param_FloatRange(0.0, false, $5, true);
764 | '(' MPFloat DotDot MPFloat ')'
766 $$ = new Module_Param_FloatRange($2, true, $4, true);
768 | '(' MPFloat DotDot InfinityKeyword ')'
770 $$ = new Module_Param_FloatRange($2, true, 0.0, false);
775 '(' UniversalCharstringFragment DotDot UniversalCharstringFragment ')'
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");
784 lower = *($2.uchars_ptr);
785 upper = *($4.uchars_ptr);
787 config_process_error("Lower bound is larger than upper bound in the char range");
793 $$ = new Module_Param_StringRange(lower, upper);
797 // integers outside of the [MODULE_PARAMETERS] section
800 | '(' IntegerValue ')' { $$ = $2; }
801 | '+' IntegerValue %prec UnarySign { $$ = $2; }
802 | '-' IntegerValue %prec UnarySign
806 $$ = new int_val_t((-op1).get_val());
809 | IntegerValue '+' IntegerValue
814 $$ = new int_val_t((op1 + op2).get_val());
818 | IntegerValue '-' IntegerValue
823 $$ = new int_val_t((op1 - op2).get_val());
827 | IntegerValue '*' IntegerValue
832 $$ = new int_val_t((op1 * op2).get_val());
836 | IntegerValue '/' IntegerValue
839 config_process_error("Integer division by zero.");
840 $$ = new int_val_t((RInt)0);
847 $$ = new int_val_t((op1 / op2).get_val());
854 // floats outside of the [MODULE_PARAMETERS] section
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
866 config_process_error("Floating point division by zero.");
873 ObjIdKeyword '{' ObjIdComponentList '}' { $$ = $3; }
880 $$.components_ptr = (int *)Malloc(sizeof(int));
881 $$.components_ptr[0] = $1->get_val();
884 | ObjIdComponentList ObjIdComponent
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();
895 NumberForm { $$ = $1; }
896 | NameAndNumberForm { $$ = $1; }
900 MPNumber { $$ = $1; }
904 Identifier '(' MPNumber ')'
923 UniversalCharstringValue:
927 $$.uchars_ptr = (universal_char*)Malloc(sizeof(universal_char));
928 $$.uchars_ptr[0] = $1;
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 '+'
939 unsigned long int_val = strtoul($1.elements[i] + offset, &p, 16);
941 //Error, should not happen
942 config_process_error_f("Invalid hexadecimal string %s.", $1.elements[i] + offset);
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;
951 Free((char*)$1.elements[i]);
957 UniversalCharstringFragment:
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];
974 $$.uchars_ptr = (universal_char*)Malloc(sizeof(universal_char));
975 $$.uchars_ptr[0] = $1;
980 CharKeyword '(' ParameterExpression ',' ParameterExpression ','
981 ParameterExpression ',' ParameterExpression ')'
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")));
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);
997 $$.uc_group = g < 0 ? 0 : 127;
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);
1006 $$.uc_plane = p < 0 ? 0 : 255;
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);
1015 $$.uc_row = r < 0 ? 0 : 255;
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);
1024 $$.uc_cell = c < 0 ? 0 : 255;
1036 CharKeyword '(' UIDlike ')'
1046 $$.elements = (const char**)
1047 Malloc($$.nElements * sizeof(*$$.elements));
1048 $$.elements[$$.nElements-1] = $1;
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;
1058 // character strings outside of the [MODULE_PARAMETERS] section
1062 $$ = mcopystr($1.chars_ptr);
1065 | StringValue '&' Cstring
1067 $$ = mputstr($1, $3.chars_ptr);
1075 $$ = new Module_Param_Value_List();
1077 | '{' FieldValueList '}'
1081 | '{' ArrayItemList '}'
1085 | '{' IndexItemList '}'
1089 | '(' ParameterValue ',' TemplateItemList ')' /* at least 2 elements to avoid shift/reduce conflicts with the ParameterExpression rule */
1091 $$ = new Module_Param_List_Template();
1092 $2->set_id(new Module_Param_Index($$->get_size(),false));
1094 $$->add_list_with_implicit_ids($4);
1097 | ComplementKeyword '(' TemplateItemList ')'
1099 $$ = new Module_Param_ComplementList_Template();
1100 $$->add_list_with_implicit_ids($3);
1103 | SupersetKeyword '(' TemplateItemList ')'
1105 $$ = new Module_Param_Superset_Template();
1106 $$->add_list_with_implicit_ids($3);
1109 | SubsetKeyword '(' TemplateItemList ')'
1111 $$ = new Module_Param_Subset_Template();
1112 $$->add_list_with_implicit_ids($3);
1117 ParameterValueOrNotUsedSymbol:
1124 $$ = new Module_Param_NotUsed();
1131 $$ = new Vector<Module_Param*>();
1134 | TemplateItemList ',' ParameterValue
1144 $$ = new Module_Param_Assignment_List();
1147 | FieldValueList ',' FieldValue
1155 FieldName AssignmentChar ParameterValueOrNotUsedSymbol
1158 $$->set_id(new Module_Param_FieldName($1));
1167 | ASN1LowerIdentifier
1176 $$ = new Module_Param_Value_List();
1177 $1->set_id(new Module_Param_Index($$->get_size(),false));
1180 | ArrayItemList ',' ArrayItem
1183 $3->set_id(new Module_Param_Index($$->get_size(),false));
1189 ParameterValueOrNotUsedSymbol
1193 | PermutationKeyword '(' TemplateItemList ')'
1195 $$ = new Module_Param_Permutation_Template();
1196 $$->add_list_with_implicit_ids($3);
1204 $$ = new Module_Param_Indexed_List();
1207 | IndexItemList ',' IndexItem
1215 IndexItemIndex AssignmentChar ParameterValue
1218 $$->set_id(new Module_Param_Index((size_t)$1,true));
1223 '[' ParameterExpression ']'
1225 $2->set_id(new Module_Param_CustomName(mcopystr("array index")));
1228 if (!tmp.get_val().is_native()) {
1229 config_process_error("bignum index."); // todo
1231 if (tmp.get_val().is_negative()) {
1232 config_process_error("negative index."); // todo
1239 /*************** [LOGGING] section *********************************/
1242 LoggingKeyword LoggingParamList
1247 | LoggingParamList LoggingParamLines optSemiColon
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) {
1253 check_duplicate_option("LOGGING", "FileMask", file_mask_set);
1255 case LP_CONSOLEMASK:
1256 check_duplicate_option("LOGGING", "ConsoleMask", console_mask_set);
1258 case LP_LOGFILESIZE:
1259 check_duplicate_option("LOGGING", "LogFileSize", log_file_size_set);
1261 case LP_LOGFILENUMBER:
1262 check_duplicate_option("LOGGING", "LogFileNumber", log_file_number_set);
1264 case LP_DISKFULLACTION:
1265 check_duplicate_option("LOGGING", "DiskFullAction", log_disk_full_action_set);
1268 check_duplicate_option("LOGGING", "LogFile", file_name_set);
1270 case LP_TIMESTAMPFORMAT:
1271 check_duplicate_option("LOGGING", "TimeStampFormat", timestamp_format_set);
1273 case LP_SOURCEINFOFORMAT:
1274 check_duplicate_option("LOGGING", "SourceInfoFormat", source_info_format_set);
1277 check_duplicate_option("LOGGING", "AppendFile", append_file_set);
1279 case LP_LOGEVENTTYPES:
1280 check_duplicate_option("LOGGING", "LogEventTypes", log_event_types_set);
1282 case LP_LOGENTITYNAME:
1283 check_duplicate_option("LOGGING", "LogEntityName", log_entity_name_set);
1285 case LP_MATCHINGHINTS:
1286 check_duplicate_option("LOGGING", "MatchingVerbosity", matching_verbosity_set);
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);
1302 $$.component.id_selector = COMPONENT_ID_ALL;
1303 $$.component.id_name = NULL;
1304 $$.plugin_id = NULL;
1307 | ComponentId '.' LoggingParam
1310 $$.plugin_id = NULL;
1313 | ComponentId '.' LoggerPluginId '.' LoggingParam
1319 | LoggerPlugins AssignmentChar '{' LoggerPluginList '}'
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;
1335 $$.logparam.log_param_selection = LP_UNKNOWN;
1337 | ComponentId '.' LoggerPlugins AssignmentChar '{' LoggerPluginList '}'
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;
1347 // Component names shall be duplicated in `register_plugin()'.
1348 if ($1.id_selector == COMPONENT_ID_NAME)
1350 $$.logparam.log_param_selection = LP_UNKNOWN;
1359 | LoggerPluginList ',' LoggerPlugin
1369 $$ = (logging_plugin_t *)Malloc(sizeof(logging_plugin_t));
1370 $$->identifier = $1;
1371 $$->filename = NULL;
1374 | Identifier AssignmentChar StringValue
1376 $$ = (logging_plugin_t *)Malloc(sizeof(logging_plugin_t));
1377 $$->identifier = $1;
1384 '*' { $$ = mcopystr("*"); }
1385 | Identifier { $$ = $1; }
1389 FileMask AssignmentChar LoggingBitmask
1391 $$.log_param_selection = LP_FILEMASK;
1392 $$.logoptions_val = $3;
1394 | ConsoleMask AssignmentChar LoggingBitmask
1396 $$.log_param_selection = LP_CONSOLEMASK;
1397 $$.logoptions_val = $3;
1399 | LogFileSize AssignmentChar Number
1401 $$.log_param_selection = LP_LOGFILESIZE;
1402 $$.int_val = (int)$3->get_val();
1405 | EmergencyLogging AssignmentChar Number
1407 $$.log_param_selection = LP_EMERGENCY;
1408 $$.int_val = (int)$3->get_val();
1411 | EmergencyLoggingBehaviour AssignmentChar EmergencyLoggingBehaviourValue
1413 $$.log_param_selection = LP_EMERGENCYBEHAVIOR;
1414 $$.emergency_logging_behaviour_value = $3;
1416 | EmergencyLoggingMask AssignmentChar LoggingBitmask
1418 $$.log_param_selection = LP_EMERGENCYMASK;
1419 $$.logoptions_val = $3;
1421 | EmergencyLoggingForFailVerdict AssignmentChar YesNoOrBoolean
1423 $$.log_param_selection = LP_EMERGENCYFORFAIL;
1426 | LogFileNumber AssignmentChar Number
1428 $$.log_param_selection = LP_LOGFILENUMBER;
1429 $$.int_val = (int)$3->get_val();
1432 | DiskFullAction AssignmentChar DiskFullActionValue
1434 $$.log_param_selection = LP_DISKFULLACTION;
1435 $$.disk_full_action_value = $3;
1437 | LogFile AssignmentChar LogFileName
1439 $$.log_param_selection = LP_LOGFILE;
1442 | TimestampFormat AssignmentChar TimestampValue
1444 $$.log_param_selection = LP_TIMESTAMPFORMAT;
1445 $$.timestamp_value = $3;
1447 | ConsoleTimestampFormat AssignmentChar TimestampValue
1449 $$.log_param_selection = LP_UNKNOWN;
1451 | SourceInfoFormat AssignmentChar SourceInfoSetting
1453 $$.log_param_selection = LP_SOURCEINFOFORMAT;
1454 $$.source_info_value = $3;
1456 | AppendFile AssignmentChar YesNoOrBoolean
1458 $$.log_param_selection = LP_APPENDFILE;
1461 | LogEventTypes AssignmentChar LogEventTypesValue
1463 $$.log_param_selection = LP_LOGEVENTTYPES;
1464 $$.log_event_types_value = $3;
1466 | LogEntityName AssignmentChar YesNoOrBoolean
1468 $$.log_param_selection = LP_LOGENTITYNAME;
1471 | MatchingHints AssignmentChar VerbosityValue
1473 $$.log_param_selection = LP_MATCHINGHINTS;
1474 $$.matching_verbosity_value = $3;
1476 | Identifier AssignmentChar StringValue
1478 $$.log_param_selection = LP_PLUGIN_SPECIFIC;
1485 Compact { $$ = TTCN_Logger::VERBOSITY_COMPACT; }
1486 | Detailed { $$ = TTCN_Logger::VERBOSITY_FULL; }
1489 DiskFullActionValue:
1490 Error { $$.type = TTCN_Logger::DISKFULL_ERROR; }
1491 | Stop { $$.type = TTCN_Logger::DISKFULL_STOP; }
1494 $$.type = TTCN_Logger::DISKFULL_RETRY;
1495 $$.retry_interval = 30; /* default retry interval */
1497 | Retry '(' Number ')'
1499 $$.type = TTCN_Logger::DISKFULL_RETRY;
1500 $$.retry_interval = (size_t)$3->get_val();
1503 | Delete { $$.type = TTCN_Logger::DISKFULL_DELETE; }
1507 StringValue { $$ = $1; }
1510 LoggingBitOrCollection:
1516 | LoggingBitCollection
1521 case TTCN_Logger::ACTION_UNQUALIFIED:
1522 $$.add_sev(TTCN_Logger::ACTION_UNQUALIFIED);
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);
1530 case TTCN_Logger::ERROR_UNQUALIFIED:
1531 $$.add_sev(TTCN_Logger::ERROR_UNQUALIFIED);
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);
1541 case TTCN_Logger::FUNCTION_UNQUALIFIED:
1542 $$.add_sev(TTCN_Logger::FUNCTION_RND);
1543 $$.add_sev(TTCN_Logger::FUNCTION_UNQUALIFIED);
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);
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);
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);
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);
1580 case TTCN_Logger::USER_UNQUALIFIED:
1581 $$.add_sev(TTCN_Logger::USER_UNQUALIFIED);
1583 case TTCN_Logger::STATISTICS_UNQUALIFIED:
1584 $$.add_sev(TTCN_Logger::STATISTICS_VERDICT);
1585 $$.add_sev(TTCN_Logger::STATISTICS_UNQUALIFIED);
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);
1593 case TTCN_Logger::WARNING_UNQUALIFIED:
1594 $$.add_sev(TTCN_Logger::WARNING_UNQUALIFIED);
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);
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);
1617 case TTCN_Logger::LOG_ALL_IMPORTANT:
1618 $$ = Logging_Bits::log_all;
1621 /* The lexer sent something the parser doesn't understand!
1622 Parser needs to be updated.
1624 TTCN_Logger::log_str(TTCN_Logger::ERROR_UNQUALIFIED,
1625 "Internal error: unknown logbit from lexer.");
1632 LoggingBitOrCollection
1636 | LoggingBitmask '|' LoggingBitOrCollection
1644 SourceInfoValue { $$ = $1; }
1647 $$ = $1 ? TTCN_Logger::SINFO_SINGLE : TTCN_Logger::SINFO_NONE;
1653 | BooleanValue { $$ = $1; }
1657 YesNoOrBoolean { $$ = $1 ? TTCN_Logger::LOGEVENTTYPES_YES :
1658 TTCN_Logger::LOGEVENTTYPES_NO; }
1659 | SubCategories { $$ = TTCN_Logger::LOGEVENTTYPES_SUBCATEGORIES; }
1660 | Detailed { $$ = TTCN_Logger::LOGEVENTTYPES_SUBCATEGORIES; }
1663 /*********************** [PROFILER] ********************************/
1666 ProfilerKeyword ProfilerSettings
1671 | ProfilerSettings ProfilerSetting optSemiColon
1675 DisableProfilerSetting
1676 | DisableCoverageSetting
1677 | DatabaseFileSetting
1678 | AggregateDataSetting
1679 | StatisticsFileSetting
1680 | DisableStatisticsSetting
1681 | StatisticsFilterSetting
1682 | StartAutomaticallySetting
1683 | NetLineTimesSetting
1684 | NetFunctionTimesSetting
1687 DisableProfilerSetting:
1688 DisableProfilerKeyword AssignmentChar BooleanValue {
1689 ttcn3_prof.set_disable_profiler($3);
1693 DisableCoverageSetting:
1694 DisableCoverageKeyword AssignmentChar BooleanValue {
1695 ttcn3_prof.set_disable_coverage($3);
1699 DatabaseFileSetting:
1700 DatabaseFileKeyword AssignmentChar StringValue {
1701 ttcn3_prof.set_database_filename($3);
1705 AggregateDataSetting:
1706 AggregateDataKeyword AssignmentChar BooleanValue {
1707 ttcn3_prof.set_aggregate_data($3);
1711 StatisticsFileSetting:
1712 StatisticsFileKeyword AssignmentChar StringValue {
1713 ttcn3_prof.set_stats_filename($3);
1717 DisableStatisticsSetting:
1718 DisableStatisticsKeyword AssignmentChar BooleanValue {
1719 ttcn3_prof.set_disable_stats($3);
1723 StatisticsFilterSetting:
1724 StatisticsFilterKeyword AssignmentChar ProfilerStatsFlags {
1725 ttcn3_prof.reset_stats_flags();
1726 ttcn3_prof.add_stats_flags($3);
1728 | StatisticsFilterKeyword ConcatChar ProfilerStatsFlags {
1729 ttcn3_prof.add_stats_flags($3);
1734 ProfilerStatsFlag { $$ = $1; }
1735 | ProfilerStatsFlag '&' ProfilerStatsFlags { $$ = $1 | $3; }
1736 | ProfilerStatsFlag '|' ProfilerStatsFlags { $$ = $1 | $3; }
1739 StartAutomaticallySetting:
1740 StartAutomaticallyKeyword AssignmentChar BooleanValue {
1750 NetLineTimesSetting:
1751 NetLineTimesKeyword AssignmentChar BooleanValue {
1752 TTCN3_Stack_Depth::set_net_line_times($3);
1756 NetFunctionTimesSetting:
1757 NetFunctionTimesKeyword AssignmentChar BooleanValue {
1758 TTCN3_Stack_Depth::set_net_func_times($3);
1763 /**************** [TESTPORT_PARAMETERS] ****************************/
1765 TestportParametersSection:
1766 TestportParametersKeyword TestportParameterList
1769 TestportParameterList:
1771 | TestportParameterList TestportParameter optSemiColon
1775 ComponentId '.' TestportName '.' TestportParameterName AssignmentChar
1776 TestportParameterValue
1778 PORT::add_parameter($1, $3, $5, $7);
1779 if ($1.id_selector == COMPONENT_ID_NAME) Free($1.id_name);
1789 $$.id_selector = COMPONENT_ID_NAME;
1794 $$.id_selector = COMPONENT_ID_NAME;
1795 $$.id_name = $1.chars_ptr;
1799 $$.id_selector = COMPONENT_ID_COMPREF;
1800 $$.id_compref = (component)$1->get_val();
1805 $$.id_selector = COMPONENT_ID_COMPREF;
1806 $$.id_compref = MTC_COMPREF;
1810 $$.id_selector = COMPONENT_ID_ALL;
1815 $$.id_selector = COMPONENT_ID_SYSTEM;
1821 Identifier { $$ = $1; }
1822 | Identifier ArrayRef
1824 $$ = mputstr($1, $2);
1827 | '*' { $$ = NULL; }
1831 '[' IntegerValue ']'
1833 char *s = $2->as_string();
1835 $$ = mputc ($$, '[');
1836 $$ = mputstr($$, s);
1837 $$ = mputc ($$, ']');
1841 | ArrayRef '[' IntegerValue ']'
1843 char *s = $3->as_string();
1844 $$ = mputc ($1, '[');
1845 $$ = mputstr($$, s);
1846 $$ = mputc ($$, ']');
1852 TestportParameterName:
1853 Identifier { $$ = $1; }
1856 TestportParameterValue:
1857 StringValue { $$ = $1; }
1860 /****************** [EXECUTE] section *************/
1863 ExecuteKeyword ExecuteList
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.");
1873 | ExecuteList ExecuteItem optSemiColon
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;
1881 Free($2.module_name);
1882 Free($2.testcase_name);
1890 $$.module_name = $1;
1891 $$.testcase_name = NULL;
1893 | Identifier '.' ControlKeyword
1895 $$.module_name = $1;
1896 $$.testcase_name = NULL;
1898 | Identifier '.' Identifier
1900 $$.module_name = $1;
1901 $$.testcase_name = $3;
1903 | Identifier '.' '*'
1905 $$.module_name = $1;
1906 $$.testcase_name = mcopystr("*");
1910 /****************** [EXTERNAL_COMMANDS] section **********************/
1912 ExternalCommandsSection:
1913 ExternalCommandsKeyword ExternalCommandList
1916 ExternalCommandList:
1918 | ExternalCommandList ExternalCommand optSemiColon
1922 BeginControlPart AssignmentChar Command
1924 check_duplicate_option("EXTERNAL_COMMANDS", "BeginControlPart",
1925 begin_controlpart_command_set);
1927 TTCN_Runtime::set_begin_controlpart_command($3);
1931 | EndControlPart AssignmentChar Command
1933 check_duplicate_option("EXTERNAL_COMMANDS", "EndControlPart",
1934 end_controlpart_command_set);
1936 TTCN_Runtime::set_end_controlpart_command($3);
1940 | BeginTestCase AssignmentChar Command
1942 check_duplicate_option("EXTERNAL_COMMANDS", "BeginTestCase",
1943 begin_testcase_command_set);
1945 TTCN_Runtime::set_begin_testcase_command($3);
1949 | EndTestCase AssignmentChar Command
1951 check_duplicate_option("EXTERNAL_COMMANDS", "EndTestCase",
1952 end_testcase_command_set);
1954 TTCN_Runtime::set_end_testcase_command($3);
1961 StringValue { $$ = $1; }
1964 /***************** [GROUPS] section *******************/
1967 GroupsKeyword GroupList
1969 check_ignored_section("GROUPS");
1975 | GroupList Group optSemiColon
1979 GroupName AssignmentChar GroupMembers
1983 Identifier { Free($1); }
1993 | seqGroupMember ',' HostName
1998 | Identifier { Free($1); }
2001 /******************** [COMPONENTS] section *******************/
2003 ComponentsKeyword ComponentList
2005 check_ignored_section("COMPONENTS");
2011 | ComponentList ComponentItem optSemiColon
2015 ComponentName AssignmentChar ComponentLocation
2019 Identifier { Free($1); }
2024 Identifier { Free($1); }
2028 /****************** [MAIN_CONTROLLER] section *********************/
2029 MainControllerSection:
2030 MainControllerKeyword MCParameterList
2032 check_ignored_section("MAIN_CONTROLLER");
2038 | MCParameterList MCParameter optSemiColon
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 {}
2053 | IntegerValue { delete $1; }
2056 /****************** [INCLUDE] section *********************/
2058 IncludeKeyword IncludeFiles
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.");
2069 | IncludeFiles IncludeFile
2073 Cstring { Free($1.chars_ptr); }
2076 /****************** [DEFINE] section *********************/
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.");
2087 /*********************************************************/
2092 $$ = Module_Param::OT_ASSIGN;
2097 $$ = Module_Param::OT_CONCAT;
2108 static void reset_configuration_options()
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] */
2127 TTCN_Runtime::clear_external_commands();
2129 begin_controlpart_command_set = FALSE;
2130 end_controlpart_command_set = FALSE;
2131 begin_testcase_command_set = FALSE;
2132 end_testcase_command_set = FALSE;
2135 Module_Param* process_config_string2ttcn(const char* mp_str, bool is_component)
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);
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; }
2152 config_process_close();
2153 config_process_lex_destroy();
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);
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;
2172 Module_Param* process_config_debugger_value(const char* mp_str)
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.");
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.");
2186 reset_config_process_lex(NULL);
2189 Debugger_Value_Parsing debugger_value_parsing;
2190 if (config_process_parse()) {
2194 catch (const TC_Error& TC_error) {
2195 if (parsed_module_param != NULL) {
2196 delete parsed_module_param;
2197 parsed_module_param = NULL;
2201 config_process_close();
2202 config_process_lex_destroy();
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);
2215 if (parsed_module_param == NULL) {
2216 ttcn3_debugger.print(DRET_NOTIFICATION, "Internal error: could not parse TTCN string.");
2219 Module_Param* ret_val = parsed_module_param;
2220 parsed_module_param = NULL;
2225 boolean process_config_string(const char *config_string, int string_len)
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.");
2238 reset_configuration_options();
2239 reset_config_process_lex(NULL);
2241 if (config_process_parse()) error_flag = TRUE;
2243 } catch (const TC_Error& TC_error) {
2247 config_process_close();
2248 config_process_lex_destroy();
2254 boolean process_config_file(const char *file_name)
2257 string_chain_t *filenames=NULL;
2259 reset_configuration_options();
2261 if(preproc_parse_file(file_name, &filenames, &config_defines))
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) {
2273 if(config_process_parse()) error_flag=TRUE;
2274 } catch (const TC_Error& TC_error) {
2278 config_process_close();
2279 config_process_lex_destroy();
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();
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. */
2295 string_map_free(config_defines);
2296 config_defines = NULL;
2301 void config_process_error_f(const char *error_str, ...)
2303 if (Ttcn_String_Parsing::happening() || Debugger_Value_Parsing::happening()) {
2305 va_start(p_var, error_str);
2306 char* error_msg_str = mprintf_va_list(error_str, 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);
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);
2317 Free(error_msg_str);
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(),
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);
2334 va_start(pvar, error_str);
2335 TTCN_Logger::log_event_va_list(error_str, pvar);
2337 TTCN_Logger::end_event();
2341 void config_process_error(const char *error_str)
2343 config_process_error_f("%s", error_str);
2346 void config_preproc_error(const char *error_str, ...)
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);
2354 va_start(pvar, error_str);
2355 TTCN_Logger::log_event_va_list(error_str, pvar);
2357 TTCN_Logger::end_event();
2361 void path_error(const char *fmt, ...)
2364 fprintf(stderr, "File error: ");
2365 va_start(parameters, fmt);
2366 vfprintf(stderr, fmt, parameters);
2368 fprintf(stderr, "\n");
2371 static void check_duplicate_option(const char *section_name,
2372 const char *option_name, boolean& 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;
2380 static void check_ignored_section(const char *section_name)
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);
2388 static void set_param(Module_Param& param)
2391 Module_List::set_param(param);
2393 catch (const TC_Error& TC_error) {
2398 unsigned char char_to_hexdigit_(char c)
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;
2404 config_process_error_f("char_to_hexdigit_(): invalid argument: %c", c);
2405 return 0; // to avoid warning