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