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