/****************************************************************************** * Copyright (c) 2000-2016 Ericsson Telecom AB * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * * Baji, Laszlo * Balasko, Jeno * Baranyi, Botond * Beres, Szabolcs * Delic, Adam * Forstner, Matyas * Kovacs, Ferenc * Pandi, Krisztian * Raduly, Csaba * Szabados, Kristof * Szabo, Bence Janos * Szabo, Janos Zoltan – initial implementation * Szalai, Gabor * Zalanyi, Balazs Andor * ******************************************************************************/ %{ #include #include #include #include #include #include #include #include "../common/config_preproc.h" #include "Param_Types.hh" #include "Integer.hh" #include "Float.hh" #include "Boolean.hh" #include "Objid.hh" #include "Verdicttype.hh" #include "Bitstring.hh" #include "Hexstring.hh" #include "Octetstring.hh" #include "Charstring.hh" #include "Universal_charstring.hh" #include "Module_list.hh" #include "Port.hh" #include "Runtime.hh" #include "LoggingBits.hh" #include "LoggingParam.hh" #include "Profiler.hh" #define YYERROR_VERBOSE #include "config_process.lex.hh" extern void reset_config_process_lex(const char* fname); extern void config_process_close(); extern int config_process_get_current_line(); extern std::string get_cfg_process_current_file(); static int config_process_parse(); static void check_duplicate_option(const char *section_name, const char *option_name, boolean& option_flag); static void check_ignored_section(const char *section_name); static void set_param(Module_Param& module_param); static unsigned char char_to_hexdigit(char c); static boolean error_flag = FALSE; static Module_Param* parsed_module_param = NULL; static char * parsing_error_messages = NULL; /* For detecting duplicate entries in the config file. Start out as FALSE, set to TRUE bycheck_duplicate_option(). Exception: duplication of parameters that can be component specific is checked by set_xxx(), these start out as TRUE. */ static boolean file_name_set = FALSE, file_mask_set = TRUE, console_mask_set = TRUE, timestamp_format_set = FALSE, source_info_format_set = FALSE, append_file_set = FALSE, log_event_types_set = FALSE, log_entity_name_set = FALSE, begin_controlpart_command_set = FALSE, end_controlpart_command_set = FALSE, begin_testcase_command_set = FALSE, end_testcase_command_set = FALSE, log_file_size_set = TRUE, log_file_number_set = TRUE, log_disk_full_action_set = TRUE, matching_verbosity_set = FALSE, logger_plugins_set = FALSE, plugin_specific_set = FALSE; int execute_list_len = 0; execute_list_item *execute_list = NULL; string_map_t *config_defines; %} %union{ char *str_val; int_val_t *int_val; int int_native; unsigned int uint_val; double float_val; boolean bool_val; param_objid_t objid_val; verdicttype verdict_val; param_bitstring_t bitstring_val; param_hexstring_t hexstring_val; param_charstring_t charstring_val; param_octetstring_t octetstring_val; universal_char universal_char_val; param_universal_charstring_t universal_charstring_val; Module_Param::operation_type_t param_optype_val; Vector* module_param_list; Module_Param* module_param_val; Module_Param_Length_Restriction* module_param_length_restriction; Vector* name_vector; component_id_t comp_id; execute_list_item execute_item_val; TTCN_Logger::emergency_logging_behaviour_t emergency_logging_behaviour_value; TTCN_Logger::timestamp_format_t timestamp_value; TTCN_Logger::source_info_format_t source_info_value; TTCN_Logger::log_event_types_t log_event_types_value; TTCN_Logger::disk_full_action_t disk_full_action_value; TTCN_Logger::matching_verbosity_t matching_verbosity_value; TTCN_Logger::Severity logseverity_val; Logging_Bits logoptions_val; logging_plugin_t *logging_plugins; logging_param_t logging_params; logging_setting_t logging_param_line; struct { size_t nElements; const char **elements; } uid_list; } %token ModuleParametersKeyword %token LoggingKeyword %token ProfilerKeyword %token TestportParametersKeyword %token ExecuteKeyword %token ExternalCommandsKeyword %token GroupsKeyword %token ComponentsKeyword %token MainControllerKeyword %token IncludeKeyword %token DefineKeyword %token Detailed %token Compact %token ObjIdKeyword "objid" %token CharKeyword "char" %token ControlKeyword "control" %token MTCKeyword "mtc" %token SystemKeyword "system" %token NULLKeyword "NULL" %token nullKeyword "null" %token OmitKeyword "omit" %token ComplementKeyword "complement" %token DotDot ".." %token SupersetKeyword "superset" %token SubsetKeyword "subset" %token PatternKeyword "pattern" %token PermutationKeyword "permutation" %token LengthKeyword "length" %token IfpresentKeyword "ifpresent" %token InfinityKeyword "infinity" %token AssignmentChar ":= or =" %token ConcatChar "&=" %token LogFile "LogFile or FileName" %token EmergencyLogging %token EmergencyLoggingBehaviour %token EmergencyLoggingMask %token EmergencyLoggingForFailVerdict %token BufferAll %token BufferMasked %token FileMask %token ConsoleMask %token TimestampFormat %token ConsoleTimestampFormat %token SourceInfoFormat "LogSourceInfo or SourceInfoFormat" %token AppendFile %token LogEventTypes %token LogEntityName %token BeginControlPart %token EndControlPart %token BeginTestCase %token EndTestCase %token Identifier %token ASN1LowerIdentifier "ASN.1 identifier beginning with a lowercase letter" %token Number MPNumber "integer value" %token Float MPFloat "float value" %token BooleanValue "true or false" %token VerdictValue %token Bstring "bit string value" %token Hstring "hex string value" %token Ostring "octet string value" %token BstringMatch "bit string template" %token HstringMatch "hex string template" %token OstringMatch "octet string template" %token Cstring MPCstring "charstring value" %token UIDval %token DNSName "hostname" /* a single bit */ %token LoggingBit /* a collection of bits */ %token LoggingBitCollection %token SubCategories %token EmergencyLoggingBehaviourValue "BufferAll or BufferMasked" %token TimestampValue "Time, Datetime or Seconds" %token SourceInfoValue "None, Single or Stack" %token YesNo "yes or no" %token LocalAddress %token TCPPort %token KillTimer %token NumHCs %token UnixSocketEnabled %token YesToken "yes" %token NoToken "no" %token LogFileSize %token LogFileNumber %token DiskFullAction %token MatchingHints %token LoggerPlugins %token Error %token Stop %token Retry %token Delete %token TtcnStringParsingKeyword %token DisableProfilerKeyword "DisableProfiler" %token DisableCoverageKeyword "DisableCoverage" %token DatabaseFileKeyword "DatabaseFile" %token AggregateDataKeyword "AggregateData" %token StatisticsFileKeyword "StatisticsFile" %token DisableStatisticsKeyword "DisableStatistics" %token StatisticsFilterKeyword "StatisticsFilter" %token StartAutomaticallyKeyword "StartAutomatically" %token NetLineTimesKeyword "NetLineTimes" %token NetFunctionTimesKeyword "NetFunctionTimes" %token ProfilerStatsFlag "profiler statistics filter" %type IntegerValue %type FloatValue %type ObjIdValue ObjIdComponentList %type ObjIdComponent NumberForm NameAndNumberForm %type UniversalCharstringValue UniversalCharstringFragment %type Quadruple %type USI UIDlike %type LoggerPluginId %type LoggerPlugin LoggerPluginList %type LoggingParam %type LoggingParamLines %type LogFileName StringValue /* a collection of bits */ %type LoggingBitmask %type LoggingBitOrCollection %type SourceInfoSetting %type YesNoOrBoolean %type LogEventTypesValue %type DiskFullActionValue %type Command %type VerbosityValue %type ComponentId %type TestportName ArrayRef TestportParameterName TestportParameterValue %type ExecuteItem %type BitstringValue %type HexstringValue %type OctetstringValue %type ParameterName ParameterNameSegment %type ParamOpType %type FieldName %type ParameterValue SimpleParameterValue ParameterValueOrNotUsedSymbol FieldValue ArrayItem IndexItem IndexItemList FieldValueList ArrayItemList CompoundValue IntegerRange FloatRange StringRange ParameterExpression ParameterReference %type TemplateItemList %type LengthMatch %type PatternChunk %type IndexItemIndex LengthBound %type ProfilerStatsFlags %destructor { Free($$); } ArrayRef ASN1LowerIdentifier Command FieldName Identifier LogFileName StringValue TestportName TestportParameterName TestportParameterValue PatternChunk BstringMatch HstringMatch OstringMatch %destructor { Free($$.components_ptr); } ObjIdComponentList ObjIdValue %destructor { Free($$.bits_ptr); } Bstring BitstringValue %destructor { Free($$.nibbles_ptr); } Hstring HexstringValue %destructor { Free($$.octets_ptr); } Ostring OctetstringValue %destructor { Free($$.chars_ptr); } Cstring MPCstring %destructor { Free($$.uchars_ptr); } UniversalCharstringFragment UniversalCharstringValue %destructor { if ($$.id_selector == COMPONENT_ID_NAME) Free($$.id_name); } ComponentId %destructor { Free($$.module_name); Free($$.testcase_name); } ExecuteItem %destructor { delete $$; } IntegerValue NameAndNumberForm Number MPNumber NumberForm ObjIdComponent ParameterValue SimpleParameterValue ParameterValueOrNotUsedSymbol ArrayItemList FieldValueList IndexItemList CompoundValue ArrayItem FieldValue IndexItem IntegerRange FloatRange StringRange ParameterExpression ParameterReference %destructor { delete $$; } LengthMatch %destructor { for(size_t i=0; i<$$->size(); i++) { delete $$->at(i); } delete $$; } TemplateItemList %destructor { for(size_t i=0; i<$$->size(); i++) { Free($$->at(i)); } delete $$; } ParameterName ParameterNameSegment %left '&' /* to avoid shift/reduce conflicts */ %left '+' '-' %left '*' '/' %left UnarySign %expect 1 /* 1 conflict: When seeing a '*' token after a module parameter expression the parser cannot decide whether the token is a multiplication operator (shift) or it refers to all modules in the next module parameter (reduce). */ %% GrammarRoot: ConfigFile { if (Ttcn_String_Parsing::happening()) { config_process_error("Config file cannot be parsed as ttcn string"); } } | TtcnStringParsingKeyword ParameterValue { parsed_module_param = $2; } ; ConfigFile: /* empty */ | ConfigFile Section ; Section: ModuleParametersSection | LoggingSection | ProfilerSection | TestportParametersSection | ExecuteSection | ExternalCommandsSection | GroupsSection | ComponentsSection | MainControllerSection | IncludeSection | DefineSection ; ModuleParametersSection: ModuleParametersKeyword ModuleParameters ; ModuleParameters: /* empty */ | ModuleParameters ModuleParameter optSemiColon ; ModuleParameter: ParameterName ParamOpType ParameterValue { Module_Param* mp = $3; mp->set_id(new Module_Param_Name(*$1)); mp->set_operation_type($2); set_param(*mp); delete mp; delete $1; } ; ParameterName: ParameterNameSegment { $$ = $1; } | '*' '.' ParameterNameSegment { $$ = $3; } ; ParameterNameSegment: ParameterNameSegment '.' Identifier { $$ = $1; $$->push_back($3); } | ParameterNameSegment IndexItemIndex { $$ = $1; $$->push_back(mprintf("%d", $2)); } | Identifier { $$ = new Vector(); $$->push_back($1); } ; ParameterValue: ParameterExpression { $$ = $1; } | ParameterExpression LengthMatch { $$ = $1; $$->set_length_restriction($2); } | ParameterExpression IfpresentKeyword { $$ = $1; $$->set_ifpresent(); } | ParameterExpression LengthMatch IfpresentKeyword { $$ = $1; $$->set_length_restriction($2); $$->set_ifpresent(); } ; LengthMatch: LengthKeyword '(' LengthBound ')' { $$ = new Module_Param_Length_Restriction(); $$->set_single((size_t)$3); } | LengthKeyword '(' LengthBound DotDot LengthBound ')' { if ($3>$5) { config_process_error("invalid length restriction: lower bound > upper bound"); } $$ = new Module_Param_Length_Restriction(); $$->set_min((size_t)$3); $$->set_max((size_t)$5); } | LengthKeyword '(' LengthBound DotDot InfinityKeyword ')' { $$ = new Module_Param_Length_Restriction(); $$->set_min((size_t)$3); } ; LengthBound: ParameterExpression { $1->set_id(new Module_Param_CustomName(mcopystr("length bound"))); INTEGER tmp; tmp.set_param(*$1); if (!tmp.get_val().is_native()) { config_process_error("bignum length restriction bound."); $$ = 0; } else if (tmp.get_val().is_negative()) { config_process_error("negative length restriction bound."); $$ = 0; } else { $$ = tmp; } delete $1; } ; // one global rule for expressions in module parameters // the expression's result will be calculated by set_param() ParameterExpression: SimpleParameterValue { $$ = $1; } | ParameterReference { $$ = $1; } | '(' ParameterExpression ')' { $$ = $2; } | '+' ParameterExpression %prec UnarySign { $$ = $2; } | '-' ParameterExpression %prec UnarySign { $$ = new Module_Param_Expression($2); } | ParameterExpression '+' ParameterExpression { $$ = new Module_Param_Expression(Module_Param::EXPR_ADD, $1, $3); } | ParameterExpression '-' ParameterExpression { $$ = new Module_Param_Expression(Module_Param::EXPR_SUBTRACT, $1, $3); } | ParameterExpression '*' ParameterExpression { $$ = new Module_Param_Expression(Module_Param::EXPR_MULTIPLY, $1, $3); } | ParameterExpression '/' ParameterExpression { $$ = new Module_Param_Expression(Module_Param::EXPR_DIVIDE, $1, $3); } | ParameterExpression '&' ParameterExpression { $$ = new Module_Param_Expression(Module_Param::EXPR_CONCATENATE, $1, $3); } ; ParameterReference: // enumerated values are also treated as references by the parser, // these will be sorted out later during set_param() ParameterNameSegment { $$ = new Module_Param_Reference(new Module_Param_Name(*$1)); } ; SimpleParameterValue: MPNumber { $$ = new Module_Param_Integer($1); } | MPFloat { $$ = new Module_Param_Float($1); } | BooleanValue { $$ = new Module_Param_Boolean($1); } | ObjIdValue { $$ = new Module_Param_Objid($1.n_components, $1.components_ptr); } | VerdictValue { $$ = new Module_Param_Verdict($1); } | BitstringValue { $$ = new Module_Param_Bitstring($1.n_bits, $1.bits_ptr); } | HexstringValue { $$ = new Module_Param_Hexstring($1.n_nibbles, $1.nibbles_ptr); } | OctetstringValue { $$ = new Module_Param_Octetstring($1.n_octets, $1.octets_ptr); } | MPCstring { $$ = new Module_Param_Charstring($1.n_chars, $1.chars_ptr); } | UniversalCharstringValue { $$ = new Module_Param_Universal_Charstring($1.n_uchars, $1.uchars_ptr); } | OmitKeyword { $$ = new Module_Param_Omit(); } | NULLKeyword { $$ = new Module_Param_Asn_Null(); } | nullKeyword { $$ = new Module_Param_Ttcn_Null(); } | MTCKeyword { $$ = new Module_Param_Ttcn_mtc(); } | SystemKeyword { $$ = new Module_Param_Ttcn_system(); } | '?' { $$ = new Module_Param_Any(); } | '*' { $$ = new Module_Param_AnyOrNone(); } | IntegerRange { $$ = $1; } | FloatRange { $$ = $1; } | StringRange { $$ = $1; } | PatternKeyword PatternChunk { $$ = new Module_Param_Pattern($2); } | BstringMatch { // conversion int n_chars = (int)mstrlen($1); unsigned char* chars_ptr = (unsigned char*)Malloc(n_chars*sizeof(unsigned char)); for (int i=0; i octet_vec; int str_len = (int)mstrlen($1); for (int i=0; i=str_len) config_process_error("Unexpected end of octetstring pattern"); // second digit num += char_to_hexdigit($1[i]); } octet_vec.push_back(num); } Free($1); int n_chars = (int)octet_vec.size(); unsigned short* chars_ptr = (unsigned short*)Malloc(n_chars*sizeof(unsigned short)); for (int i=0; iget_val(); delete $1; } | ObjIdComponentList ObjIdComponent { $$.n_components = $1.n_components + 1; $$.components_ptr = (int *)Realloc($1.components_ptr, $$.n_components * sizeof(int)); $$.components_ptr[$$.n_components - 1] = $2->get_val(); delete $2; } ; ObjIdComponent: NumberForm { $$ = $1; } | NameAndNumberForm { $$ = $1; } ; NumberForm: MPNumber { $$ = $1; } ; NameAndNumberForm: Identifier '(' MPNumber ')' { Free($1); $$ = $3; } ; BitstringValue: Bstring { $$ = $1; } ; HexstringValue: Hstring { $$ = $1; } ; OctetstringValue: Ostring { $$ = $1; } ; UniversalCharstringValue: Quadruple { $$.n_uchars = 1; $$.uchars_ptr = (universal_char*)Malloc(sizeof(universal_char)); $$.uchars_ptr[0] = $1; } | USI { $$.n_uchars = $1.nElements; $$.uchars_ptr = (universal_char*)Malloc($$.n_uchars * sizeof(universal_char)); for (int i = 0; i < $$.n_uchars; ++i) { size_t offset = 1; //Always starts with u or U offset = $1.elements[i][1] == '+' ? offset + 1 : offset; //Optional '+' char* p; unsigned long int_val = strtoul($1.elements[i] + offset, &p, 16); if(*p != 0) { //Error, should not happen config_process_error_f("Invalid hexadecimal string %s.", $1.elements[i] + offset); } //Fill in the quadruple $$.uchars_ptr[i].uc_group = (int_val >> 24) & 0xFF; $$.uchars_ptr[i].uc_plane = (int_val >> 16) & 0xFF; $$.uchars_ptr[i].uc_row = (int_val >> 8) & 0xFF; $$.uchars_ptr[i].uc_cell = int_val & 0xFF; Free((char*)$1.elements[i]); } Free($1.elements); } ; UniversalCharstringFragment: MPCstring { $$.n_uchars = $1.n_chars; $$.uchars_ptr = (universal_char*) Malloc($$.n_uchars * sizeof(universal_char)); for (int i = 0; i < $1.n_chars; i++) { $$.uchars_ptr[i].uc_group = 0; $$.uchars_ptr[i].uc_plane = 0; $$.uchars_ptr[i].uc_row = 0; $$.uchars_ptr[i].uc_cell = $1.chars_ptr[i]; } Free($1.chars_ptr); } | Quadruple { $$.n_uchars = 1; $$.uchars_ptr = (universal_char*)Malloc(sizeof(universal_char)); $$.uchars_ptr[0] = $1; } ; Quadruple: CharKeyword '(' ParameterExpression ',' ParameterExpression ',' ParameterExpression ',' ParameterExpression ')' { $3->set_id(new Module_Param_CustomName(mcopystr("quadruple group"))); $5->set_id(new Module_Param_CustomName(mcopystr("quadruple plane"))); $7->set_id(new Module_Param_CustomName(mcopystr("quadruple row"))); $9->set_id(new Module_Param_CustomName(mcopystr("quadruple cell"))); INTEGER g, p, r, c; g.set_param(*$3); p.set_param(*$5); r.set_param(*$7); c.set_param(*$9); if (g < 0 || g > 127) { char *s = g.get_val().as_string(); config_process_error_f("The first number of quadruple (group) must be " "within the range 0 .. 127 instead of %s.", s); Free(s); $$.uc_group = g < 0 ? 0 : 127; } else { $$.uc_group = g; } if (p < 0 || p > 255) { char *s = p.get_val().as_string(); config_process_error_f("The second number of quadruple (plane) must be " "within the range 0 .. 255 instead of %s.", s); Free(s); $$.uc_plane = p < 0 ? 0 : 255; } else { $$.uc_plane = p; } if (r < 0 || r > 255) { char *s = r.get_val().as_string(); config_process_error_f("The third number of quadruple (row) must be " "within the range 0 .. 255 instead of %s.", s); Free(s); $$.uc_row = r < 0 ? 0 : 255; } else { $$.uc_row = r; } if (c < 0 || c > 255) { char *s = c.get_val().as_string(); config_process_error_f("The fourth number of quadruple (cell) must be " "within the range 0 .. 255 instead of %s.", s); Free(s); $$.uc_cell = c < 0 ? 0 : 255; } else { $$.uc_cell = c; } delete $3; delete $5; delete $7; delete $9; } ; USI: CharKeyword '(' UIDlike ')' { $$ = $3; } ; UIDlike: UIDval { $$.nElements = 1; $$.elements = (const char**) Malloc($$.nElements * sizeof(*$$.elements)); $$.elements[$$.nElements-1] = $1; } | UIDlike ',' UIDval { $$.nElements = $1.nElements + 1; $$.elements = (const char**) Realloc($1.elements, ($$.nElements) * sizeof(*$1.elements)); $$.elements[$$.nElements-1] = $3; } ; // character strings outside of the [MODULE_PARAMETERS] section StringValue: Cstring { $$ = mcopystr($1.chars_ptr); Free($1.chars_ptr); } | StringValue '&' Cstring { $$ = mputstr($1, $3.chars_ptr); Free($3.chars_ptr); } ; CompoundValue: '{' '}' { $$ = new Module_Param_Value_List(); } | '{' FieldValueList '}' { $$ = $2; } | '{' ArrayItemList '}' { $$ = $2; } | '{' IndexItemList '}' { $$ = $2; } | '(' ParameterValue ',' TemplateItemList ')' /* at least 2 elements to avoid shift/reduce conflicts with the ParameterExpression rule */ { $$ = new Module_Param_List_Template(); $2->set_id(new Module_Param_Index($$->get_size(),false)); $$->add_elem($2); $$->add_list_with_implicit_ids($4); delete $4; } | ComplementKeyword '(' TemplateItemList ')' { $$ = new Module_Param_ComplementList_Template(); $$->add_list_with_implicit_ids($3); delete $3; } | SupersetKeyword '(' TemplateItemList ')' { $$ = new Module_Param_Superset_Template(); $$->add_list_with_implicit_ids($3); delete $3; } | SubsetKeyword '(' TemplateItemList ')' { $$ = new Module_Param_Subset_Template(); $$->add_list_with_implicit_ids($3); delete $3; } ; ParameterValueOrNotUsedSymbol: ParameterValue { $$ = $1; } | '-' { $$ = new Module_Param_NotUsed(); } ; TemplateItemList: ParameterValue { $$ = new Vector(); $$->push_back($1); } | TemplateItemList ',' ParameterValue { $$ = $1; $$->push_back($3); } ; FieldValueList: FieldValue { $$ = new Module_Param_Assignment_List(); $$->add_elem($1); } | FieldValueList ',' FieldValue { $$ = $1; $$->add_elem($3); } ; FieldValue: FieldName AssignmentChar ParameterValueOrNotUsedSymbol { $$ = $3; $$->set_id(new Module_Param_FieldName($1)); } ; FieldName: Identifier { $$ = $1; } | ASN1LowerIdentifier { $$ = $1; } ; ArrayItemList: ArrayItem { $$ = new Module_Param_Value_List(); $1->set_id(new Module_Param_Index($$->get_size(),false)); $$->add_elem($1); } | ArrayItemList ',' ArrayItem { $$ = $1; $3->set_id(new Module_Param_Index($$->get_size(),false)); $$->add_elem($3); } ; ArrayItem: ParameterValueOrNotUsedSymbol { $$ = $1; } | PermutationKeyword '(' TemplateItemList ')' { $$ = new Module_Param_Permutation_Template(); $$->add_list_with_implicit_ids($3); delete $3; } ; IndexItemList: IndexItem { $$ = new Module_Param_Indexed_List(); $$->add_elem($1); } | IndexItemList ',' IndexItem { $$ = $1; $$->add_elem($3); } ; IndexItem: IndexItemIndex AssignmentChar ParameterValue { $$ = $3; $$->set_id(new Module_Param_Index((size_t)$1,true)); } ; IndexItemIndex: '[' ParameterExpression ']' { $2->set_id(new Module_Param_CustomName(mcopystr("array index"))); INTEGER tmp; tmp.set_param(*$2); if (!tmp.get_val().is_native()) { config_process_error("bignum index."); // todo } if (tmp.get_val().is_negative()) { config_process_error("negative index."); // todo } $$ = tmp; delete $2; } ; /*************** [LOGGING] section *********************************/ LoggingSection: LoggingKeyword LoggingParamList ; LoggingParamList: /* empty */ | LoggingParamList LoggingParamLines optSemiColon { // Centralized duplication handling for `[LOGGING]'. if ($2.logparam.log_param_selection != LP_UNKNOWN && TTCN_Logger::add_parameter($2)) { switch ($2.logparam.log_param_selection) { case LP_FILEMASK: check_duplicate_option("LOGGING", "FileMask", file_mask_set); break; case LP_CONSOLEMASK: check_duplicate_option("LOGGING", "ConsoleMask", console_mask_set); break; case LP_LOGFILESIZE: check_duplicate_option("LOGGING", "LogFileSize", log_file_size_set); break; case LP_LOGFILENUMBER: check_duplicate_option("LOGGING", "LogFileNumber", log_file_number_set); break; case LP_DISKFULLACTION: check_duplicate_option("LOGGING", "DiskFullAction", log_disk_full_action_set); break; case LP_LOGFILE: check_duplicate_option("LOGGING", "LogFile", file_name_set); break; case LP_TIMESTAMPFORMAT: check_duplicate_option("LOGGING", "TimeStampFormat", timestamp_format_set); break; case LP_SOURCEINFOFORMAT: check_duplicate_option("LOGGING", "SourceInfoFormat", source_info_format_set); break; case LP_APPENDFILE: check_duplicate_option("LOGGING", "AppendFile", append_file_set); break; case LP_LOGEVENTTYPES: check_duplicate_option("LOGGING", "LogEventTypes", log_event_types_set); break; case LP_LOGENTITYNAME: check_duplicate_option("LOGGING", "LogEntityName", log_entity_name_set); break; case LP_MATCHINGHINTS: check_duplicate_option("LOGGING", "MatchingVerbosity", matching_verbosity_set); break; case LP_PLUGIN_SPECIFIC: // It would be an overkill to check for the infinite number of custom parameters... check_duplicate_option("LOGGING", "PluginSpecific", plugin_specific_set); break; default: break; } } } ; LoggingParamLines: LoggingParam { $$.component.id_selector = COMPONENT_ID_ALL; $$.component.id_name = NULL; $$.plugin_id = NULL; $$.logparam = $1; } | ComponentId '.' LoggingParam { $$.component = $1; $$.plugin_id = NULL; $$.logparam = $3; } | ComponentId '.' LoggerPluginId '.' LoggingParam { $$.component = $1; $$.plugin_id = $3; $$.logparam = $5; } | LoggerPlugins AssignmentChar '{' LoggerPluginList '}' { check_duplicate_option("LOGGING", "LoggerPlugins", logger_plugins_set); component_id_t comp; comp.id_selector = COMPONENT_ID_ALL; comp.id_name = NULL; logging_plugin_t *plugin = $4; while (plugin != NULL) { // `identifier' and `filename' are reused. Various checks and // validations must be done in the logger itself (e.g. looking for // duplicate options). TTCN_Logger::register_plugin(comp, plugin->identifier, plugin->filename); logging_plugin_t *tmp = plugin; plugin = tmp->next; Free(tmp); } $$.logparam.log_param_selection = LP_UNKNOWN; } | ComponentId '.' LoggerPlugins AssignmentChar '{' LoggerPluginList '}' { check_duplicate_option("LOGGING", "LoggerPlugins", logger_plugins_set); logging_plugin_t *plugin = $6; while (plugin != NULL) { TTCN_Logger::register_plugin($1, plugin->identifier, plugin->filename); logging_plugin_t *tmp = plugin; plugin = tmp->next; Free(tmp); } // Component names shall be duplicated in `register_plugin()'. if ($1.id_selector == COMPONENT_ID_NAME) Free($1.id_name); $$.logparam.log_param_selection = LP_UNKNOWN; } ; LoggerPluginList: LoggerPlugin { $$ = $1; } | LoggerPluginList ',' LoggerPlugin { $$ = $3; $$->next = $1; } ; LoggerPlugin: Identifier { $$ = (logging_plugin_t *)Malloc(sizeof(logging_plugin_t)); $$->identifier = $1; $$->filename = NULL; $$->next = NULL; } | Identifier AssignmentChar StringValue { $$ = (logging_plugin_t *)Malloc(sizeof(logging_plugin_t)); $$->identifier = $1; $$->filename = $3; $$->next = NULL; } ; LoggerPluginId: '*' { $$ = mcopystr("*"); } | Identifier { $$ = $1; } ; LoggingParam: FileMask AssignmentChar LoggingBitmask { $$.log_param_selection = LP_FILEMASK; $$.logoptions_val = $3; } | ConsoleMask AssignmentChar LoggingBitmask { $$.log_param_selection = LP_CONSOLEMASK; $$.logoptions_val = $3; } | LogFileSize AssignmentChar Number { $$.log_param_selection = LP_LOGFILESIZE; $$.int_val = (int)$3->get_val(); delete $3; } | EmergencyLogging AssignmentChar Number { $$.log_param_selection = LP_EMERGENCY; $$.int_val = (int)$3->get_val(); delete $3; } | EmergencyLoggingBehaviour AssignmentChar EmergencyLoggingBehaviourValue { $$.log_param_selection = LP_EMERGENCYBEHAVIOR; $$.emergency_logging_behaviour_value = $3; } | EmergencyLoggingMask AssignmentChar LoggingBitmask { $$.log_param_selection = LP_EMERGENCYMASK; $$.logoptions_val = $3; } | EmergencyLoggingForFailVerdict AssignmentChar YesNoOrBoolean { $$.log_param_selection = LP_EMERGENCYFORFAIL; $$.bool_val = $3; } | LogFileNumber AssignmentChar Number { $$.log_param_selection = LP_LOGFILENUMBER; $$.int_val = (int)$3->get_val(); delete $3; } | DiskFullAction AssignmentChar DiskFullActionValue { $$.log_param_selection = LP_DISKFULLACTION; $$.disk_full_action_value = $3; } | LogFile AssignmentChar LogFileName { $$.log_param_selection = LP_LOGFILE; $$.str_val = $3; } | TimestampFormat AssignmentChar TimestampValue { $$.log_param_selection = LP_TIMESTAMPFORMAT; $$.timestamp_value = $3; } | ConsoleTimestampFormat AssignmentChar TimestampValue { $$.log_param_selection = LP_UNKNOWN; } | SourceInfoFormat AssignmentChar SourceInfoSetting { $$.log_param_selection = LP_SOURCEINFOFORMAT; $$.source_info_value = $3; } | AppendFile AssignmentChar YesNoOrBoolean { $$.log_param_selection = LP_APPENDFILE; $$.bool_val = $3; } | LogEventTypes AssignmentChar LogEventTypesValue { $$.log_param_selection = LP_LOGEVENTTYPES; $$.log_event_types_value = $3; } | LogEntityName AssignmentChar YesNoOrBoolean { $$.log_param_selection = LP_LOGENTITYNAME; $$.bool_val = $3; } | MatchingHints AssignmentChar VerbosityValue { $$.log_param_selection = LP_MATCHINGHINTS; $$.matching_verbosity_value = $3; } | Identifier AssignmentChar StringValue { $$.log_param_selection = LP_PLUGIN_SPECIFIC; $$.param_name = $1; $$.str_val = $3; } ; VerbosityValue: Compact { $$ = TTCN_Logger::VERBOSITY_COMPACT; } | Detailed { $$ = TTCN_Logger::VERBOSITY_FULL; } ; DiskFullActionValue: Error { $$.type = TTCN_Logger::DISKFULL_ERROR; } | Stop { $$.type = TTCN_Logger::DISKFULL_STOP; } | Retry { $$.type = TTCN_Logger::DISKFULL_RETRY; $$.retry_interval = 30; /* default retry interval */ } | Retry '(' Number ')' { $$.type = TTCN_Logger::DISKFULL_RETRY; $$.retry_interval = (size_t)$3->get_val(); delete $3; } | Delete { $$.type = TTCN_Logger::DISKFULL_DELETE; } ; LogFileName: StringValue { $$ = $1; } ; LoggingBitOrCollection: LoggingBit { $$.clear(); $$.add_sev($1); } | LoggingBitCollection { $$.clear(); switch($1) { case TTCN_Logger::ACTION_UNQUALIFIED: $$.add_sev(TTCN_Logger::ACTION_UNQUALIFIED); break; case TTCN_Logger::DEFAULTOP_UNQUALIFIED: $$.add_sev(TTCN_Logger::DEFAULTOP_ACTIVATE); $$.add_sev(TTCN_Logger::DEFAULTOP_DEACTIVATE); $$.add_sev(TTCN_Logger::DEFAULTOP_EXIT); $$.add_sev(TTCN_Logger::DEFAULTOP_UNQUALIFIED); break; case TTCN_Logger::ERROR_UNQUALIFIED: $$.add_sev(TTCN_Logger::ERROR_UNQUALIFIED); break; case TTCN_Logger::EXECUTOR_UNQUALIFIED: $$.add_sev(TTCN_Logger::EXECUTOR_RUNTIME); $$.add_sev(TTCN_Logger::EXECUTOR_CONFIGDATA); $$.add_sev(TTCN_Logger::EXECUTOR_EXTCOMMAND); $$.add_sev(TTCN_Logger::EXECUTOR_COMPONENT); $$.add_sev(TTCN_Logger::EXECUTOR_LOGOPTIONS); $$.add_sev(TTCN_Logger::EXECUTOR_UNQUALIFIED); break; case TTCN_Logger::FUNCTION_UNQUALIFIED: $$.add_sev(TTCN_Logger::FUNCTION_RND); $$.add_sev(TTCN_Logger::FUNCTION_UNQUALIFIED); break; case TTCN_Logger::PARALLEL_UNQUALIFIED: $$.add_sev(TTCN_Logger::PARALLEL_PTC); $$.add_sev(TTCN_Logger::PARALLEL_PORTCONN); $$.add_sev(TTCN_Logger::PARALLEL_PORTMAP); $$.add_sev(TTCN_Logger::PARALLEL_UNQUALIFIED); break; case TTCN_Logger::PORTEVENT_UNQUALIFIED: $$.add_sev(TTCN_Logger::PORTEVENT_PQUEUE); $$.add_sev(TTCN_Logger::PORTEVENT_MQUEUE); $$.add_sev(TTCN_Logger::PORTEVENT_STATE); $$.add_sev(TTCN_Logger::PORTEVENT_PMIN); $$.add_sev(TTCN_Logger::PORTEVENT_PMOUT); $$.add_sev(TTCN_Logger::PORTEVENT_PCIN); $$.add_sev(TTCN_Logger::PORTEVENT_PCOUT); $$.add_sev(TTCN_Logger::PORTEVENT_MMRECV); $$.add_sev(TTCN_Logger::PORTEVENT_MMSEND); $$.add_sev(TTCN_Logger::PORTEVENT_MCRECV); $$.add_sev(TTCN_Logger::PORTEVENT_MCSEND); $$.add_sev(TTCN_Logger::PORTEVENT_DUALRECV); $$.add_sev(TTCN_Logger::PORTEVENT_DUALSEND); $$.add_sev(TTCN_Logger::PORTEVENT_UNQUALIFIED); break; case TTCN_Logger::TESTCASE_UNQUALIFIED: $$.add_sev(TTCN_Logger::TESTCASE_START); $$.add_sev(TTCN_Logger::TESTCASE_FINISH); $$.add_sev(TTCN_Logger::TESTCASE_UNQUALIFIED); break; case TTCN_Logger::TIMEROP_UNQUALIFIED: $$.add_sev(TTCN_Logger::TIMEROP_READ); $$.add_sev(TTCN_Logger::TIMEROP_START); $$.add_sev(TTCN_Logger::TIMEROP_GUARD); $$.add_sev(TTCN_Logger::TIMEROP_STOP); $$.add_sev(TTCN_Logger::TIMEROP_TIMEOUT); $$.add_sev(TTCN_Logger::TIMEROP_UNQUALIFIED); break; case TTCN_Logger::USER_UNQUALIFIED: $$.add_sev(TTCN_Logger::USER_UNQUALIFIED); break; case TTCN_Logger::STATISTICS_UNQUALIFIED: $$.add_sev(TTCN_Logger::STATISTICS_VERDICT); $$.add_sev(TTCN_Logger::STATISTICS_UNQUALIFIED); break; case TTCN_Logger::VERDICTOP_UNQUALIFIED: $$.add_sev(TTCN_Logger::VERDICTOP_GETVERDICT); $$.add_sev(TTCN_Logger::VERDICTOP_SETVERDICT); $$.add_sev(TTCN_Logger::VERDICTOP_FINAL); $$.add_sev(TTCN_Logger::VERDICTOP_UNQUALIFIED); break; case TTCN_Logger::WARNING_UNQUALIFIED: $$.add_sev(TTCN_Logger::WARNING_UNQUALIFIED); break; case TTCN_Logger::MATCHING_UNQUALIFIED: $$.add_sev(TTCN_Logger::MATCHING_DONE); $$.add_sev(TTCN_Logger::MATCHING_TIMEOUT); $$.add_sev(TTCN_Logger::MATCHING_PCSUCCESS); $$.add_sev(TTCN_Logger::MATCHING_PCUNSUCC); $$.add_sev(TTCN_Logger::MATCHING_PMSUCCESS); $$.add_sev(TTCN_Logger::MATCHING_PMUNSUCC); $$.add_sev(TTCN_Logger::MATCHING_MCSUCCESS); $$.add_sev(TTCN_Logger::MATCHING_MCUNSUCC); $$.add_sev(TTCN_Logger::MATCHING_MMSUCCESS); $$.add_sev(TTCN_Logger::MATCHING_MMUNSUCC); $$.add_sev(TTCN_Logger::MATCHING_PROBLEM); $$.add_sev(TTCN_Logger::MATCHING_UNQUALIFIED); break; case TTCN_Logger::DEBUG_UNQUALIFIED: $$.add_sev(TTCN_Logger::DEBUG_ENCDEC); $$.add_sev(TTCN_Logger::DEBUG_TESTPORT); $$.add_sev(TTCN_Logger::DEBUG_USER); $$.add_sev(TTCN_Logger::DEBUG_FRAMEWORK); $$.add_sev(TTCN_Logger::DEBUG_UNQUALIFIED); break; case TTCN_Logger::LOG_ALL_IMPORTANT: $$ = Logging_Bits::log_all; break; default: /* The lexer sent something the parser doesn't understand! Parser needs to be updated. */ TTCN_Logger::log_str(TTCN_Logger::ERROR_UNQUALIFIED, "Internal error: unknown logbit from lexer."); break; } // switch } ; LoggingBitmask: LoggingBitOrCollection { $$ = $1; } | LoggingBitmask '|' LoggingBitOrCollection { $$ = $1; $$.merge($3); } ; SourceInfoSetting: SourceInfoValue { $$ = $1; } | YesNoOrBoolean { $$ = $1 ? TTCN_Logger::SINFO_SINGLE : TTCN_Logger::SINFO_NONE; } ; YesNoOrBoolean: YesNo { $$ = $1; } | BooleanValue { $$ = $1; } ; LogEventTypesValue: YesNoOrBoolean { $$ = $1 ? TTCN_Logger::LOGEVENTTYPES_YES : TTCN_Logger::LOGEVENTTYPES_NO; } | SubCategories { $$ = TTCN_Logger::LOGEVENTTYPES_SUBCATEGORIES; } | Detailed { $$ = TTCN_Logger::LOGEVENTTYPES_SUBCATEGORIES; } ; /*********************** [PROFILER] ********************************/ ProfilerSection: ProfilerKeyword ProfilerSettings ; ProfilerSettings: /* empty */ | ProfilerSettings ProfilerSetting optSemiColon ; ProfilerSetting: DisableProfilerSetting | DisableCoverageSetting | DatabaseFileSetting | AggregateDataSetting | StatisticsFileSetting | DisableStatisticsSetting | StatisticsFilterSetting | StartAutomaticallySetting | NetLineTimesSetting | NetFunctionTimesSetting ; DisableProfilerSetting: DisableProfilerKeyword AssignmentChar BooleanValue { ttcn3_prof.set_disable_profiler($3); } ; DisableCoverageSetting: DisableCoverageKeyword AssignmentChar BooleanValue { ttcn3_prof.set_disable_coverage($3); } ; DatabaseFileSetting: DatabaseFileKeyword AssignmentChar StringValue { ttcn3_prof.set_database_filename($3); } ; AggregateDataSetting: AggregateDataKeyword AssignmentChar BooleanValue { ttcn3_prof.set_aggregate_data($3); } ; StatisticsFileSetting: StatisticsFileKeyword AssignmentChar StringValue { ttcn3_prof.set_stats_filename($3); } ; DisableStatisticsSetting: DisableStatisticsKeyword AssignmentChar BooleanValue { ttcn3_prof.set_disable_stats($3); } ; StatisticsFilterSetting: StatisticsFilterKeyword AssignmentChar ProfilerStatsFlags { ttcn3_prof.reset_stats_flags(); ttcn3_prof.add_stats_flags($3); } | StatisticsFilterKeyword ConcatChar ProfilerStatsFlags { ttcn3_prof.add_stats_flags($3); } ; ProfilerStatsFlags: ProfilerStatsFlag { $$ = $1; } | ProfilerStatsFlag '&' ProfilerStatsFlags { $$ = $1 | $3; } | ProfilerStatsFlag '|' ProfilerStatsFlags { $$ = $1 | $3; } ; StartAutomaticallySetting: StartAutomaticallyKeyword AssignmentChar BooleanValue { if ($3) { ttcn3_prof.start(); } else { ttcn3_prof.stop(); } } ; NetLineTimesSetting: NetLineTimesKeyword AssignmentChar BooleanValue { TTCN3_Stack_Depth::set_net_line_times($3); } ; NetFunctionTimesSetting: NetFunctionTimesKeyword AssignmentChar BooleanValue { TTCN3_Stack_Depth::set_net_func_times($3); } ; /**************** [TESTPORT_PARAMETERS] ****************************/ TestportParametersSection: TestportParametersKeyword TestportParameterList ; TestportParameterList: /* empty */ | TestportParameterList TestportParameter optSemiColon ; TestportParameter: ComponentId '.' TestportName '.' TestportParameterName AssignmentChar TestportParameterValue { PORT::add_parameter($1, $3, $5, $7); if ($1.id_selector == COMPONENT_ID_NAME) Free($1.id_name); Free($3); Free($5); Free($7); } ; ComponentId: Identifier { $$.id_selector = COMPONENT_ID_NAME; $$.id_name = $1; } | Cstring { $$.id_selector = COMPONENT_ID_NAME; $$.id_name = $1.chars_ptr; } | Number { $$.id_selector = COMPONENT_ID_COMPREF; $$.id_compref = (component)$1->get_val(); delete $1; } | MTCKeyword { $$.id_selector = COMPONENT_ID_COMPREF; $$.id_compref = MTC_COMPREF; } | '*' { $$.id_selector = COMPONENT_ID_ALL; $$.id_name = NULL; } | SystemKeyword { $$.id_selector = COMPONENT_ID_SYSTEM; $$.id_name = NULL; } ; TestportName: Identifier { $$ = $1; } | Identifier ArrayRef { $$ = mputstr($1, $2); Free($2); } | '*' { $$ = NULL; } ; ArrayRef: '[' IntegerValue ']' { char *s = $2->as_string(); $$ = memptystr(); $$ = mputc ($$, '['); $$ = mputstr($$, s); $$ = mputc ($$, ']'); Free(s); delete $2; } | ArrayRef '[' IntegerValue ']' { char *s = $3->as_string(); $$ = mputc ($1, '['); $$ = mputstr($$, s); $$ = mputc ($$, ']'); Free(s); delete $3; } ; TestportParameterName: Identifier { $$ = $1; } ; TestportParameterValue: StringValue { $$ = $1; } ; /****************** [EXECUTE] section *************/ ExecuteSection: ExecuteKeyword ExecuteList { if (!TTCN_Runtime::is_single()) config_process_error("Internal error: " "the Main Controller must not send section [EXECUTE] of the " "configuration file."); } ; ExecuteList: /* empty */ | ExecuteList ExecuteItem optSemiColon { if (TTCN_Runtime::is_single()) { execute_list = (execute_list_item *)Realloc( execute_list, (execute_list_len + 1) * sizeof(*execute_list)); execute_list[execute_list_len++] = $2; } else { Free($2.module_name); Free($2.testcase_name); } } ; ExecuteItem: Identifier { $$.module_name = $1; $$.testcase_name = NULL; } | Identifier '.' ControlKeyword { $$.module_name = $1; $$.testcase_name = NULL; } | Identifier '.' Identifier { $$.module_name = $1; $$.testcase_name = $3; } | Identifier '.' '*' { $$.module_name = $1; $$.testcase_name = mcopystr("*"); } ; /****************** [EXTERNAL_COMMANDS] section **********************/ ExternalCommandsSection: ExternalCommandsKeyword ExternalCommandList ; ExternalCommandList: /* empty */ | ExternalCommandList ExternalCommand optSemiColon ; ExternalCommand: BeginControlPart AssignmentChar Command { check_duplicate_option("EXTERNAL_COMMANDS", "BeginControlPart", begin_controlpart_command_set); TTCN_Runtime::set_begin_controlpart_command($3); Free($3); } | EndControlPart AssignmentChar Command { check_duplicate_option("EXTERNAL_COMMANDS", "EndControlPart", end_controlpart_command_set); TTCN_Runtime::set_end_controlpart_command($3); Free($3); } | BeginTestCase AssignmentChar Command { check_duplicate_option("EXTERNAL_COMMANDS", "BeginTestCase", begin_testcase_command_set); TTCN_Runtime::set_begin_testcase_command($3); Free($3); } | EndTestCase AssignmentChar Command { check_duplicate_option("EXTERNAL_COMMANDS", "EndTestCase", end_testcase_command_set); TTCN_Runtime::set_end_testcase_command($3); Free($3); } ; Command: StringValue { $$ = $1; } ; /***************** [GROUPS] section *******************/ GroupsSection: GroupsKeyword GroupList { check_ignored_section("GROUPS"); } ; GroupList: /* empty */ | GroupList Group optSemiColon ; Group: GroupName AssignmentChar GroupMembers ; GroupName: Identifier { Free($1); } ; GroupMembers: '*' | seqGroupMember ; seqGroupMember: HostName | seqGroupMember ',' HostName ; HostName: DNSName | Identifier { Free($1); } ; /******************** [COMPONENTS] section *******************/ ComponentsSection: ComponentsKeyword ComponentList { check_ignored_section("COMPONENTS"); } ; ComponentList: /* empty */ | ComponentList ComponentItem optSemiColon ; ComponentItem: ComponentName AssignmentChar ComponentLocation ; ComponentName: Identifier { Free($1); } | '*' ; ComponentLocation: Identifier { Free($1); } | DNSName ; /****************** [MAIN_CONTROLLER] section *********************/ MainControllerSection: MainControllerKeyword MCParameterList { check_ignored_section("MAIN_CONTROLLER"); } ; MCParameterList: /* empty */ | MCParameterList MCParameter optSemiColon ; MCParameter: LocalAddress AssignmentChar HostName { } | TCPPort AssignmentChar IntegerValue { delete $3; } | KillTimer AssignmentChar KillTimerValue { } | NumHCs AssignmentChar IntegerValue { delete $3; } | UnixSocketEnabled AssignmentChar YesToken {} | UnixSocketEnabled AssignmentChar NoToken {} | UnixSocketEnabled AssignmentChar HostName {} ; KillTimerValue: FloatValue { } | IntegerValue { delete $1; } ; /****************** [INCLUDE] section *********************/ IncludeSection: IncludeKeyword IncludeFiles { if(!TTCN_Runtime::is_single()) config_process_error ("Internal error: the Main Controller must not send section [INCLUDE]" " of the configuration file."); } ; IncludeFiles: /* empty */ | IncludeFiles IncludeFile ; IncludeFile: Cstring { Free($1.chars_ptr); } ; /****************** [DEFINE] section *********************/ DefineSection: DefineKeyword { if(!TTCN_Runtime::is_single()) config_process_error ("Internal error: the Main Controller must not send section [DEFINE]" " of the configuration file."); } ; /*********************************************************/ ParamOpType: AssignmentChar { $$ = Module_Param::OT_ASSIGN; } | ConcatChar { $$ = Module_Param::OT_CONCAT; } ; optSemiColon: /* empty */ | ';' ; %% static void reset_configuration_options() { /* Section [MODULE_PARAMETERS */ /** \todo reset module parameters to their default values */ /* Section [LOGGING] */ TTCN_Logger::close_file(); TTCN_Logger::reset_configuration(); file_name_set = FALSE; file_mask_set = TRUE; console_mask_set = TRUE; timestamp_format_set = FALSE; source_info_format_set = FALSE; append_file_set = FALSE; log_event_types_set = FALSE; log_entity_name_set = FALSE; /* Section [TESTPORT_PARAMETERS] */ PORT::clear_parameters(); /* Section [EXTERNAL_COMMANDS] */ TTCN_Runtime::clear_external_commands(); begin_controlpart_command_set = FALSE; end_controlpart_command_set = FALSE; begin_testcase_command_set = FALSE; end_testcase_command_set = FALSE; } Module_Param* process_config_string2ttcn(const char* mp_str, bool is_component) { if (parsed_module_param!=NULL || parsing_error_messages!=NULL) TTCN_error("Internal error: previously parsed ttcn string was not cleared."); // add the hidden keyword std::string mp_string = (is_component) ? std::string("$#&&&(#TTCNSTRINGPARSING_COMPONENT$#&&^#% ") + mp_str : std::string("$#&&&(#TTCNSTRINGPARSING$#&&^#% ") + mp_str; struct yy_buffer_state *flex_buffer = config_process__scan_bytes(mp_string.c_str(), (int)mp_string.size()); if (flex_buffer == NULL) TTCN_error("Internal error: flex buffer creation failed."); reset_config_process_lex(NULL); error_flag = FALSE; try { Ttcn_String_Parsing ttcn_string_parsing; if (config_process_parse()) error_flag = TRUE; } catch (const TC_Error& TC_error) { if (parsed_module_param!=NULL) { delete parsed_module_param; parsed_module_param = NULL; } error_flag = TRUE; } config_process_close(); config_process_lex_destroy(); if (error_flag || parsing_error_messages!=NULL) { delete parsed_module_param; parsed_module_param = NULL; char* pem = parsing_error_messages!=NULL ? parsing_error_messages : mcopystr("Unknown parsing error"); parsing_error_messages = NULL; TTCN_error_begin("%s", pem); Free(pem); TTCN_error_end(); return NULL; } else { if (parsed_module_param==NULL) TTCN_error("Internal error: could not parse ttcn string."); Module_Param* ret_val = parsed_module_param; parsed_module_param = NULL; return ret_val; } } boolean process_config_string(const char *config_string, int string_len) { error_flag = FALSE; struct yy_buffer_state *flex_buffer = config_process__scan_bytes(config_string, string_len); if (flex_buffer == NULL) { TTCN_Logger::log_str(TTCN_Logger::ERROR_UNQUALIFIED, "Internal error: flex buffer creation failed."); return FALSE; } try { reset_configuration_options(); reset_config_process_lex(NULL); if (config_process_parse()) error_flag = TRUE; } catch (const TC_Error& TC_error) { error_flag = TRUE; } config_process_close(); config_process_lex_destroy(); return !error_flag; } boolean process_config_file(const char *file_name) { error_flag = FALSE; string_chain_t *filenames=NULL; reset_configuration_options(); if(preproc_parse_file(file_name, &filenames, &config_defines)) error_flag=TRUE; while(filenames) { char *fn=string_chain_cut(&filenames); reset_config_process_lex(fn); /* The lexer can modify config_process_in * when it's input buffer is changed */ config_process_in = fopen(fn, "r"); FILE* tmp_cfg = config_process_in; if (config_process_in != NULL) { try { if(config_process_parse()) error_flag=TRUE; } catch (const TC_Error& TC_error) { error_flag=TRUE; } fclose(tmp_cfg); config_process_close(); config_process_lex_destroy(); } else { TTCN_Logger::begin_event(TTCN_Logger::ERROR_UNQUALIFIED); TTCN_Logger::log_event("Cannot open configuration file: %s", fn); TTCN_Logger::OS_error(); TTCN_Logger::end_event(); error_flag=TRUE; } /* During parsing flex or libc may use some system calls (e.g. ioctl) * that fail with an error status. Such error codes shall be ignored in * future error messages. */ errno = 0; Free(fn); } string_map_free(config_defines); config_defines = NULL; return !error_flag; } void config_process_error_f(const char *error_str, ...) { if (Ttcn_String_Parsing::happening()) { va_list p_var; va_start(p_var, error_str); char* error_msg_str = mprintf_va_list(error_str, p_var); va_end(p_var); if (parsing_error_messages!=NULL) parsing_error_messages = mputc(parsing_error_messages, '\n'); parsing_error_messages = mputprintf(parsing_error_messages, "Parse error in line %d, at or before token `%s': %s", config_process_get_current_line(), config_process_text, error_msg_str); Free(error_msg_str); error_flag = TRUE; return; } TTCN_Logger::begin_event(TTCN_Logger::ERROR_UNQUALIFIED); if (!get_cfg_process_current_file().empty()) { TTCN_Logger::log_event("Parse error in configuration file `%s': in line %d, " "at or before token `%s': ", get_cfg_process_current_file().c_str(), config_process_get_current_line(), config_process_text ); } else { TTCN_Logger::log_event("Parse error while reading configuration " "information: in line %d, at or before token `%s': ", config_process_get_current_line(), config_process_text); } va_list pvar; va_start(pvar, error_str); TTCN_Logger::log_event_va_list(error_str, pvar); va_end(pvar); TTCN_Logger::end_event(); error_flag = TRUE; } void config_process_error(const char *error_str) { config_process_error_f("%s", error_str); } void config_preproc_error(const char *error_str, ...) { TTCN_Logger::begin_event(TTCN_Logger::ERROR_UNQUALIFIED); TTCN_Logger::log_event("Parse error while pre-processing configuration" " file `%s': in line %d: ", get_cfg_preproc_current_file().c_str(), config_preproc_yylineno); va_list pvar; va_start(pvar, error_str); TTCN_Logger::log_event_va_list(error_str, pvar); va_end(pvar); TTCN_Logger::end_event(); error_flag = TRUE; } void path_error(const char *fmt, ...) { va_list parameters; fprintf(stderr, "File error: "); va_start(parameters, fmt); vfprintf(stderr, fmt, parameters); va_end(parameters); fprintf(stderr, "\n"); } static void check_duplicate_option(const char *section_name, const char *option_name, boolean& option_flag) { if (option_flag) { TTCN_warning("Option `%s' was given more than once in section [%s] of the " "configuration file.", option_name, section_name); } else option_flag = TRUE; } static void check_ignored_section(const char *section_name) { if (TTCN_Runtime::is_single()) TTCN_warning("Section [%s] of " "configuration file is ignored in single mode.", section_name); else config_process_error_f("Internal error: the Main Controller must not " "send section [%s] of the configuration file.", section_name); } static void set_param(Module_Param& param) { try { Module_List::set_param(param); } catch (const TC_Error& TC_error) { error_flag = TRUE; } } unsigned char char_to_hexdigit(char c) { if (c >= '0' && c <= '9') return c - '0'; else if (c >= 'A' && c <= 'F') return c - 'A' + 10; else if (c >= 'a' && c <= 'f') return c - 'a' + 10; else { config_process_error_f("char_to_hexdigit(): invalid argument: %c", c); return 0; // to avoid warning } }