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 ******************************************************************************/
17 #include <openssl/crypto.h>
18 #include <openssl/bn.h>
20 #include "../../common/memory.h"
21 #include "../../common/config_preproc.h"
22 #include "../mctr/config_data.h"
23 #include "../../core/Types.h"
24 #include "../../core/RInt.hh"
26 #define YYERROR_VERBOSE
28 extern FILE *config_read_in;
29 extern int config_read_lineno;
30 extern char *config_read_text;
31 extern int config_read_lex();
32 extern void config_read_restart(FILE *new_file);
33 extern void config_read_reset(const char* fname);
34 extern void config_read_close();
35 extern std::string get_cfg_read_current_file();
39 boolean error_flag = FALSE;
40 static boolean local_addr_set = FALSE,
41 tcp_listen_port_set = FALSE,
42 kill_timer_set = FALSE,
45 static int config_read_parse();
46 int process_config_read_file(const char *file_name);
47 static void check_duplicate_option(const char *option_name,
48 boolean *option_flag);
49 void config_read_warning(const char *warning_str, ...);
50 void config_read_error(const char *error_str, ...);
54 static char *group_name = NULL;
56 string_map_t *config_defines;
61 static void yyprint(FILE *file, int type, const YYSTYPE& value);
62 #define YYPRINT(f,t,v) yyprint(f,t,v)
73 cf_timestamp_format ts_val;
74 execute_list_item execute_item_val;
77 %token ModuleParametersKeyword
79 %token ProfilerKeyword
80 %token TestportParametersKeyword
82 %token ExternalCommandsKeyword
84 %token ComponentsKeyword
85 %token MainControllerKeyword
89 %token ObjIdKeyword "objid"
90 %token CharKeyword "char"
91 %token ControlKeyword "control"
92 %token MTCKeyword "mtc"
93 %token SystemKeyword "system"
94 %token NULLKeyword "NULL"
95 %token nullKeyword "null"
96 %token OmitKeyword "omit"
97 %token AssignmentChar ":= or ="
98 %token ConcatChar "&="
99 %token ComplementKeyword "complement"
101 %token SupersetKeyword "superset"
102 %token SubsetKeyword "subset"
103 %token PatternKeyword "pattern"
104 %token PermutationKeyword "permutation"
105 %token LengthKeyword "length"
106 %token IfpresentKeyword "ifpresent"
107 %token InfinityKeyword "infinity"
109 %token LogFile "LogFile of FileName"
110 %token EmergencyLogging
111 %token EmergencyLoggingBehaviour
112 %token EmergencyLoggingBehaviourValue "BufferAll or BufferMasked"
113 %token EmergencyLoggingMask
116 %token TimestampFormat
117 %token ConsoleTimestampFormat
118 %token SourceInfoFormat "LogSourceInfo or SourceInfoFormat"
125 %token BeginControlPart
126 %token EndControlPart
130 %token <str_val> Identifier
131 %token ASN1LowerIdentifier "ASN.1 identifier beginning with a lowercase letter"
133 %token <int_val> Number
134 %token <float_val> Float
135 %token BooleanValue "true or false"
137 %token Bstring "bit string value"
138 %token Hstring "hex string value"
139 %token Ostring "octet string value"
140 %token BstringMatch "bit string template"
141 %token HstringMatch "hex string template"
142 %token OstringMatch "octet string template"
143 %token <str_val> Cstring "character string value"
144 %token <str_val> DNSName "a host name"
146 %token LoggingBitCollection
147 %token <ts_val> TimestampValue "Time, Datetime or Seconds"
148 %token SourceInfoValue "None, Single or Stack"
149 %token YesNo "Yes or No" /* from LOGGING section */
154 %token UnixSocketEnabled
155 %token YesToken "yes" /* from MAIN_CONTROLLER section */
162 %token DiskFullAction
165 %token Re_try /* Retry clashes with an enum in Qt */
168 %token DisableProfilerKeyword "DisableProfiler"
169 %token DisableCoverageKeyword "DisableCoverage"
170 %token DatabaseFileKeyword "DatabaseFile"
171 %token AggregateDataKeyword "AggregateData"
172 %token StatisticsFileKeyword "StatisticsFile"
173 %token DisableStatisticsKeyword "DisableStatistics"
174 %token StatisticsFilterKeyword "StatisticsFilter"
175 %token StartAutomaticallyKeyword "StartAutomatically"
176 %token NetLineTimesKeyword "NetLineTimes"
177 %token NetFunctionTimesKeyword "NetFunctionTimes"
178 %token ProfilerStatsFlag "profiler statistics flag"
180 %type <int_val> IntegerValue
181 %type <float_val> FloatValue KillTimerValue
182 %type <str_val> HostName StringValue LogFileName
183 %type <str_val> ComponentName
184 %type <str_val> ComponentLocation
185 %type <execute_item_val> ExecuteItem
187 %destructor { Free($$); }
198 Free($$.module_name);
199 Free($$.testcase_name);
203 %destructor { BN_free($$); }
214 Source of conflicts (2 S/R):
216 1.) 2 conflicts in two distinct states
217 When seeing a '*' token after an integer or float value in section
218 [MODULE_PARAMETERS] parser cannot decide whether the token is a multiplication
219 operator (shift) or it refers to all modules in the next module parameter
222 The built-in Bison behavior always chooses the shift over the reduce
223 (the * is interpreted as multiplication).
234 ModuleParametersSection
237 | TestportParametersSection
239 | ExternalCommandsSection
242 | MainControllerSection
247 /******************* [MODULE_PARAMETERS] section *******************/
249 ModuleParametersSection:
250 ModuleParametersKeyword ModuleParameters
255 | ModuleParameters ModuleParameter optSemiColon
259 ParameterName ParamOpType ParameterValue
264 | '*' '.' ParameterNameSegment
267 ParameterNameSegment:
268 ParameterNameSegment '.' Identifier { Free($3); }
269 | ParameterNameSegment '[' Number ']' { BN_free($3); }
270 | Identifier { Free($1); }
275 | SimpleParameterValue LengthMatch
276 | SimpleParameterValue IfpresentKeyword
277 | SimpleParameterValue LengthMatch IfpresentKeyword
281 LengthKeyword '(' LengthBound ')'
282 | LengthKeyword '(' LengthBound DotDot LengthBound ')'
283 | LengthKeyword '(' LengthBound DotDot InfinityKeyword ')'
287 IntegerValue { BN_free($1); }
290 SimpleParameterValue:
291 IntegerValue { BN_free($1); }
299 | Cstring { Free($1); }
300 | UniversalCharstringValue
310 | PatternKeyword PatternChunkList
321 | PatternChunkList '&' PatternChunk
325 Cstring { Free($1); }
330 '(' '-' InfinityKeyword DotDot IntegerValue ')' { BN_free($5); }
331 | '(' IntegerValue DotDot IntegerValue ')' { BN_free($2); BN_free($4); }
332 | '(' IntegerValue DotDot InfinityKeyword ')' { BN_free($2); }
336 '(' '-' InfinityKeyword DotDot FloatValue ')'
337 | '(' FloatValue DotDot FloatValue ')'
338 | '(' FloatValue DotDot InfinityKeyword ')'
342 '(' UniversalCharstringFragment DotDot UniversalCharstringFragment ')'
346 | '(' IntegerValue ')' { $$ = $2; }
347 | '+' IntegerValue %prec UnarySign { $$ = $2; }
348 | '-' IntegerValue %prec UnarySign
350 BN_set_negative($2, !BN_is_negative($2));
353 | IntegerValue '+' IntegerValue
360 | IntegerValue '-' IntegerValue
367 | IntegerValue '*' IntegerValue
370 BN_CTX *ctx = BN_CTX_new();
372 BN_mul($$, $1, $3, ctx);
377 | IntegerValue '/' IntegerValue
380 BIGNUM *BN_0 = BN_new();
381 BN_set_word(BN_0, 0);
382 if (BN_cmp($3, BN_0) == 0) {
383 config_read_error("Integer division by zero.");
386 BN_CTX *ctx = BN_CTX_new();
388 BN_div($$, NULL, $1, $3, ctx);
399 | '(' FloatValue ')' { $$ = $2; }
400 | '+' FloatValue %prec UnarySign { $$ = $2; }
401 | '-' FloatValue %prec UnarySign { $$ = -$2; }
402 | FloatValue '+' FloatValue { $$ = $1 + $3; }
403 | FloatValue '-' FloatValue { $$ = $1 - $3; }
404 | FloatValue '*' FloatValue { $$ = $1 * $3; }
405 | FloatValue '/' FloatValue
408 config_read_error("Floating point division by zero.");
415 ObjIdKeyword '{' ObjIdComponentList '}'
420 | ObjIdComponentList ObjIdComponent
429 Number { BN_free($1); }
433 Identifier '(' Number ')' { Free($1); BN_free($3); }
438 | BitstringValue ConcatOp Bstring
443 | HexstringValue ConcatOp Hstring
448 | OctetstringValue ConcatOp Ostring
451 UniversalCharstringValue:
452 Cstring seqUniversalCharstringFragment { Free($1); }
454 | Quadruple seqUniversalCharstringFragment
457 seqUniversalCharstringFragment:
458 ConcatOp UniversalCharstringFragment
459 | seqUniversalCharstringFragment ConcatOp UniversalCharstringFragment
462 UniversalCharstringFragment:
463 Cstring { Free($1); }
468 CharKeyword '(' IntegerValue ',' IntegerValue ',' IntegerValue ','
471 char *int_val_str_1 = BN_bn2dec($3);
472 char *int_val_str_2 = BN_bn2dec($5);
473 char *int_val_str_3 = BN_bn2dec($7);
474 char *int_val_str_4 = BN_bn2dec($9);
475 BIGNUM *BN_0 = BN_new();
476 BN_set_word(BN_0, 0);
477 BIGNUM *BN_127 = BN_new();
478 BN_set_word(BN_127, 127);
479 BIGNUM *BN_255 = BN_new();
480 BN_set_word(BN_255, 255);
481 if (BN_cmp($3, BN_0) < 0 || BN_cmp($3, BN_127) > 0)
482 config_read_error("An integer value within range 0 .. 127 was expected "
483 "as first number of quadruple (group) instead of "
484 "%s.", int_val_str_1);
485 if (BN_cmp($5, BN_0) < 0 || BN_cmp($5, BN_255) > 0)
486 config_read_error("An integer value within range 0 .. 255 was expected "
487 "as second number of quadruple (plane) instead of %s.",
489 if (BN_cmp($7, BN_0) < 0 || BN_cmp($7, BN_255) > 0)
490 config_read_error("An integer value within range 0 .. 255 was expected "
491 "as third number of quadruple (row) instead of %s.",
493 if (BN_cmp($9, BN_0) < 0 || BN_cmp($9, BN_255) > 0)
494 config_read_error("An integer value within range 0 .. 255 was expected "
495 "as fourth number of quadruple (cell) instead of %d.",
504 OPENSSL_free(int_val_str_1);
505 OPENSSL_free(int_val_str_2);
506 OPENSSL_free(int_val_str_3);
507 OPENSSL_free(int_val_str_4);
517 | StringValue ConcatOp Cstring {
518 $$ = mputstr($1, $3);
524 Identifier { Free($1); }
525 | ASN1LowerIdentifier
530 | '{' FieldValueList '}'
531 | '{' ArrayItemList '}'
532 | '{' IndexItemList '}'
533 | '(' ParameterValue ',' TemplateItemList ')' /* at least 2 elements to avoid shift/reduce conflicts with IntegerValue and FloatValue rules */
534 | ComplementKeyword '(' TemplateItemList ')'
535 | SupersetKeyword '(' TemplateItemList ')'
536 | SubsetKeyword '(' TemplateItemList ')'
539 ParameterValueOrNotUsedSymbol:
546 | TemplateItemList ',' ParameterValue
551 | FieldValueList ',' FieldValue
555 FieldName AssignmentChar ParameterValueOrNotUsedSymbol
559 Identifier { Free($1); }
560 | ASN1LowerIdentifier
565 | ArrayItemList ',' ArrayItem
569 ParameterValueOrNotUsedSymbol
570 | PermutationKeyword '(' TemplateItemList ')'
575 | IndexItemList ',' IndexItem
579 IndexItemIndex AssignmentChar ParameterValue
583 '[' IntegerValue ']' { BN_free($2); }
586 /******************* [LOGGING] section *******************/
589 LoggingKeyword LoggingParamList
594 | LoggingParamList LoggingParamLines optSemiColon
599 | ComponentId '.' LoggingParam
600 | ComponentId '.' LoggerPluginId '.' LoggingParam
601 | LoggerPlugins AssignmentChar '{' LoggerPluginList '}'
602 | ComponentId '.' LoggerPlugins AssignmentChar '{' LoggerPluginList '}'
607 | Identifier { Free($1); }
611 FileMask AssignmentChar LoggingBitMask
612 | ConsoleMask AssignmentChar LoggingBitMask
613 | LogFileSize AssignmentChar Number { BN_free($3); }
614 | EmergencyLogging AssignmentChar Number { BN_free($3); }
615 | EmergencyLoggingBehaviour AssignmentChar EmergencyLoggingBehaviourValue
616 | EmergencyLoggingMask AssignmentChar LoggingBitMask
617 | LogFileNumber AssignmentChar Number { BN_free($3); }
618 | DiskFullAction AssignmentChar DiskFullActionValue
619 | LogFile AssignmentChar LogFileName { cfg->set_log_file($3); }
620 | TimestampFormat AssignmentChar TimestampValue
621 | ConsoleTimestampFormat AssignmentChar TimestampValue {cfg->tsformat=$3;}
622 | SourceInfoFormat AssignmentChar SourceInfoSetting
623 | AppendFile AssignmentChar YesNoOrBoolean
624 | LogEventTypes AssignmentChar LogEventTypesValue
625 | LogEntityName AssignmentChar YesNoOrBoolean
626 | MatchingHints AssignmentChar MatchVerbosityValue
627 | Identifier AssignmentChar StringValue { Free($1); Free($3); }
632 | LoggerPluginList ',' LoggerPlugin
636 Identifier { Free($1); }
637 | Identifier AssignmentChar StringValue { Free($1); Free($3); }
644 | Re_try '(' Number ')' { BN_free($3); }
649 StringValue { $$ = $1; }
652 //optTestComponentIdentifier:
654 /* | Identifier '.' { Free($1); }
661 LoggingBitorCollection
662 | LoggingBitMask ListOp LoggingBitorCollection
670 LoggingBitorCollection:
672 | LoggingBitCollection
696 /*********************** [PROFILER] ********************************/
699 ProfilerKeyword ProfilerSettings
704 | ProfilerSettings ProfilerSetting optSemiColon
708 DisableProfilerSetting
709 | DisableCoverageSetting
710 | DatabaseFileSetting
711 | AggregateDataSetting
712 | StatisticsFileSetting
713 | DisableStatisticsSetting
714 | StatisticsFilterSetting
715 | StartAutomaticallySetting
716 | NetLineTimesSetting
717 | NetFunctionTimesSetting
720 DisableProfilerSetting:
721 DisableProfilerKeyword AssignmentChar BooleanValue
724 DisableCoverageSetting:
725 DisableCoverageKeyword AssignmentChar BooleanValue
729 DatabaseFileKeyword AssignmentChar StringValue { Free($3); }
732 AggregateDataSetting:
733 AggregateDataKeyword AssignmentChar BooleanValue
736 StatisticsFileSetting:
737 StatisticsFileKeyword AssignmentChar StringValue { Free($3); }
740 DisableStatisticsSetting:
741 DisableStatisticsKeyword AssignmentChar BooleanValue
744 StatisticsFilterSetting:
745 StatisticsFilterKeyword AssignmentChar ProfilerStatsFlags
746 | StatisticsFilterKeyword ConcatChar ProfilerStatsFlags
751 | ProfilerStatsFlag '&' ProfilerStatsFlags
752 | ProfilerStatsFlag '|' ProfilerStatsFlags
755 StartAutomaticallySetting:
756 StartAutomaticallyKeyword AssignmentChar BooleanValue
760 NetLineTimesKeyword AssignmentChar BooleanValue
763 NetFunctionTimesSetting:
764 NetFunctionTimesKeyword AssignmentChar BooleanValue
767 /******************* [TESTPORT_PARAMETERS] section *******************/
769 TestportParametersSection:
770 TestportParametersKeyword TestportParameterList
773 TestportParameterList:
775 | TestportParameterList TestportParameter optSemiColon
779 ComponentId '.' TestportName '.' TestportParameterName AssignmentChar
780 TestportParameterValue
784 Identifier { Free($1); }
785 | Number { BN_free($1); }
789 | Cstring { Free($1); }
793 Identifier { Free($1); }
794 | Identifier ArrayRef { Free($1); }
799 '[' IntegerValue ']' { BN_free($2); }
800 | ArrayRef '[' IntegerValue ']' { BN_free($3); }
803 TestportParameterName:
804 Identifier { Free($1); }
807 TestportParameterValue:
808 StringValue { Free($1); }
811 /******************* [EXECUTE] section *******************/
814 ExecuteKeyword ExecuteList
819 | ExecuteList ExecuteItem optSemiColon
829 $$.testcase_name = NULL;
831 | Identifier '.' ControlKeyword
834 $$.testcase_name = NULL;
836 | Identifier '.' Identifier
839 $$.testcase_name = $3;
844 $$.testcase_name = mcopystr("*");
848 /******************* [EXTERNAL_COMMANDS] section *******************/
850 ExternalCommandsSection:
851 ExternalCommandsKeyword ExternalCommandList
856 | ExternalCommandList ExternalCommand optSemiColon
860 BeginControlPart AssignmentChar Command
861 | EndControlPart AssignmentChar Command
862 | BeginTestCase AssignmentChar Command
863 | EndTestCase AssignmentChar Command
867 StringValue { Free($1); }
870 /******************* [GROUPS] section *******************/
873 GroupsKeyword GroupList
878 | GroupList Group optSemiColon
882 GroupName AssignmentChar GroupMembers
890 Identifier { group_name = $1; }
896 if (group_name != NULL) cfg->add_host(group_name, NULL);
904 if (group_name != NULL && $1 != NULL)
905 cfg->add_host(group_name, $1);
908 | seqGroupMember ',' HostName
910 if (group_name != NULL && $3 != NULL)
911 cfg->add_host(group_name, $3);
922 size_t string_len = strlen($$);
923 for (size_t i = 0; i < string_len; i++) $$[i] = tolower($$[i]);
928 /******************* [COMPONENTS] section *******************/
931 ComponentsKeyword ComponentList
936 | ComponentList ComponentItem optSemiColon
940 ComponentName AssignmentChar ComponentLocation
942 if ($3 != NULL) cfg->add_component($3, $1);
949 Identifier { $$ = $1; }
954 Identifier { $$ = $1; }
955 | DNSName { $$ = $1; }
958 /******************* [MAIN_CONTROLLER] section *******************/
960 MainControllerSection:
961 MainControllerKeyword MCParameterList
966 | MCParameterList MCParameter optSemiColon
970 LocalAddress AssignmentChar HostName
972 check_duplicate_option("LocalAddress", &local_addr_set);
973 Free(cfg->local_addr);
974 cfg->local_addr = $3;
976 | TCPPort AssignmentChar IntegerValue
978 check_duplicate_option("TCPPort", &tcp_listen_port_set);
979 BIGNUM *BN_0 = BN_new();
980 BN_set_word(BN_0, 0);
981 BIGNUM *BN_65535 = BN_new();
982 BN_set_word(BN_65535, 65535);
983 char *int_val_str = BN_bn2dec($3);
984 if (BN_cmp($3, BN_0) < 0 || BN_cmp($3, BN_65535) > 0)
985 config_read_error("An integer value within range 0 .. 65535 was "
986 "expected for parameter TCPPort instead of %s.",
988 else cfg->tcp_listen_port = (unsigned short)BN_get_word($3);
992 OPENSSL_free(int_val_str);
994 | KillTimer AssignmentChar KillTimerValue
996 check_duplicate_option("KillTimer", &kill_timer_set);
997 if ($3 >= 0.0) cfg->kill_timer = $3;
998 else config_read_error("A non-negative numeric value was expected for "
999 "parameter KillTimer instead of %g.", $3);
1001 | NumHCs AssignmentChar IntegerValue
1003 check_duplicate_option("NumHCs", &num_hcs_set);
1004 BIGNUM *BN_0 = BN_new();
1005 BN_set_word(BN_0, 0);
1006 char *int_val_str = BN_bn2dec($3);
1007 if (BN_cmp($3, BN_0) <= 0)
1008 config_read_error("A positive integer value was expected for "
1009 "parameter NumHCs instead of %s.", int_val_str);
1010 else cfg->num_hcs = (int)BN_get_word($3);
1012 // Check if we really need to free this!
1014 OPENSSL_free(int_val_str);
1016 | UnixSocketEnabled AssignmentChar YesToken
1018 cfg->unix_sockets_enabled = true;
1020 | UnixSocketEnabled AssignmentChar NoToken
1022 cfg->unix_sockets_enabled = false;
1024 | UnixSocketEnabled AssignmentChar HostName
1026 config_read_error("Only 'yes' or 'no' is accepted instead of '%s'", $3);
1031 FloatValue { $$ = $1; }
1034 double tmp = (double)BN_get_word($1);
1035 if (BN_is_negative($1)) tmp *= -1;
1041 /******************* [INCLUDE] section *******************/
1044 IncludeKeyword IncludeFiles
1049 | IncludeFiles IncludeFile
1053 Cstring { Free($1); }
1056 /******************* [DEFINE] section *******************/
1062 /********************************************************/
1077 int process_config_read_file(const char *file_name, config_data *pcfg)
1080 local_addr_set = FALSE;
1081 tcp_listen_port_set = FALSE;
1082 kill_timer_set = FALSE;
1083 num_hcs_set = FALSE;
1086 string_chain_t *filenames=NULL;
1089 /* Initializing parameters to default values */
1092 if(preproc_parse_file(file_name, &filenames, &config_defines))
1096 char *fn=string_chain_cut(&filenames);
1097 config_read_lineno=1;
1098 /* The lexer can modify config_process_in
1099 * when it's input buffer is changed */
1100 config_read_in = fopen(fn, "r");
1101 if (config_read_in == NULL) {
1102 fprintf(stderr, "Cannot open configuration file: %s (%s)\n",
1103 fn, strerror(errno));
1106 FILE* tmp_cfg = config_read_in;
1107 config_read_restart(config_read_in);
1108 config_read_reset(fn);
1109 if(config_read_parse()) error_flag=TRUE;
1111 /* During parsing flex or libc may use some system calls (e.g. ioctl)
1112 * that fail with an error status. Such error codes shall be ignored in
1113 * future error messages. */
1119 config_read_close();
1121 string_map_free(config_defines);
1122 config_defines=NULL;
1124 return error_flag ? -1 : 0;
1127 static void check_duplicate_option(const char *option_name,
1128 boolean *option_flag)
1131 config_read_warning("Option `%s' was given more than once in section "
1132 "[MAIN_CONTROLLER].", option_name);
1133 } else *option_flag = TRUE;
1138 void yyprint(FILE *file, int type, const YYSTYPE& value)
1144 fprintf(file, "'%s'", value.str_val);
1148 char *string_repr = BN_bn2dec(value.int_val);
1149 fprintf(file, "%s", string_repr);
1150 OPENSSL_free(string_repr);