From a38c6d4c92d78d84a8c44543ee3a890e50432e35 Mon Sep 17 00:00:00 2001 From: erititan <elemer.lelik@ericsson.com> Date: Fri, 22 May 2015 10:58:38 +0200 Subject: [PATCH] Sync with 5.3.0 --- common/version.h | 4 +- compiler2/AST.cc | 47 +- compiler2/Setting.cc | 31 +- compiler2/Type.cc | 81 +- compiler2/Type.hh | 6 +- compiler2/Type_codegen.cc | 63 +- compiler2/Value.cc | 26 +- compiler2/Value.hh | 6 +- compiler2/compiler.1 | 7 + compiler2/datatypes.h | 2 + compiler2/main.cc | 66 +- compiler2/main.hh | 3 +- compiler2/record.c | 39 +- compiler2/record_of.c | 387 ++-- compiler2/subtype.cc | 3 + compiler2/ttcn3/AST_ttcn3.cc | 2046 +++++++++-------- compiler2/ttcn3/Makefile | 2 +- compiler2/ttcn3/Statement.cc | 56 +- compiler2/ttcn3/Statement.hh | 9 +- compiler2/ttcn3/TtcnTemplate.cc | 37 +- compiler2/ttcn3/compiler.c | 5 +- compiler2/ttcn3/compiler.l | 1 + compiler2/ttcn3/compiler.y | 41 +- compiler2/ttcn3/profiler.c | 126 + compiler2/ttcn3/profiler.h | 74 + core/ASN_CharacterString.cc | 26 +- core/ASN_EmbeddedPDV.cc | 26 +- core/ASN_External.cc | 8 +- core/Array.hh | 36 +- core/Basetype.cc | 64 +- core/Basetype.hh | 14 +- core/Component.cc | 38 +- core/Float.cc | 65 +- core/Float.hh | 4 + core/Makefile | 24 +- core/Module_list.cc | 2 - core/Optional.hh | 32 +- core/Parallel_main.cc | 18 +- core/PreGenRecordOf.ttcn | 83 + core/Profiler.cc | 1549 ++++++++++--- core/Profiler.hh | 133 +- core/RAW.cc | 4 +- core/RefdIndex.hh | 55 + core/Runtime.cc | 5 + core/Single_main.cc | 20 +- core/Snapshot.cc | 1 + core/TEXT.cc | 3 + core/TEXT.hh | 1 + core/TTCN3.hh | 3 + core/Template.hh | 13 +- core/Universal_charstring.cc | 241 +- core/Universal_charstring.hh | 4 + core/XER.hh | 26 +- core/config_process.l | 191 +- core/config_process.y | 64 +- core2/Basetype2.cc | 73 +- etc/xsd/TXD.xsd | 174 -- .../BER_EncDec/BER_EncDec_TD.fast_script | 6 +- .../Config_Parser/Logging_1_TD.script | 6 +- .../Config_Parser/OrderedInclude.script | 4 +- .../PreprocessingCfgFiles_TD.script | 6 +- .../RAW_EncDec/RAW_EncDec_TD.fast_script | 4 +- .../Semantic_Analyser/ASN_SA_1_TD.script | 6 +- .../ASN_SA_asn1adhoc_TD.script | 6 +- .../Semantic_Analyser/TTCN3_SA_10_TD.script | 6 +- .../Semantic_Analyser/TTCN3_SA_11_TD.script | 6 +- .../TTCN3_SA_12_TD.script_not_running | 4 +- .../Semantic_Analyser/TTCN3_SA_13_TD.script | 4 +- .../Semantic_Analyser/TTCN3_SA_1_TD.script | 6 +- .../Semantic_Analyser/TTCN3_SA_3_TD.script | 8 +- .../Semantic_Analyser/TTCN3_SA_4_TD.script | 4 +- .../Semantic_Analyser/TTCN3_SA_5_TD.script | 6 +- .../Semantic_Analyser/TTCN3_SA_6_TD.script | 12 +- .../Semantic_Analyser/TTCN3_SA_7_TD.script | 4 +- .../Semantic_Analyser/TTCN3_SA_9_TD.script | 13 +- .../TTCN3_SA_ttcn3adhoc_TD.script | 142 +- .../Text_EncDec/TEXT_1_TD.fast_script | 4 +- function_test/Tools/SAtester | 9 +- function_test/XER_EncDec/XER_EncDec_TD.script | 18 +- .../doc/TTCN3_Executor_TestReport.doc | Bin 1091072 -> 1106432 bytes help/Makefile | 10 +- help/info/on.html | 2 +- help/info/operators.html | 4 +- help/info/optional.html | 2 +- help/info/procedure.html | 2 +- help/info/profiler.html | 134 ++ help/info/public.html | 2 +- help/info/running.html | 28 +- help/info/start.html | 14 +- help/info/stop.html | 22 +- help/titan_index.html | 17 +- help/titan_main.html | 4 +- loggerplugins/JUnitLogger2/JUnitLogger2.cc | 346 +++ loggerplugins/JUnitLogger2/JUnitLogger2.hh | 119 + loggerplugins/JUnitLogger2/Makefile | 96 + loggerplugins/Makefile | 2 +- loggerplugins/TSTLogger/TSTLogger.cc | 1 + mctr2/cli/config_read.l | 63 +- mctr2/cli/config_read.y | 44 +- mctr2/mctr/MainController.cc | 2 + mctr2/mctr/ttcn3_start | 5 +- regression_test/Makefile | 2 +- .../XML/EXER-whitepaper/EmbedValues.ttcnpp | 96 +- regression_test/XML/TTCNandXML/Makefile | 2 +- regression_test/XML/XER/checkit.pl | 1 + .../all_from/all_from_subtype.ttcn | 191 ++ .../all_from/all_from_with_functions.ttcn | 44 +- regression_test/all_from/types.ttcn | 44 + regression_test/boolOper/TboolOper.ttcn | 55 + .../assignment/assignment.cfg | 4 +- .../assignment/assignment.ttcn | 16 +- regression_test/compileonly/Makefile | 2 +- .../compileonly/selectCase/Makefile | 41 + .../compileonly/selectCase/selectCase.ttcn | 76 + regression_test/negativeTest/Makefile | 2 +- regression_test/profiler/Makefile | 82 + regression_test/profiler/PIPEasp_PT.cc | 738 ++++++ regression_test/profiler/PIPEasp_PT.hh | 106 + .../profiler/PIPEasp_PortType.ttcn | 46 + .../profiler/PIPEasp_Templates.ttcn | 93 + regression_test/profiler/PIPEasp_Types.ttcn | 180 ++ regression_test/profiler/Shell.ttcn | 244 ++ regression_test/profiler/Testcases.ttcn | 74 + regression_test/profiler/data_e.json | 226 ++ regression_test/profiler/empty_e.stats | 5 + regression_test/profiler/prof1.cfg | 22 + regression_test/profiler/prof1.ttcn | 30 + regression_test/profiler/prof1_e.stats | 84 + regression_test/profiler/prof2.cfg | 20 + regression_test/profiler/prof2.ttcn | 36 + regression_test/profiler/prof3.cfg | 22 + regression_test/profiler/prof3.ttcn | 35 + regression_test/profiler/prof_files.txt | 3 + regression_test/recofOper/Makefile | 2 +- regression_test/recofOper/TrecofCompat.ttcn | 262 +++ regression_test/recofOper/TrecofParamRef.ttcn | 28 + regression_test/recofOper/config.cfg | 1 + regression_test/recofOper/config_rt2.cfg | 1 + regression_test/testcase_defparam/Makefile | 2 +- .../ucharstrOper/cstr_content.ttcn | 36 + .../doc/Titan_Executor_API_User_Guide.doc | Bin 64512 -> 64512 bytes usrguide/PRI.doc | Bin 83456 -> 84480 bytes usrguide/apiguide.doc | Bin 564224 -> 555520 bytes usrguide/installationguide.doc | Bin 118272 -> 118272 bytes usrguide/referenceguide.doc | Bin 1541120 -> 1615360 bytes usrguide/releasenotes.doc | Bin 572416 -> 581120 bytes usrguide/userguide.doc | Bin 849408 -> 847872 bytes 147 files changed, 8087 insertions(+), 2238 deletions(-) create mode 100644 compiler2/ttcn3/profiler.c create mode 100644 compiler2/ttcn3/profiler.h create mode 100644 core/PreGenRecordOf.ttcn create mode 100644 core/RefdIndex.hh delete mode 100644 etc/xsd/TXD.xsd create mode 100644 help/info/profiler.html create mode 100644 loggerplugins/JUnitLogger2/JUnitLogger2.cc create mode 100644 loggerplugins/JUnitLogger2/JUnitLogger2.hh create mode 100644 loggerplugins/JUnitLogger2/Makefile create mode 100644 regression_test/all_from/all_from_subtype.ttcn create mode 100644 regression_test/compileonly/selectCase/Makefile create mode 100644 regression_test/compileonly/selectCase/selectCase.ttcn create mode 100755 regression_test/profiler/Makefile create mode 100644 regression_test/profiler/PIPEasp_PT.cc create mode 100644 regression_test/profiler/PIPEasp_PT.hh create mode 100644 regression_test/profiler/PIPEasp_PortType.ttcn create mode 100644 regression_test/profiler/PIPEasp_Templates.ttcn create mode 100644 regression_test/profiler/PIPEasp_Types.ttcn create mode 100644 regression_test/profiler/Shell.ttcn create mode 100644 regression_test/profiler/Testcases.ttcn create mode 100644 regression_test/profiler/data_e.json create mode 100644 regression_test/profiler/empty_e.stats create mode 100644 regression_test/profiler/prof1.cfg create mode 100644 regression_test/profiler/prof1.ttcn create mode 100644 regression_test/profiler/prof1_e.stats create mode 100644 regression_test/profiler/prof2.cfg create mode 100644 regression_test/profiler/prof2.ttcn create mode 100644 regression_test/profiler/prof3.cfg create mode 100644 regression_test/profiler/prof3.ttcn create mode 100644 regression_test/profiler/prof_files.txt create mode 100644 regression_test/recofOper/TrecofCompat.ttcn diff --git a/common/version.h b/common/version.h index a72a783c6..5ee284291 100644 --- a/common/version.h +++ b/common/version.h @@ -10,7 +10,7 @@ /* Version numbers */ #define TTCN3_MAJOR 5 -#define TTCN3_MINOR 2 +#define TTCN3_MINOR 3 #define TTCN3_PATCHLEVEL 0 //#define TTCN3_BUILDNUMBER 0 @@ -22,7 +22,7 @@ * TTCN3_VERSION = TTCN3_MAJOR * 1000000 + TTCN3_MINOR * 10000 + * TTCN3_PATCHLEVEL * 100 + TTCN3_BUILDNUMBER */ -#define TTCN3_VERSION 50200 +#define TTCN3_VERSION 50300 /* A monotonically increasing version number. * An official release is deemed to have the highest possible build number (99) diff --git a/compiler2/AST.cc b/compiler2/AST.cc index 4cfcad260..202d282f2 100644 --- a/compiler2/AST.cc +++ b/compiler2/AST.cc @@ -23,6 +23,7 @@ #include "../common/version.h" #include "CodeGenHelper.hh" #include <limits.h> +#include "ttcn3/profiler.h" reffer::reffer(const char*) {} @@ -774,7 +775,9 @@ namespace Common { } // pre_init function bool has_pre_init = false; - if (output->functions.pre_init) { + bool profiled = MOD_TTCN == get_moduletype() && is_file_profiled(get_filename()); + // always generate pre_init_module if the file is profiled + if (output->functions.pre_init || profiled) { output->source.static_function_prototypes = mputstr(output->source.static_function_prototypes, "static void pre_init_module();\n"); @@ -800,11 +803,11 @@ namespace Common { mputprintf(effective_module_functions, "%s\"%s\"", (effective_module_functions ? ", " : ""), get_modid().get_dispname().c_str()); } - if (profiler_enabled && MOD_TTCN == get_moduletype()) { + if (profiled) { output->source.static_function_bodies = mputprintf(output->source.static_function_bodies, + "%s::init_ttcn3_profiler();\n" "TTCN3_Stack_Depth stack_depth;\n" - "ttcn3_prof.enter_function(\"%s\", 0, \"%s\");\n", - get_filename(), get_modid().get_dispname().c_str()); + "ttcn3_prof.execute_line(\"%s\", 0);\n", get_modid().get_name().c_str(), get_filename()); } } output->source.static_function_bodies = @@ -843,11 +846,10 @@ namespace Common { mputprintf(effective_module_functions, "%s\"%s\"", (effective_module_functions ? ", " : ""), get_modid().get_dispname().c_str()); } - if (profiler_enabled && MOD_TTCN == get_moduletype()) { + if (MOD_TTCN == get_moduletype() && is_file_profiled(get_filename())) { output->source.static_function_bodies = mputprintf(output->source.static_function_bodies, "TTCN3_Stack_Depth stack_depth;\n" - "ttcn3_prof.enter_function(\"%s\", 0, \"%s\");\n", - get_filename(), get_modid().get_dispname().c_str()); + "ttcn3_prof.execute_line(\"%s\", 0);\n", get_filename()); } } output->source.static_function_bodies = @@ -1482,13 +1484,38 @@ namespace Common { // language specific parts (definitions, imports, etc.) //generate_code_internal(&target); <- needed to pass cgh generate_code_internal(cgh); + + output_struct* output = cgh.get_current_outputstruct(); // string literals - generate_literals(cgh.get_current_outputstruct()); + generate_literals(output); // module level entry points - generate_functions(cgh.get_current_outputstruct()); + generate_functions(output); // type conversion functions for type compatibility - generate_conversion_functions(cgh.get_current_outputstruct()); + generate_conversion_functions(output); + + /* generate the initializer function for the TTCN-3 profiler + * (this is done at the end of the code generation, to make sure all code + * lines have been added to the profiler database) */ + if (is_file_profiled(get_filename())) { + output->source.global_vars = mputstr(output->source.global_vars, + "\n/* Initializing TTCN-3 profiler */\n" + "void init_ttcn3_profiler()\n" + "{\n"); + char* function_name = 0; + int line_no = -1; + while(get_profiler_code_line(get_filename(), &function_name, &line_no)) { + output->source.global_vars = mputprintf(output->source.global_vars, + " ttcn3_prof.create_line(ttcn3_prof.get_element(\"%s\"), %d);\n", + get_filename(), line_no); + if (0 != function_name) { + output->source.global_vars = mputprintf(output->source.global_vars, + " ttcn3_prof.create_function(ttcn3_prof.get_element(\"%s\"), %d, \"%s\");\n", + get_filename(), line_no, function_name); + } + } + output->source.global_vars = mputstr(output->source.global_vars, "}\n\n"); + } } void Module::dump(unsigned level) const diff --git a/compiler2/Setting.cc b/compiler2/Setting.cc index 1dae00b16..47e5a736c 100644 --- a/compiler2/Setting.cc +++ b/compiler2/Setting.cc @@ -18,6 +18,7 @@ #include "Value.hh" #include "Int.hh" #include "main.hh" +#include "ttcn3/profiler.h" namespace Common { @@ -232,11 +233,20 @@ namespace Common { mputprintf(effective_module_functions, "%s\"%s\"", (effective_module_functions ? ", " : ""), entityname); } - if (profiler_enabled) { + if (is_file_profiled(filename)) { + // .ttcnpp -> .ttcn + size_t file_name_len = strlen(filename); + if ('p' == filename[file_name_len - 1] && 'p' == filename[file_name_len - 2]) { + file_name_len -= 2; + } + char* file_name2 = mcopystrn(filename, file_name_len); str = mputprintf(str, "TTCN3_Stack_Depth stack_depth;\n" - "ttcn3_prof.enter_function(\"%s\", %d, \"%s\");\n", - filename, yyloc.first_line, entityname); + "ttcn3_prof.enter_function(\"%s\", %d);\n", file_name2, yyloc.first_line); + insert_profiler_code_line(file_name2, + (0 == strcmp(entitytype, "CONTROLPART") ? "control" : entityname), + yyloc.first_line); + Free(file_name2); } } return str; @@ -248,11 +258,20 @@ namespace Common { if (include_location_info && !transparency) { str = mputprintf(str, "current_location.update_lineno(%d);\n", yyloc.first_line); - if (profiler_enabled) { + const char* file_name = get_filename(); + if (is_file_profiled(file_name)) { + // .ttcnpp -> .ttcn + size_t file_name_len = strlen(file_name); + if ('p' == file_name[file_name_len - 1] && 'p' == file_name[file_name_len - 2]) { + file_name_len -= 2; + } + char* file_name2 = mcopystrn(file_name, file_name_len); str = mputprintf(str, "ttcn3_prof.execute_line(\"%s\", %d);\n", - get_filename(), yyloc.first_line); + file_name2, yyloc.first_line); + insert_profiler_code_line(file_name2, NULL, yyloc.first_line); + Free(file_name2); } - if (tcov_file_name && in_tcov_files(get_filename())) { + if (tcov_file_name && in_tcov_files(file_name)) { effective_module_lines = mputprintf(effective_module_lines, "%s%d", (effective_module_lines ? ", " : ""), yyloc.first_line); diff --git a/compiler2/Type.cc b/compiler2/Type.cc index 2a9683d3c..fd06d5d4c 100644 --- a/compiler2/Type.cc +++ b/compiler2/Type.cc @@ -149,7 +149,7 @@ namespace Common { } } - Type *Type::get_stream_type(MessageEncodingType_t encoding_type) + Type *Type::get_stream_type(MessageEncodingType_t encoding_type, int stream_variant) { switch (encoding_type) { case CT_BER: @@ -159,7 +159,11 @@ namespace Common { case CT_JSON: return get_pooltype(T_OSTR); case CT_TEXT: - return get_pooltype(T_CSTR); + if(stream_variant==0){ + return get_pooltype(T_CSTR); + } else { + return get_pooltype(T_OSTR); + } default: FATAL_ERROR("Type::get_stream_type()"); return 0; @@ -3529,6 +3533,20 @@ namespace Common { { if (typetype != T_SEQOF) FATAL_ERROR("Type::is_compatible_record_of()"); if (this == p_type) return true; + else if (T_SEQOF == p_type->get_type_refd_last()->typetype && + is_pregenerated() && p_type->is_pregenerated() && + get_ofType()->get_type_refd_last()->typetype == + p_type->get_ofType()->get_type_refd_last()->typetype && + (use_runtime_2 || get_optimize_attribute() == p_type->get_optimize_attribute())) { + // Pre-generated record-ofs of the same element type are compatible with + // each other (in RT1 optimized record-ofs are not compatible with non-optimized ones) + if (!is_subtype_length_compatible(p_type)) { + p_info->set_is_erroneous(this, p_type, string("Incompatible " + "record of/SEQUENCE OF subtypes")); + return false; + } + return true; + } else if (!use_runtime_2 || !p_info || (p_info && p_info->is_strict())) return false; switch (p_type->typetype) { @@ -3878,6 +3896,20 @@ namespace Common { { if (typetype != T_SETOF) FATAL_ERROR("Type::is_compatible_set_of()"); if (this == p_type) return true; + else if (T_SETOF == p_type->get_type_refd_last()->typetype && + is_pregenerated() && p_type->is_pregenerated() && + get_ofType()->get_type_refd_last()->typetype == + p_type->get_ofType()->get_type_refd_last()->typetype && + (use_runtime_2 || get_optimize_attribute() == p_type->get_optimize_attribute())) { + // Pre-generated set-ofs of the same element type are compatible with + // each other (in RT1 optimized set-ofs are not compatible with non-optimized ones) + if (!is_subtype_length_compatible(p_type)) { + p_info->set_is_erroneous(this, p_type, string("Incompatible " + "set of/SET OF subtypes")); + return false; + } + return true; + } else if (!use_runtime_2 || !p_info || (p_info && p_info->is_strict())) return false; Type *of_type = get_ofType(); @@ -5523,6 +5555,7 @@ end_ext: case T_INT: case T_OSTR: case T_CSTR: + case T_USTR: // TTCN3 universal charstring // these basic types support TEXT encoding by default return true; default: @@ -6833,6 +6866,50 @@ end_ext: } return dispname; } + + bool Type::is_pregenerated() + { + // records/sets of base types are already pre-generated, only a type alias will be generated + // exception: record of universal charstring with the XER coding instruction "anyElement" + if (!force_gen_seof && (T_SEQOF == get_type_refd_last()->typetype || + T_SETOF == get_type_refd_last()->typetype) && + (NULL == xerattrib || /* check for "anyElement" at the record of type */ + NamespaceRestriction::UNUSED == xerattrib->anyElement_.type_) && + (NULL == u.seof.ofType->xerattrib || /* check for "anyElement" at the element type */ + NamespaceRestriction::UNUSED == u.seof.ofType->xerattrib->anyElement_.type_)) { + switch(u.seof.ofType->get_type_refd_last()->typetype) { + case T_BOOL: + case T_INT: + case T_INT_A: + case T_REAL: + case T_BSTR: + case T_BSTR_A: + case T_HSTR: + case T_OSTR: + case T_CSTR: + case T_NUMERICSTRING: + case T_PRINTABLESTRING: + case T_IA5STRING: + case T_VISIBLESTRING: + case T_UNRESTRICTEDSTRING: + case T_UTCTIME: + case T_GENERALIZEDTIME: + case T_USTR: + case T_UTF8STRING: + case T_TELETEXSTRING: + case T_VIDEOTEXSTRING: + case T_GRAPHICSTRING: + case T_GENERALSTRING: + case T_UNIVERSALSTRING: + case T_BMPSTRING: + case T_OBJECTDESCRIPTOR: + return true; + default: + return false; + } + } + return false; + } } // namespace Common diff --git a/compiler2/Type.hh b/compiler2/Type.hh index 55737c94b..29f85957b 100644 --- a/compiler2/Type.hh +++ b/compiler2/Type.hh @@ -244,7 +244,7 @@ namespace Common { static const char *get_encoding_name(MessageEncodingType_t encoding_type); /** Returns a pool type that represents the encoded stream of the given * \a encoding_type. */ - static Type *get_stream_type(MessageEncodingType_t encoding_type); + static Type *get_stream_type(MessageEncodingType_t encoding_type, int stream_variant=0); enum truth { No, Maybe, Yes @@ -1017,6 +1017,10 @@ namespace Common { otherwise returns false. **/ bool ispresent_anyvalue_embedded_field(Type* t, Ttcn::FieldOrArrayRefs *subrefs, size_t begin_index); + + /** Returns true if the C++ class for this type has already been pre-generated + * or false if it still needs to be generated */ + bool is_pregenerated(); public: /** Generates type specific call for the reference used in isbound call * into argument \a expr. Argument \a subrefs holds the reference path diff --git a/compiler2/Type_codegen.cc b/compiler2/Type_codegen.cc index b6baffb61..5be67c25d 100644 --- a/compiler2/Type_codegen.cc +++ b/compiler2/Type_codegen.cc @@ -382,6 +382,16 @@ void Type::generate_code_typedescriptor(output_struct *target) "NULL, "); } } + + if (T_SEQOF == get_type_refd_last()->typetype || + T_SETOF == get_type_refd_last()->typetype) { + target->source.global_vars=mputprintf(target->source.global_vars, + "&%s_descr_, ", get_type_refd_last()->u.seof.ofType->get_genname_typedescriptor(my_scope).c_str()); + } + else { + target->source.global_vars = mputstr(target->source.global_vars, + "NULL, "); + } target->source.global_vars=mputprintf(target->source.global_vars, "TTCN_Typedescriptor_t::%s };\n" @@ -483,6 +493,7 @@ void Type::generate_code_xerdescriptor(output_struct* target) any_except=0, nof_ns_uris=0; const char* dfe_str = 0; char** ns_uris = 0; + char* oftype_descr_name = 0; if (xerattrib) { change_name(last_s, xerattrib->name_); @@ -572,6 +583,12 @@ void Type::generate_code_xerdescriptor(output_struct* target) size_t last_len = 2 + last_s.size(); // 2 for > \n size_t bxer_len = 2 + bxer_name.size(); // 2 for > \n + if ((T_SEQOF == last->typetype || T_SETOF == last->typetype) && + T_ANYTYPE != last->u.seof.ofType->get_type_refd_last()->typetype) { + // anytypes don't have XER descriptors + oftype_descr_name = mprintf("&%s_xer_", last->u.seof.ofType->get_genname_typedescriptor(my_scope).c_str()); + } + // Generate a separate variable for the namespace URIs, if there are any char* ns_uris_var = 0; if (ns_uris && nof_ns_uris) { @@ -591,7 +608,7 @@ void Type::generate_code_xerdescriptor(output_struct* target) target->source.global_vars = mputprintf(target->source.global_vars, "const XERdescriptor_t %s_xer_ = { {\"%s>\\n\", \"%s>\\n\"}," " {%lu, %lu}, %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s, WHITESPACE_%s, %c%s, " - "&%s, %ld, %u, %s };\n", + "&%s, %ld, %u, %s, %s };\n", gennameown_str, bxer_name.c_str(), last_s.c_str(), // names (unsigned long)bxer_len, (unsigned long)last_len, // lengths @@ -618,10 +635,12 @@ void Type::generate_code_xerdescriptor(output_struct* target) "module_object", ns_index, nof_ns_uris, - (ns_uris_var ? ns_uris_var : "NULL") + (ns_uris_var ? ns_uris_var : "NULL"), + (oftype_descr_name ? oftype_descr_name : "NULL") ); Free(ns_uris_var); + Free(oftype_descr_name); } void Type::generate_code_rawdescriptor(output_struct *target) @@ -1471,6 +1490,7 @@ void Type::generate_code_Se(output_struct *target) cur.dispname = id.get_ttcnname().c_str(); cur.isOptional = cf->get_is_optional(); cur.isDefault = cf->has_default(); + cur.optimizedMemAlloc = cur.of_type && (type->get_optimize_attribute() == "memalloc"); if (cur.isDefault) { Value *defval = cf->get_defval(); const_def cdef; @@ -1810,6 +1830,41 @@ bool Type::is_untagged() const { return xerattrib && xerattrib->untagged_; } void Type::generate_code_SeOf(output_struct *target) { + const Type *oftypelast = u.seof.ofType->get_type_refd_last(); + const string& oftypename = u.seof.ofType->get_genname_value(my_scope); + boolean optimized_memalloc = !use_runtime_2 && get_optimize_attribute() == "memalloc"; + + if (is_pregenerated()) { + switch(oftypelast->typetype) { + case T_USTR: + case T_UTF8STRING: + case T_TELETEXSTRING: + case T_VIDEOTEXSTRING: + case T_GRAPHICSTRING: + case T_GENERALSTRING: + case T_UNIVERSALSTRING: + case T_BMPSTRING: + case T_OBJECTDESCRIPTOR: + target->header.typedefs = mputprintf(target->header.typedefs, + "typedef PreGenRecordOf::PREGEN__%s__OF__UNIVERSAL__CHARSTRING%s %s;\n" + "typedef PreGenRecordOf::PREGEN__%s__OF__UNIVERSAL__CHARSTRING%s_template %s_template;\n", + (typetype == T_SEQOF) ? "RECORD" : "SET", + optimized_memalloc ? "__OPTIMIZED" : "", get_genname_own().c_str(), + (typetype == T_SEQOF) ? "RECORD" : "SET", + optimized_memalloc ? "__OPTIMIZED" : "", get_genname_own().c_str()); + return; + default: + target->header.typedefs = mputprintf(target->header.typedefs, + "typedef PreGenRecordOf::PREGEN__%s__OF__%s%s %s;\n" + "typedef PreGenRecordOf::PREGEN__%s__OF__%s%s_template %s_template;\n", + (typetype == T_SEQOF) ? "RECORD" : "SET", oftypename.c_str(), + optimized_memalloc ? "__OPTIMIZED" : "", get_genname_own().c_str(), + (typetype == T_SEQOF) ? "RECORD" : "SET", oftypename.c_str(), + optimized_memalloc ? "__OPTIMIZED" : "", get_genname_own().c_str()); + return; + } + } + stringpool pool; struct_of_def sofdef; memset(&sofdef, 0, sizeof(sofdef)); @@ -1826,10 +1881,8 @@ void Type::generate_code_SeOf(output_struct *target) } // If a record of UTF8String, we need to prepare for ANY-ATTRIBUTES and // ANY-ELEMENT - const Type *oftypelast = u.seof.ofType->get_type_refd_last(); sofdef.xerAnyAttrElem = oftypelast->typetype == T_USTR || oftypelast->typetype == T_UTF8STRING; - const string& oftypename = u.seof.ofType->get_genname_value(my_scope); sofdef.type = oftypename.c_str(); sofdef.has_opentypes = get_has_opentypes(); const string& oftypedescrname = @@ -1895,7 +1948,7 @@ void Type::generate_code_SeOf(output_struct *target) sofdef.hasRaw=true; } else sofdef.hasRaw=false; - if (!use_runtime_2 && get_optimize_attribute()=="memalloc") { + if (optimized_memalloc) { defRecordOfClassMemAllocOptimized(&sofdef, target); } else { defRecordOfClass(&sofdef, target); diff --git a/compiler2/Value.cc b/compiler2/Value.cc index a1c1c8a52..7fb2f0b5d 100644 --- a/compiler2/Value.cc +++ b/compiler2/Value.cc @@ -143,6 +143,7 @@ namespace Common { case OPTYPE_TMR_RUNNING_ANY: case OPTYPE_GETVERDICT: case OPTYPE_TESTCASENAME: + case OPTYPE_PROF_RUNNING: break; case OPTYPE_UNARYPLUS: // v1 case OPTYPE_UNARYMINUS: @@ -446,6 +447,7 @@ namespace Common { case OPTYPE_TMR_RUNNING_ANY: case OPTYPE_GETVERDICT: case OPTYPE_TESTCASENAME: + case OPTYPE_PROF_RUNNING: break; case OPTYPE_UNARYPLUS: // v1 case OPTYPE_UNARYMINUS: @@ -809,6 +811,7 @@ namespace Common { case OPTYPE_TMR_RUNNING_ANY: case OPTYPE_GETVERDICT: case OPTYPE_TESTCASENAME: + case OPTYPE_PROF_RUNNING: break; default: FATAL_ERROR("Value::Value()"); @@ -1388,6 +1391,7 @@ namespace Common { case OPTYPE_TMR_RUNNING_ANY: case OPTYPE_GETVERDICT: case OPTYPE_TESTCASENAME: + case OPTYPE_PROF_RUNNING: break; case OPTYPE_UNARYPLUS: // v1 case OPTYPE_UNARYMINUS: @@ -1567,6 +1571,7 @@ namespace Common { case OPTYPE_TMR_RUNNING_ANY: case OPTYPE_GETVERDICT: case OPTYPE_TESTCASENAME: + case OPTYPE_PROF_RUNNING: break; case OPTYPE_UNARYPLUS: // v1 case OPTYPE_UNARYMINUS: @@ -1876,6 +1881,7 @@ namespace Common { case OPTYPE_TMR_RUNNING_ANY: case OPTYPE_GETVERDICT: case OPTYPE_TESTCASENAME: + case OPTYPE_PROF_RUNNING: break; case OPTYPE_UNARYPLUS: // v1 case OPTYPE_UNARYMINUS: @@ -2765,6 +2771,7 @@ namespace Common { case OPTYPE_ISCHOSEN_T: case OPTYPE_ISVALUE: case OPTYPE_ISBOUND: + case OPTYPE_PROF_RUNNING: return Type::T_BOOL; case OPTYPE_GETVERDICT: return Type::T_VERDICT; @@ -3448,6 +3455,8 @@ namespace Common { return "log2str()"; case OPTYPE_TTCN2STRING: return "ttcn2string()"; + case OPTYPE_PROF_RUNNING: + return "@profiler.running"; default: FATAL_ERROR("Value::get_opname()"); } // switch @@ -6038,6 +6047,7 @@ error: switch (u.expr.v_optype) { case OPTYPE_COMP_NULL: case OPTYPE_TESTCASENAME: + case OPTYPE_PROF_RUNNING: break; case OPTYPE_COMP_MTC: case OPTYPE_COMP_SYSTEM: @@ -6998,6 +7008,7 @@ error: case OPTYPE_COMP_ALIVE_ALL: case OPTYPE_TMR_RUNNING_ANY: case OPTYPE_GETVERDICT: + case OPTYPE_PROF_RUNNING: case OPTYPE_RNDWITHVAL: // v1 case OPTYPE_COMP_RUNNING: // v1 case OPTYPE_COMP_ALIVE: @@ -8294,6 +8305,7 @@ error: case OPTYPE_TMR_RUNNING_ANY: case OPTYPE_GETVERDICT: case OPTYPE_TESTCASENAME: + case OPTYPE_PROF_RUNNING: case OPTYPE_RNDWITHVAL: // v1 case OPTYPE_MATCH: // v1 t2 case OPTYPE_UNDEF_RUNNING: // v1 @@ -9797,6 +9809,7 @@ error: case OPTYPE_COMP_ALIVE_ALL: // - case OPTYPE_TMR_RUNNING_ANY: // - case OPTYPE_GETVERDICT: // - + case OPTYPE_PROF_RUNNING: // - break; // nothing to do case OPTYPE_MATCH: // v1 t2 @@ -10496,6 +10509,8 @@ error: } ret_val += ')'; return ret_val; } + case OPTYPE_PROF_RUNNING: + return string("@profiler.running"); default: return string("<unsupported optype>"); } // switch u.expr.v_optype @@ -11771,6 +11786,9 @@ error: } expr->expr = mputstr(expr->expr, ")"); } break; + case OPTYPE_PROF_RUNNING: + expr->expr = mputstr(expr->expr, "ttcn3_prof.is_running()"); + break; default: FATAL_ERROR("Value::generate_code_expr_expr()"); } @@ -12857,6 +12875,7 @@ error: case OPTYPE_TMR_RUNNING_ANY: case OPTYPE_GETVERDICT: case OPTYPE_TESTCASENAME: + case OPTYPE_PROF_RUNNING: return true; case OPTYPE_ENCODE: case OPTYPE_DECODE: @@ -13178,13 +13197,16 @@ error: if (t_subrefs) { // the evaluation of the reference does not have side effects // (i.e. false shall be returned) only if all sub-references point to - // mandatory fields of record/set types + // mandatory fields of record/set types, and neither sub-reference points + // to a field of a union type Type *t_type = t_ass->get_Type(); for (size_t i = 0; i < t_subrefs->get_nof_refs(); i++) { Ttcn::FieldOrArrayRef *t_fieldref = t_subrefs->get_ref(i); if (t_fieldref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF) { CompField *t_cf = t_type->get_comp_byName(*t_fieldref->get_id()); - if (t_cf->get_is_optional()) return true; + if (Type::T_CHOICE_T == t_type->get_type_refd_last()->get_typetype() || + Type::T_CHOICE_A == t_type->get_type_refd_last()->get_typetype() || + t_cf->get_is_optional()) return true; t_type = t_cf->get_type(); } else return true; } diff --git a/compiler2/Value.hh b/compiler2/Value.hh index cfd3f796b..61d324cf9 100644 --- a/compiler2/Value.hh +++ b/compiler2/Value.hh @@ -238,7 +238,8 @@ namespace Common { OPTYPE_EXECUTE, // r1 [v2] OPTYPE_EXECUTE_REFD, // v1 t_list2 [v3] - OPTYPE_LOG2STR, // logagrs 98 + OPTYPE_LOG2STR, // logagrs + OPTYPE_PROF_RUNNING, // - 99 NUMBER_OF_OPTYPES // must be last }; @@ -369,7 +370,8 @@ namespace Common { Value(valuetype_t p_vt, Value *p_v, Ttcn::ParsedActualParameters *p_t_list); /** Constructor used by V_EXPR "-": RND, TESTCASENAME, COMP_NULL, COMP_MTC, * COMP_SYSTEM, COMP_SELF, COMP_RUNNING_ANY, COMP_RUNNING_ALL, - * COMP_ALIVE_ALL, COMP_ALIVE_ANY, TMR_RUNNING_ANY, GETVERDICT */ + * COMP_ALIVE_ALL, COMP_ALIVE_ANY, TMR_RUNNING_ANY, GETVERDICT, + * PROF_RUNNING */ Value(operationtype_t p_optype); /** Constructor used by V_EXPR "v1" */ Value(operationtype_t p_optype, Value *p_v1); diff --git a/compiler2/compiler.1 b/compiler2/compiler.1 index a3416e4b5..2df9a3418 100644 --- a/compiler2/compiler.1 +++ b/compiler2/compiler.1 @@ -8,6 +8,8 @@ compiler \- TTCN-3 and ASN.1 to C++ translator .IR " verb_level" " \|]" .RB "[\| " \-K .IR " file" " \|]" +.RB "[\| " \-z +.IR " file" " \|]" .RB "[\| " \-o .IR " dir" " \|]" .RB "[\| " \-P @@ -294,6 +296,11 @@ checking .B \-Y Enforces legacy behaviour of the "out" function parameters (see refguide). .TP +.BI \-z " file" +Enables profiling and code coverage in the selected TTCN-3 files. The +.I file +argument contains a list of TTCN-3 files separated by new lines. Each TTCN-3 file must be among the compiler's TTCN-3 file arguments. +.TP .B \- The single dash character as command line argument controls the .I selective code generation diff --git a/compiler2/datatypes.h b/compiler2/datatypes.h index a24cf6355..a49fe4be8 100644 --- a/compiler2/datatypes.h +++ b/compiler2/datatypes.h @@ -70,6 +70,8 @@ typedef struct { boolean jsonOmitAsNull; const char* jsonAlias; const char* jsonDefaultValue; + /** true if the field is a record-of or set-of with optimized memory allocation */ + boolean optimizedMemAlloc; } struct_field; /** Structure (record, set, union, anytype) descriptor for code generation */ diff --git a/compiler2/main.cc b/compiler2/main.cc index fd58f1a80..7a0d19b5e 100644 --- a/compiler2/main.cc +++ b/compiler2/main.cc @@ -45,6 +45,8 @@ #include "ttcn3/Ttcn2Json.hh" +#include "ttcn3/profiler.h" + #ifdef LICENSE #include "../common/license.h" #endif @@ -53,6 +55,7 @@ using namespace Common; const char *output_dir = NULL; const char *tcov_file_name = NULL; +const char *profiler_file_name = NULL; tcov_file_list *tcov_files = NULL; expstring_t effective_module_lines = NULL; expstring_t effective_module_functions = NULL; @@ -68,7 +71,7 @@ boolean generate_skeleton = FALSE, force_overwrite = FALSE, use_runtime_2 = FALSE, gcc_compat = FALSE, asn1_xer = FALSE, check_subtype = TRUE, suppress_context = FALSE, display_up_to_date = FALSE, implicit_json_encoding = FALSE, json_refs_for_all_types = TRUE, - profiler_enabled = FALSE; + force_gen_seof = FALSE; // Default code splitting mode is set to 'no splitting'. CodeGenHelper::split_type code_splitting_mode = CodeGenHelper::SPLIT_NONE; @@ -286,7 +289,8 @@ boolean in_tcov_files(const char *file_name) return get_tcov_file_name(file_name) ? TRUE : FALSE; } -static bool check_file_list(const char *file_name, module_struct *module_list, size_t n_modules) +static bool check_file_list(const char *file_name, module_struct *module_list, + size_t n_modules, tcov_file_list *&file_list_head) { FILE *fp = fopen(file_name, "r"); if (fp == NULL) { @@ -316,11 +320,11 @@ static bool check_file_list(const char *file_name, module_struct *module_list, s for (; i < n_modules; ++i) { const module_struct *module = module_list + i; if (!strncmp(module->file_name, line, line_len)) { - tcov_file_list *next_file = new tcov_file_list; - next_file->next = tcov_files; + tcov_file_list *next_file = (tcov_file_list*)Malloc(sizeof(tcov_file_list)); + next_file->next = file_list_head; // We'll need the `.ttcnpp' file name. next_file->file_name = mcopystr(line); - tcov_files = next_file; + file_list_head = next_file; break; } } @@ -332,13 +336,13 @@ static bool check_file_list(const char *file_name, module_struct *module_list, s } fclose(fp); if (unlisted_files) { - while (tcov_files != NULL) { - tcov_file_list *next_file = tcov_files->next; - Free(tcov_files->file_name); - delete tcov_files; - tcov_files = next_file; + while (file_list_head != NULL) { + tcov_file_list *next_file = file_list_head->next; + Free(file_list_head->file_name); + Free(file_list_head); + file_list_head = next_file; } - tcov_files = NULL; + file_list_head = NULL; } return !unlisted_files; } @@ -354,8 +358,8 @@ static boolean is_valid_asn1_filename(const char* file_name) static void usage() { fprintf(stderr, "\n" - "usage: %s [-abcdfgilLOpqrRsStuwxXjy] [-K file] [-V verb_level] [-o dir]\n" - " [-U none|type] [-P modulename.top_level_pdu_name] [-Q number] ...\n" + "usage: %s [-abcdfgijlLOpqrRsStuwxXyY] [-K file] [-z file] [-V verb_level]\n" + " [-o dir] [-U none|type] [-P modulename.top_level_pdu_name] [-Q number] ...\n" " [-T] module.ttcn [-A] module.asn ...\n" " or %s -v\n" " or %s --ttcn2json [-jf] ... [-T] module.ttcn [-A] module.asn ... [- schema.json]\n" @@ -390,7 +394,7 @@ static void usage() " -X: disable XER encoder/decoder functions\n" " -y: disable subtype checking\n" " -Y: Enforces legacy behaviour of the \"out\" function parameters (see refguide)\n" - //" -z: enable profiling and code coverage for TTCN-3 files\n" - not open to the public yet + " -z file: enable profiling and code coverage for the TTCN-3 files in the argument\n" " -T file: force interpretation of file as TTCN-3 module\n" " -A file: force interpretation of file as ASN.1 module\n" " -v: show version\n" @@ -438,7 +442,7 @@ int main(int argc, char *argv[]) usage(); return EXIT_FAILURE; } - + bool Aflag = false, Lflag = false, Yflag = false, Pflag = false, Tflag = false, Vflag = false, bflag = false, @@ -447,7 +451,7 @@ int main(int argc, char *argv[]) tflag = false, uflag = false, vflag = false, wflag = false, xflag = false, dflag = false, Xflag = false, Rflag = false, gflag = false, aflag = false, s0flag = false, Cflag = false, yflag = false, Uflag = false, Qflag = false, - Sflag = false, Kflag = false, jflag = false, zflag = false, + Sflag = false, Kflag = false, jflag = false, zflag = false, Fflag = false, errflag = false, print_usage = false, ttcn2json = false; CodeGenHelper cgh; @@ -540,7 +544,7 @@ int main(int argc, char *argv[]) if (!ttcn2json) { for ( ; ; ) { - int c = getopt(argc, argv, "aA:C:K:LP:T:V:bcdfgilo:YpqQ:rRs0StuU:vwxXjyz-"); + int c = getopt(argc, argv, "aA:C:K:LP:T:V:bcdfFgilo:YpqQ:rRs0StuU:vwxXjyz:-"); if (c == -1) break; switch (c) { case 'a': @@ -697,7 +701,11 @@ int main(int argc, char *argv[]) break; case 'z': SET_FLAG(z); - profiler_enabled = TRUE; + profiler_file_name = optarg; + break; + case 'F': + SET_FLAG(F); + force_gen_seof = TRUE; break; case 'Q': { @@ -722,8 +730,8 @@ int main(int argc, char *argv[]) Error_Context::set_max_errors(max_errs); break; } - - case '-': + + case '-': if (!strcmp(argv[optind], "--ttcn2json")) { ERROR("Option `--ttcn2json' is only allowed as the first option"); } else { @@ -743,7 +751,7 @@ int main(int argc, char *argv[]) if (Aflag || Lflag || Pflag || Tflag || Vflag || Yflag || bflag || fflag || iflag || lflag || oflag || pflag || qflag || rflag || sflag || tflag || uflag || wflag || xflag || Xflag || Rflag || - Uflag || yflag || Kflag || jflag || zflag) { + Uflag || yflag || Kflag || jflag || zflag || Fflag) { errflag = true; print_usage = true; } @@ -966,11 +974,20 @@ int main(int argc, char *argv[]) has_xer_feature = check_feature(&lstr, FEATURE_XER); free_license(&lstr); #endif - if (Kflag && !check_file_list(tcov_file_name, module_list, n_modules)) { + if (Kflag && !check_file_list(tcov_file_name, module_list, n_modules, tcov_files)) { ERROR("Error while processing `%s' provided for code coverage data " "generation.", tcov_file_name); return EXIT_FAILURE; } + if (zflag) { + tcov_file_list *file_list_head = NULL; + if(!check_file_list(profiler_file_name, module_list, n_modules, file_list_head)) { + ERROR("Error while processing `%s' provided for profiling and code coverage.", + profiler_file_name); + return EXIT_FAILURE; + } + init_profiler_data(file_list_head); + } { STOPWATCH("Parsing modules"); @@ -1069,7 +1086,7 @@ int main(int argc, char *argv[]) while (tcov_files != NULL) { tcov_file_list *next_file = tcov_files->next; Free(tcov_files->file_name); - delete tcov_files; + Free(tcov_files); tcov_files = next_file; } tcov_files = NULL; @@ -1081,6 +1098,9 @@ int main(int argc, char *argv[]) Common::Node::chk_counter(); Location::delete_source_file_names(); Free(json_schema_name); + if (zflag) { + free_profiler_data(); + } // dbgnew.hh already does it: check_mem_leak(argv[0]); diff --git a/compiler2/main.hh b/compiler2/main.hh index 18ec89601..4e522034a 100644 --- a/compiler2/main.hh +++ b/compiler2/main.hh @@ -13,6 +13,7 @@ extern "C" { #endif #include "datatypes.h" +#include "../common/memory.h" typedef struct tcov_file_list { @@ -34,7 +35,7 @@ extern boolean generate_skeleton, force_overwrite, include_line_info, include_location_info, duplicate_underscores, parse_only, semantic_check_only, output_only_linenum, default_as_optional, use_runtime_2, gcc_compat, asn1_xer, check_subtype, suppress_context, enable_set_bound_out_param, display_up_to_date, - implicit_json_encoding, json_refs_for_all_types, profiler_enabled; + implicit_json_encoding, json_refs_for_all_types, force_gen_seof; extern const char *expected_platform; diff --git a/compiler2/record.c b/compiler2/record.c index 79e914f38..eeda17628 100644 --- a/compiler2/record.c +++ b/compiler2/record.c @@ -2118,10 +2118,17 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) " embed_values_enc_struct_t* emb_val = 0;\n" " if (e_xer && (p_td.xer_bits & EMBED_VALUES) && field_%s.size_of() > 1) {\n" " emb_val = new embed_values_enc_struct_t;\n" - " emb_val->embval_array = &field_%s;\n" + /* If the first field is a record of ANY-ELEMENTs, then it won't be a pre-generated + * record of universal charstring, so it needs a cast to avoid a compilation error */ + " emb_val->embval_array%s = (const PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING%s*)&field_%s;\n" + " emb_val->embval_array%s = NULL;\n" " emb_val->embval_index = 1;\n" - " emb_val->embval_size = field_%s.size_of();\n" - " }\n", sdef->elements[0].name, sdef->elements[0].name, sdef->elements[0].name); + " }\n" + , sdef->elements[0].name + , sdef->elements[0].optimizedMemAlloc ? "_opt" : "_reg" + , sdef->elements[0].optimizedMemAlloc ? "__OPTIMIZED" : "" + , sdef->elements[0].name + , sdef->elements[0].optimizedMemAlloc ? "_reg" : "_opt"); } if (sdef->xerUseOrderPossible) { @@ -2223,12 +2230,12 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) if (sdef->xerEmbedValuesPossible) { src = mputprintf(src, " if (e_xer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&\n" - " emb_val->embval_index < emb_val->embval_size) { // embed-val\n" + " emb_val->embval_index < field_%s.size_of()) { // embed-val\n" " field_%s[emb_val->embval_index].XER_encode(\n" " UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n" " ++emb_val->embval_index;\n" " }\n" - , sdef->elements[0].name); + , sdef->elements[0].name, sdef->elements[0].name); } @@ -2255,27 +2262,27 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) if (sdef->xerEmbedValuesPossible) { src = mputprintf(src, " if (e_xer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&\n" - " emb_val->embval_index < emb_val->embval_size) {\n" + " emb_val->embval_index < field_%s.size_of()) {\n" " field_%s[emb_val->embval_index].XER_encode(\n" " UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n" " ++emb_val->embval_index;\n" " }\n" - , sdef->elements[0].name); + , sdef->elements[0].name, sdef->elements[0].name); } } /* next field when not USE-ORDER */ if (sdef->xerEmbedValuesPossible) { src = mputprintf(src, " if (0 != emb_val) {\n" - " if (emb_val->embval_index < emb_val->embval_size) {\n" + " if (emb_val->embval_index < field_%s.size_of()) {\n" " ec_1.set_msg(\"%s': \");\n" " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,\n" " \"Too many EMBED-VALUEs specified: %%d (expected %%d or less)\",\n" - " emb_val->embval_size, emb_val->embval_index);\n" + " field_%s.size_of(), emb_val->embval_index);\n" " }\n" " delete emb_val;\n" " }\n" - , sdef->elements[0].name); + , sdef->elements[0].name, sdef->elements[0].name, sdef->elements[0].name); } src = mputstr(src, " } // QN?\n"); @@ -2636,10 +2643,18 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) " embed_values_dec_struct_t* emb_val = 0;\n" " if (e_xer && (p_td.xer_bits & EMBED_VALUES)) {\n" " emb_val = new embed_values_dec_struct_t;\n" - " emb_val->embval_array = &field_%s;\n" + /* If the first field is a record of ANY-ELEMENTs, then it won't be a pre-generated + * record of universal charstring, so it needs a cast to avoid a compilation error */ + " emb_val->embval_array%s = (PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING%s*)&field_%s;\n" + " emb_val->embval_array%s = NULL;\n" " emb_val->embval_index = 0;\n" " field_%s.set_size(0);\n" - " }\n", sdef->elements[0].name, sdef->elements[0].name); + " }\n" + , sdef->elements[0].optimizedMemAlloc ? "_opt" : "_reg" + , sdef->elements[0].optimizedMemAlloc ? "__OPTIMIZED" : "" + , sdef->elements[0].name + , sdef->elements[0].optimizedMemAlloc ? "_reg" : "_opt" + , sdef->elements[0].name); } if (sdef->xerUseOrderPossible) { diff --git a/compiler2/record_of.c b/compiler2/record_of.c index b820722e9..5f97b3d90 100644 --- a/compiler2/record_of.c +++ b/compiler2/record_of.c @@ -39,11 +39,11 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) char *def = NULL, *src = NULL; const char *name = sdef->name, *dispname = sdef->dispname; const char *type = sdef->type; - boolean ber_needed = sdef->isASN1 && enable_ber(); - boolean raw_needed = sdef->hasRaw && enable_raw(); - boolean text_needed = sdef->hasText && enable_text(); - boolean xer_needed = sdef->hasXer && enable_xer(); - boolean json_needed = sdef->hasJson && enable_json(); + boolean ber_needed = force_gen_seof || (sdef->isASN1 && enable_ber()); + boolean raw_needed = force_gen_seof || (sdef->hasRaw && enable_raw()); + boolean text_needed = force_gen_seof || (sdef->hasText && enable_text()); + boolean xer_needed = force_gen_seof || (sdef->hasXer && enable_xer()); + boolean json_needed = force_gen_seof || (sdef->hasJson && enable_json()); /* Class definition and private data members */ def = mputprintf(def, @@ -723,7 +723,7 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " p_buf.put_cs(*p_td.text->separator_encode);\n" " encoded_length+=p_td.text->separator_encode->lengthof();\n" " }\n" - " encoded_length+=(*this)[a].TEXT_encode(%s_descr_,p_buf);\n" + " encoded_length+=(*this)[a].TEXT_encode(*p_td.oftype_descr,p_buf);\n" " }\n" " if(p_td.text->end_encode){\n" " p_buf.put_cs(*p_td.text->end_encode);\n" @@ -731,7 +731,7 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " }\n" " return encoded_length;\n" "}\n" - ,name,sdef->oftypedescrname + ,name ); src = mputprintf(src, "int %s::TEXT_decode(const TTCN_Typedescriptor_t& p_td," @@ -774,7 +774,7 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " while(TRUE){\n" " %s *val=new %s;\n" " pos=p_buf.get_pos();\n" - " int len=val->TEXT_decode(%s_descr_,p_buf,limit,TRUE);\n" + " int len=val->TEXT_decode(*p_td.oftype_descr,p_buf,limit,TRUE);\n" " if(len==-1 || (len==0 && !limit.has_token())){\n" " p_buf.set_pos(pos);\n" " delete val;\n" @@ -816,7 +816,7 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " }\n" " }\n" " }\n" - ,name,type,type,sdef->oftypedescrname,type + ,name,type,type,type ); src = mputstr(src, " limit.remove_tokens(ml);\n" @@ -871,7 +871,7 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " for(int elem_i=0; elem_i<val_ptr->n_elements; elem_i++) {\n" " ec.set_msg(\"Component #%%d: \", elem_i);\n" " new_tlv->add_TLV((*this)[elem_i].BER_encode_TLV" - "(%s_descr_, p_coding));\n" + "(*p_td.oftype_descr, p_coding));\n" " }\n" "%s" " }\n" @@ -905,16 +905,16 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) "val_ptr->n_elements + 1);\n" " val_ptr->n_elements++;\n" " val_ptr->value_elements[val_ptr->n_elements - 1] = new %s;\n" - " val_ptr->value_elements[val_ptr->n_elements - 1]->BER_decode_TLV(%s_descr_, tmp_tlv, " + " val_ptr->value_elements[val_ptr->n_elements - 1]->BER_decode_TLV(*p_td.oftype_descr, tmp_tlv, " "L_form);\n" " ec_2.set_msg(\"%%d: \", val_ptr->n_elements);\n" " }\n" " return TRUE;\n" "}\n" "\n" - , name, sdef->oftypedescrname + , name , sdef->kind==SET_OF?" new_tlv->sort_tlvs();\n":"" - , name, type, type, sdef->oftypedescrname + , name, type, type ); if(sdef->has_opentypes) { @@ -966,7 +966,7 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " int a=0;\n" " if(sel_field==-1) sel_field=p_td.raw->fieldlength;\n" " for(a=0;a<sel_field;a++){\n" - " decoded_field_length=(*this)[a+start_field].RAW_decode(%s_descr_," + " decoded_field_length=(*this)[a+start_field].RAW_decode(*p_td.oftype_descr," "p_buf,limit,top_bit_ord,TRUE);\n" " if(decoded_field_length < 0) return decoded_field_length;\n" " decoded_length+=decoded_field_length;\n" @@ -983,7 +983,7 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " }\n" " while(limit>0){\n" " start_of_field=p_buf.get_pos_bit();\n" - " decoded_field_length=(*this)[a].RAW_decode(%s_descr_,p_buf,limit," + " decoded_field_length=(*this)[a].RAW_decode(*p_td.oftype_descr,p_buf,limit," "top_bit_ord,TRUE);\n" " if(decoded_field_length < 0){\n" " delete &(*this)[a];\n" @@ -997,13 +997,16 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " decoded_length+=decoded_field_length;\n" " limit-=decoded_field_length;\n" " a++;\n" - ,name,sdef->oftypedescrname,sdef->oftypedescrname + ,name ); - if(sdef->raw.extension_bit!=XDEFNO && sdef->raw.extension_bit!=XDEFDEFAULT){ + if (force_gen_seof || (sdef->raw.extension_bit!=XDEFNO && sdef->raw.extension_bit!=XDEFDEFAULT)){ src=mputprintf(src, - " if (%sp_buf.get_last_bit())\n" + " if (%s%sp_buf.get_last_bit()%s)\n" " return decoded_length+p_buf.increase_pos_padd(p_td.raw->padding)" - "+prepaddlength;\n", sdef->raw.extension_bit == XDEFYES ? "" : "!"); + "+prepaddlength;\n" + , force_gen_seof ? "EXT_BIT_NO != p_td.raw->extension_bit && ((EXT_BIT_YES != p_td.raw->extension_bit) ^ " : "" + , (force_gen_seof || sdef->raw.extension_bit == XDEFYES) ? "" : "!" + , force_gen_seof ? ")" : ""); } src=mputprintf(src, " }\n" @@ -1023,12 +1026,12 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " myleaf.body.node.nodes=init_nodes_of_enc_tree(encoded_num_of_records);\n" " for(int a=0;a<encoded_num_of_records;a++){\n" " myleaf.body.node.nodes[a]=new RAW_enc_tree(TRUE,&myleaf," - "&(myleaf.curr_pos),a,%s_descr_.raw);\n" - " encoded_length+=(*this)[a].RAW_encode(%s_descr_," + "&(myleaf.curr_pos),a,p_td.oftype_descr->raw);\n" + " encoded_length+=(*this)[a].RAW_encode(*p_td.oftype_descr," "*myleaf.body.node.nodes[a]);\n" " }\n" " return myleaf.length=encoded_length;\n}\n\n" - , name, sdef->oftypedescrname, sdef->oftypedescrname + , name ); } @@ -1042,10 +1045,12 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) "boolean %s::can_start(const char *name, const char *uri, " "XERdescriptor_t const& xd, unsigned int flavor) {\n" " boolean e_xer = is_exer(flavor);\n" - " if (e_xer && (xd.xer_bits & ANY_ELEMENT)) " + " if ((!e_xer || !(xd.xer_bits & UNTAGGED)) && !(flavor & XER_RECOF)) return " + "check_name(name, xd, e_xer) && (!e_xer || check_namespace(uri, xd));\n" + " if (e_xer && (xd.oftype_descr->xer_bits & ANY_ELEMENT)) " , name ); - if (sdef->nFollowers) { + if (!force_gen_seof && sdef->nFollowers) { /* If there are optional fields following the record-of, then seeing * {any XML tag that belongs to those fields} where the record-of may be * means that the record-of is empty. */ @@ -1065,12 +1070,9 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) else src = mputstr(src, "return TRUE;\n"); src = mputprintf(src, - " if ((!e_xer || !(xd.xer_bits & UNTAGGED)) && !(flavor & XER_RECOF)) return " - "check_name(name, xd, e_xer) && (!e_xer || check_namespace(uri, xd));\n" - " else return %s::can_start(name, uri, %s_xer_, flavor | XER_RECOF);\n" + " return %s::can_start(name, uri, *xd.oftype_descr, flavor | XER_RECOF);\n" "}\n\n" , sdef->type - , sdef->oftypedescrname ); src = mputprintf(src, @@ -1083,7 +1085,7 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " size_t num_new;\n" " for (int i = 0; i < val_ptr->n_elements; ++i) {\n" " bool def_ns_1 = false;" - " new_ns = (*this)[i].collect_ns(%s_xer_, num_new, def_ns_1);\n" + " new_ns = (*this)[i].collect_ns(*p_td.oftype_descr, num_new, def_ns_1);\n" " merge_ns(collected_ns, num_collected, new_ns, num_new);\n" " def_ns = def_ns || def_ns_1;\n" /* alas, no ||= */ " }\n" @@ -1098,7 +1100,7 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " num = num_collected;\n" " return collected_ns;\n" "}\n\n" - , name, sdef->oftypedescrname); + , name); src=mputprintf(src, "int %s::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, " @@ -1112,16 +1114,18 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) "%s" /* Factor out p_indent if not attribute */ " if (val_ptr->n_elements==0) {\n" /* Empty record of */ , name - , sdef->xerAttribute ? "" : " if (indenting) do_indent(p_buf, p_indent);\n" + , force_gen_seof ? " if (indenting && !(p_td.xer_bits & XER_ATTRIBUTE)) do_indent(p_buf, p_indent);\n" + : (sdef->xerAttribute ? "" : " if (indenting) do_indent(p_buf, p_indent);\n") ); - if (sdef->xerAttribute) { - src=mputstr(src, - " if (e_xer) {\n" /* Empty attribute. */ + if (force_gen_seof || sdef->xerAttribute) { + src=mputprintf(src, + " if (e_xer%s) {\n" /* Empty attribute. */ " begin_attribute(p_td, p_buf);\n" " p_buf.put_c('\\'');\n" - " } else\n"); + " } else\n" + , force_gen_seof ? " && (p_td.xer_bits & XER_ATTRIBUTE)" : ""); } - else { + if (force_gen_seof || !sdef->xerAttribute) { src = mputstr(src, " if (own_tag)"); } @@ -1149,7 +1153,8 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " }\n" " }\n" " else {\n" /* Not empty record of. Start tag or attribute */ - , sdef->xerAttribute ? " if (indenting) do_indent(p_buf, p_indent);\n" : "" + , force_gen_seof ? " if (indenting && (p_td.xer_bits & XER_ATTRIBUTE)) do_indent(p_buf, p_indent);\n" + : (sdef->xerAttribute ? " if (indenting) do_indent(p_buf, p_indent);\n" : "") ); if (sdef->xerAnyAttrElem) { src = mputstr(src, @@ -1236,11 +1241,12 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " p_buf.put_s(shorter, saved);\n" /* restore the '>' and anything after */ " } else {\n"); } - if (sdef->xerAttribute) { - src=mputstr(src, - " if (e_xer) {\n" + if (force_gen_seof || sdef->xerAttribute) { + src=mputprintf(src, + " if (e_xer%s) {\n" " begin_attribute(p_td, p_buf);\n" - " } else\n"); + " } else\n" + , force_gen_seof ? " && (p_td.xer_bits & XER_ATTRIBUTE)" : ""); } src=mputprintf(src, " if (own_tag) {\n" @@ -1266,7 +1272,8 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " Free(collected_ns);\n" " p_buf.put_s(1 + keep_newline, (cbyte*)\">\\n\");\n" " }\n" - , sdef->xerAttribute ? " if (indenting) do_indent(p_buf, p_indent);\n" : "" + , force_gen_seof ? " if (indenting && (p_td.xer_bits & XER_ATTRIBUTE)) do_indent(p_buf, p_indent);\n" + : (sdef->xerAttribute ? " if (indenting) do_indent(p_buf, p_indent);\n" : "") ); if (sdef->xmlValueList) { src=mputstr(src, " if (indenting && !e_xer) do_indent(p_buf, p_indent+1);\n"); /* !e_xer or GDMO */ @@ -1277,20 +1284,26 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " TTCN_EncDec_ErrorContext ec_0(\"Index \");\n" " TTCN_EncDec_ErrorContext ec_1;\n" ); - src=mputprintf(src, + src=mputstr(src, " for (int i = 0; i < val_ptr->n_elements; ++i) {\n" - /*" if (i > 0 && !own_tag && 0 != emb_val &&\n" - " emb_val->embval_index < emb_val->embval_size) {\n" - " emb_val->embval_array->get_embedded_value(emb_val->embval_index).XER_encode(\n" - " UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n" + " if (i > 0 && !own_tag && 0 != emb_val &&\n" + " emb_val->embval_index < (0 != emb_val->embval_array_reg ?\n" + " emb_val->embval_array_reg->size_of() : emb_val->embval_array_opt->size_of())) {\n" + " if (0 != emb_val->embval_array_reg) {\n" + " (*emb_val->embval_array_reg)[emb_val->embval_index].XER_encode(\n" + " UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n" + " }\n" + " else {\n" + " (*emb_val->embval_array_opt)[emb_val->embval_index].XER_encode(\n" + " UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n" + " }\n" " ++emb_val->embval_index;\n" - " }\n" - temporarily removed in RT1 */ - " ec_1.set_msg(\"%%d: \", i);\n" + " }\n" + " ec_1.set_msg(\"%d: \", i);\n" " if (e_xer && (p_td.xer_bits & XER_LIST) && i>0) p_buf.put_c(' ');\n" - " (*this)[i].XER_encode(%s_xer_, p_buf, p_flavor, p_indent+own_tag, emb_val);\n" + " (*this)[i].XER_encode(*p_td.oftype_descr, p_buf, p_flavor, p_indent+own_tag, emb_val);\n" " }\n" - " if (indenting && !is_exerlist(p_flavor)) {\n", - sdef->oftypedescrname + " if (indenting && !is_exerlist(p_flavor)) {\n" ); if (sdef->xmlValueList) { src=mputstr(src, " if (!e_xer) p_buf.put_c('\\n');\n"); /* !e_xer or GDMO */ @@ -1298,10 +1311,11 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) src=mputstr(src, " do_indent(p_buf, p_indent);\n" " }\n"); - if (sdef->xerAttribute) { - src=mputstr(src, - " if (e_xer) p_buf.put_c('\\'');\n" - " else\n"); + if (force_gen_seof || sdef->xerAttribute) { + src=mputprintf(src, + " if (e_xer%s) p_buf.put_c('\\'');\n" + " else\n" + , force_gen_seof ? " && (p_td.xer_bits & XER_ATTRIBUTE)" : ""); } src=mputstr(src, " if (own_tag){\n" @@ -1357,13 +1371,15 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " }\n" /* next read */ " else xml_depth = p_reader.Depth();\n" " p_flavor |= XER_RECOF;\n" + " TTCN_EncDec_ErrorContext ec_0(\"Index \");\n" + " TTCN_EncDec_ErrorContext ec_1;\n" #ifndef NDEBUG , __FUNCTION__, __LINE__ #endif , name ); - src = mputprintf(src, + src = mputstr(src, " if (e_xer && (p_td.xer_bits & XER_LIST)) {\n" /* LIST decoding*/ " char *x_val = (char*)p_reader.NewValue();\n" /* we own it */ " size_t x_pos = 0;\n" @@ -1377,13 +1393,13 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " x_pos += strlen(str) + 1;\n" " TTCN_Buffer buf_2;\n" " buf_2.put_c('<');\n" - " write_ns_prefix(%s_xer_, buf_2);\n" - " const char * const exer_name = %s_xer_.names[1];\n" - " boolean i_can_has_ns = %s_xer_.my_module != 0 && %s_xer_.ns_index != -1;\n" + " write_ns_prefix(*p_td.oftype_descr, buf_2);\n" + " const char * const exer_name = p_td.oftype_descr->names[1];\n" + " boolean i_can_has_ns = p_td.oftype_descr->my_module != 0 && p_td.oftype_descr->ns_index != -1;\n" /* If it has a namespace, chop off the '>' from the end */ - " buf_2.put_s((size_t)%s_xer_.namelens[1]-1-i_can_has_ns, (cbyte*)exer_name);\n" + " buf_2.put_s((size_t)p_td.oftype_descr->namelens[1]-1-i_can_has_ns, (cbyte*)exer_name);\n" " if (i_can_has_ns) {\n" - " const namespace_t * const pns = %s_xer_.my_module->get_ns(%s_xer_.ns_index);\n" + " const namespace_t * const pns = p_td.oftype_descr->my_module->get_ns(p_td.oftype_descr->ns_index);\n" " buf_2.put_s(7 - (*pns->px == 0), (cbyte*)\" xmlns:\");\n" " buf_2.put_s(strlen(pns->px), (cbyte*)pns->px);\n" " buf_2.put_s(2, (cbyte*)\"='\");\n" @@ -1394,14 +1410,15 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " buf_2.put_s(strlen(str), (cbyte*)str);\n" " buf_2.put_c('<');\n" " buf_2.put_c('/');\n" - " write_ns_prefix(%s_xer_, buf_2);\n" - " buf_2.put_s((size_t)%s_xer_.namelens[1], (cbyte*)exer_name);\n" + " write_ns_prefix(*p_td.oftype_descr, buf_2);\n" + " buf_2.put_s((size_t)p_td.oftype_descr->namelens[1], (cbyte*)exer_name);\n" " XmlReaderWrap reader_2(buf_2);\n" " rd_ok = reader_2.Read();\n" /* Move to the start element. */ + " ec_1.set_msg(\"%d: \", val_ptr->n_elements);\n" /* Don't move to the #text, that's the callee's responsibility. */ /* The call to the non-const operator[] creates a new element object, * then we call its XER_decode with the temporary XML reader. */ - " (*this)[val_ptr->n_elements].XER_decode(%s_xer_, reader_2, p_flavor, 0);\n" + " (*this)[val_ptr->n_elements].XER_decode(*p_td.oftype_descr, reader_2, p_flavor, 0);\n" " if (p_flavor & EXIT_ON_ERROR && !(*this)[val_ptr->n_elements - 1].is_bound()) {\n" " if (1 == val_ptr->n_elements) {\n" // Failed to decode even the first element @@ -1423,11 +1440,6 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " p_reader.Read();\n" /* past it */ " }\n" " }\n" - , sdef->oftypedescrname, sdef->oftypedescrname - , sdef->oftypedescrname, sdef->oftypedescrname - , sdef->oftypedescrname, sdef->oftypedescrname - , sdef->oftypedescrname, sdef->oftypedescrname - , sdef->oftypedescrname, sdef->oftypedescrname ); src = mputprintf(src, @@ -1457,17 +1469,18 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " if (p_reader.NodeType() != XML_READER_TYPE_ELEMENT) rd_ok = p_reader.Read();\n" " } else"); } - src = mputprintf(src, + src = mputstr(src, " {\n" /* An untagged record-of ends if it encounters an element with a name * that doesn't match its component */ " if (!own_tag && !can_start((const char*)p_reader.LocalName(), " - "(const char*)p_reader.NamespaceUri(), %s_xer_, p_flavor)) {\n" + "(const char*)p_reader.NamespaceUri(), p_td, p_flavor)) {\n" " for (; rd_ok == 1 && p_reader.Depth() > xml_depth; rd_ok = p_reader.Read()) ;\n" " break;\n" " }\n" + " ec_1.set_msg(\"%d: \", val_ptr->n_elements);\n" /* The call to the non-const operator[] creates the element */ - " (*this)[val_ptr->n_elements].XER_decode(%s_xer_, p_reader, p_flavor, emb_val);\n" + " (*this)[val_ptr->n_elements].XER_decode(*p_td.oftype_descr, p_reader, p_flavor, emb_val);\n" " if (0 != emb_val && !own_tag && val_ptr->n_elements > 1) {\n" " ++emb_val->embval_index;\n" " }\n" @@ -1481,11 +1494,16 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " }\n" " break;\n" " }\n" - /*" else if (XML_READER_TYPE_TEXT == type && 0 != emb_val && !own_tag && get_nof_elements() > 0) {\n" + " else if (XML_READER_TYPE_TEXT == type && 0 != emb_val && !own_tag && val_ptr->n_elements > 0) {\n" " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n" - " emb_val->embval_array->set_embedded_value(emb_val->embval_index, emb_ustr);\n" + " if (0 != emb_val->embval_array_reg) {\n" + " (*emb_val->embval_array_reg)[emb_val->embval_index] = emb_ustr;\n" + " }\n" + " else {\n" + " (*emb_val->embval_array_opt)[emb_val->embval_index] = emb_ustr;\n" + " }\n" " rd_ok = p_reader.Read();\n" - " }\n" - temporarily removed in RT1 */ + " }\n" " else {\n" " rd_ok = p_reader.Read();\n" " }\n" @@ -1494,13 +1512,12 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " }\n" /* if not LIST */ " return 1;\n" "}\n\n" - , sdef->oftypedescrname, sdef->oftypedescrname ); } if (json_needed) { // JSON encode, RT1 src = mputprintf(src, - "int %s::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const\n" + "int %s::JSON_encode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok) const\n" "{\n" " if (!is_bound()) {\n" " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,\n" @@ -1509,18 +1526,18 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " }\n\n" " int enc_len = p_tok.put_next_token(JSON_TOKEN_ARRAY_START, NULL);\n" " for(int i = 0; i < val_ptr->n_elements; ++i) {\n" - " int ret_val = (*this)[i].JSON_encode(%s_descr_, p_tok);\n" + " int ret_val = (*this)[i].JSON_encode(*p_td.oftype_descr, p_tok);\n" " if (0 > ret_val) break;\n" " enc_len += ret_val;\n" " }\n" " enc_len += p_tok.put_next_token(JSON_TOKEN_ARRAY_END, NULL);\n" " return enc_len;\n" "}\n\n" - , name, dispname, sdef->oftypedescrname); + , name, dispname); // JSON decode, RT1 src = mputprintf(src, - "int %s::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent)\n" + "int %s::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent)\n" "{\n" " json_token_t token = JSON_TOKEN_NONE;\n" " int dec_len = p_tok.get_next_token(&token, NULL, NULL);\n" @@ -1535,7 +1552,7 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " while (true) {\n" " size_t buf_pos = p_tok.get_buf_pos();\n" " %s* val = new %s;\n" - " int ret_val = val->JSON_decode(%s_descr_, p_tok, p_silent);\n" + " int ret_val = val->JSON_decode(*p_td.oftype_descr, p_tok, p_silent);\n" " if (JSON_ERROR_INVALID_TOKEN == ret_val) {\n" " p_tok.set_buf_pos(buf_pos);\n" " delete val;\n" @@ -1564,7 +1581,7 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " }\n\n" " return dec_len;\n" "}\n\n" - , name, type, type, sdef->oftypedescrname, type); + , name, type, type, type); } /* end of class */ def = mputstr(def, "};\n\n"); @@ -1604,11 +1621,11 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct char *def = NULL, *src = NULL; const char *name = sdef->name, *dispname = sdef->dispname; const char *type = sdef->type; - boolean ber_needed = sdef->isASN1 && enable_ber(); - boolean raw_needed = sdef->hasRaw && enable_raw(); - boolean text_needed = sdef->hasText && enable_text(); - boolean xer_needed = sdef->hasXer && enable_xer(); - boolean json_needed = sdef->hasJson && enable_json(); + boolean ber_needed = force_gen_seof || (sdef->isASN1 && enable_ber()); + boolean raw_needed = force_gen_seof || (sdef->hasRaw && enable_raw()); + boolean text_needed = force_gen_seof || (sdef->hasText && enable_text()); + boolean xer_needed = force_gen_seof || (sdef->hasXer && enable_xer()); + boolean json_needed = force_gen_seof || (sdef->hasJson && enable_json()); /* Class definition and private data members */ def = mputprintf(def, @@ -1684,7 +1701,7 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct /* constructors */ def = mputprintf(def, "%s(): n_elements(-1), value_elements(NULL) {}\n", name); - def = mputprintf(def, "%s(null_type other_value): n_elements(0), value_elements(NULL) {}\n", name); + def = mputprintf(def, "%s(null_type): n_elements(0), value_elements(NULL) {}\n", name); /* copy constructor */ def = mputprintf(def, "%s(const %s& other_value) { copy_value(other_value); }\n", name, name); @@ -2176,7 +2193,7 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " p_buf.put_cs(*p_td.text->separator_encode);\n" " encoded_length+=p_td.text->separator_encode->lengthof();\n" " }\n" - " encoded_length+=value_elements[a].TEXT_encode(%s_descr_,p_buf);\n" + " encoded_length+=value_elements[a].TEXT_encode(*p_td.oftype_descr,p_buf);\n" " }\n" " if(p_td.text->end_encode){\n" " p_buf.put_cs(*p_td.text->end_encode);\n" @@ -2184,7 +2201,7 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " }\n" " return encoded_length;\n" "}\n" - ,name,sdef->oftypedescrname + ,name ); src = mputprintf(src, "int %s::TEXT_decode(const TTCN_Typedescriptor_t& p_td," @@ -2223,7 +2240,7 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " while(TRUE){\n" " %s val;\n" " pos=p_buf.get_pos();\n" - " int len=val.TEXT_decode(%s_descr_,p_buf,limit,TRUE);\n" + " int len=val.TEXT_decode(*p_td.oftype_descr,p_buf,limit,TRUE);\n" " if(len==-1 || (len==0 && !limit.has_token())){\n" " p_buf.set_pos(pos);\n" " if(sep_found){\n" @@ -2261,7 +2278,7 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " }\n" " }\n" " }\n" - ,name,type,sdef->oftypedescrname + ,name,type ); src = mputstr(src, " limit.remove_tokens(ml);\n" @@ -2315,7 +2332,7 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " for(int elem_i=0; elem_i<n_elements; elem_i++) {\n" " ec.set_msg(\"Component #%%d: \", elem_i);\n" " new_tlv->add_TLV(value_elements[elem_i].BER_encode_TLV" - "(%s_descr_, p_coding));\n" + "(*p_td.oftype_descr, p_coding));\n" " }\n" "%s" " }\n" @@ -2341,16 +2358,16 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " while(BER_decode_constdTLV_next(stripped_tlv, V_pos, L_form, " "tmp_tlv)) {\n" " set_size(n_elements+1);\n" - " value_elements[n_elements-1].BER_decode_TLV(%s_descr_, tmp_tlv, " + " value_elements[n_elements-1].BER_decode_TLV(*p_td.oftype_descr, tmp_tlv, " "L_form);\n" " ec_2.set_msg(\"%%d: \", n_elements);\n" " }\n" " return TRUE;\n" "}\n" "\n" - , name, sdef->oftypedescrname + , name , sdef->kind==SET_OF?" new_tlv->sort_tlvs();\n":"" - , name, sdef->oftypedescrname + , name ); if(sdef->has_opentypes) { @@ -2396,7 +2413,7 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " int a=0;\n" " if(sel_field==-1) sel_field=p_td.raw->fieldlength;\n" " for(a=0;a<sel_field;a++){\n" - " decoded_field_length=(*this)[a+start_field].RAW_decode(%s_descr_," + " decoded_field_length=(*this)[a+start_field].RAW_decode(*p_td.oftype_descr," "p_buf,limit,top_bit_ord,TRUE);\n" " if(decoded_field_length < 0) return decoded_field_length;\n" " decoded_length+=decoded_field_length;\n" @@ -2413,7 +2430,7 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " }\n" " while(limit>0){\n" " start_of_field=p_buf.get_pos_bit();\n" - " decoded_field_length=(*this)[a].RAW_decode(%s_descr_,p_buf,limit," + " decoded_field_length=(*this)[a].RAW_decode(*p_td.oftype_descr,p_buf,limit," "top_bit_ord,TRUE);\n" " if(decoded_field_length < 0){\n" /*" delete &(*this)[a];\n"*/ @@ -2427,7 +2444,7 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " decoded_length+=decoded_field_length;\n" " limit-=decoded_field_length;\n" " a++;\n" - ,name,sdef->oftypedescrname,sdef->oftypedescrname + ,name ); if(sdef->raw.extension_bit!=XDEFNO && sdef->raw.extension_bit!=XDEFDEFAULT){ src=mputprintf(src, @@ -2452,12 +2469,12 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " myleaf.body.node.nodes=init_nodes_of_enc_tree(encoded_num_of_records);\n" " for(int a=0;a<encoded_num_of_records;a++){\n" " myleaf.body.node.nodes[a]=new RAW_enc_tree(TRUE,&myleaf," - "&(myleaf.curr_pos),a,%s_descr_.raw);\n" - " encoded_length+=(*this)[a].RAW_encode(%s_descr_," + "&(myleaf.curr_pos),a,p_td.oftype_descr->raw);\n" + " encoded_length+=(*this)[a].RAW_encode(*p_td.oftype_descr," "*myleaf.body.node.nodes[a]);\n" " }\n" " return myleaf.length=encoded_length;\n}\n\n" - , name, sdef->oftypedescrname, sdef->oftypedescrname + , name ); } @@ -2471,10 +2488,12 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct "boolean %s::can_start(const char *name, const char *uri, " "XERdescriptor_t const& xd, unsigned int flavor) {\n" " boolean e_xer = is_exer(flavor);\n" - " if (e_xer && (xd.xer_bits & ANY_ELEMENT)) " + " if ((!e_xer || !(xd.xer_bits & UNTAGGED)) && !(flavor & XER_RECOF)) return " + "check_name(name, xd, e_xer) && (!e_xer || check_namespace(uri, xd));\n" + " if (e_xer && (xd.oftype_descr->xer_bits & ANY_ELEMENT)) " , name ); - if (sdef->nFollowers) { + if (!force_gen_seof && sdef->nFollowers) { /* If there are optional fields following the record-of, then seeing * {any XML tag that belongs to those fields} where the record-of may be * means that the record-of is empty. */ @@ -2494,12 +2513,9 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct else src = mputstr(src, "return TRUE;\n"); src = mputprintf(src, - " if ((!e_xer || !(xd.xer_bits & UNTAGGED)) && !(flavor & XER_RECOF)) return " - "check_name(name, xd, e_xer) && (!e_xer || check_namespace(uri, xd));\n" - " else return %s::can_start(name, uri, %s_xer_, flavor | XER_RECOF);\n" + " return %s::can_start(name, uri, *xd.oftype_descr, flavor | XER_RECOF);\n" "}\n\n" , sdef->type - , sdef->oftypedescrname ); src = mputprintf(src, @@ -2512,7 +2528,7 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " size_t num_new;\n" " for (int i = 0; i < n_elements; ++i) {\n" " bool def_ns_1 = false;" - " new_ns = value_elements[i].collect_ns(%s_xer_, num_new, def_ns_1);\n" + " new_ns = value_elements[i].collect_ns(*p_td.oftype_descr, num_new, def_ns_1);\n" " merge_ns(collected_ns, num_collected, new_ns, num_new);\n" " def_ns = def_ns || def_ns_1;\n" /* alas, no ||= */ " }\n" @@ -2527,7 +2543,7 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " num = num_collected;\n" " return collected_ns;\n" "}\n\n" - , name, sdef->oftypedescrname); + , name); src=mputprintf(src, "int %s::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, " @@ -2541,16 +2557,18 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct "%s" /* Factor out p_indent if not attribute */ " if (n_elements==0) {\n" /* Empty record of */ , name - , sdef->xerAttribute ? "" : " if (indenting) do_indent(p_buf, p_indent);\n" + , force_gen_seof ? " if (indenting && !(p_td.xer_bits & XER_ATTRIBUTE)) do_indent(p_buf, p_indent);\n" + : (sdef->xerAttribute ? "" : " if (indenting) do_indent(p_buf, p_indent);\n") ); - if (sdef->xerAttribute) { - src=mputstr(src, - " if (e_xer) {\n" /* Empty attribute. */ + if (force_gen_seof || sdef->xerAttribute) { + src=mputprintf(src, + " if (e_xer%s) {\n" /* Empty attribute. */ " begin_attribute(p_td, p_buf);\n" " p_buf.put_c('\\'');\n" - " } else\n"); + " } else\n" + , force_gen_seof ? " && (p_td.xer_bits & XER_ATTRIBUTE)" : ""); } - else { + if (force_gen_seof || !sdef->xerAttribute) { src = mputstr(src, " if (own_tag)"); } @@ -2578,7 +2596,8 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " }\n" " }\n" " else {\n" /* Not empty record of. Start tag or attribute */ - , sdef->xerAttribute ? " if (indenting) do_indent(p_buf, p_indent);\n" : "" + , force_gen_seof ? " if (indenting && !(p_td.xer_bits & XER_ATTRIBUTE)) do_indent(p_buf, p_indent);\n" + : (sdef->xerAttribute ? "" : " if (indenting) do_indent(p_buf, p_indent);\n") ); if (sdef->xerAnyAttrElem) { src = mputstr(src, @@ -2660,11 +2679,12 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " p_buf.put_s(shorter, saved);\n" /* restore the '>' and anything after */ " } else {\n"); } - if (sdef->xerAttribute) { - src=mputstr(src, - " if (e_xer) {\n" + if (force_gen_seof || sdef->xerAttribute) { + src=mputprintf(src, + " if (e_xer%s) {\n" " begin_attribute(p_td, p_buf);\n" - " } else\n"); + " } else\n" + , force_gen_seof ? " && (p_td.xer_bits & XER_ATTRIBUTE)" : ""); } src=mputprintf(src, " if (own_tag) {\n" @@ -2690,7 +2710,8 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " Free(collected_ns);\n" " p_buf.put_s(1 + keep_newline, (cbyte*)\">\\n\");\n" " }\n" - , sdef->xerAttribute ? " if (indenting) do_indent(p_buf, p_indent);\n" : "" + , force_gen_seof ? " if (indenting && (p_td.xer_bits & XER_ATTRIBUTE)) do_indent(p_buf, p_indent);\n" + : (sdef->xerAttribute ? " if (indenting) do_indent(p_buf, p_indent);\n" : "") ); if (sdef->xmlValueList) { src=mputstr(src, " if (indenting && !e_xer) do_indent(p_buf, p_indent+1);\n"); /* !e_xer or GDMO */ @@ -2701,20 +2722,26 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " TTCN_EncDec_ErrorContext ec_0(\"Index \");\n" " TTCN_EncDec_ErrorContext ec_1;\n" ); - src=mputprintf(src, + src=mputstr(src, " for (int i = 0; i < n_elements; ++i) {\n" - /*" if (i > 0 && !own_tag && 0 != emb_val &&\n" - " emb_val->embval_index < emb_val->embval_size) {\n" - " emb_val->embval_array->get_embedded_value(emb_val->embval_index).XER_encode(\n" - " UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n" + " if (i > 0 && !own_tag && 0 != emb_val &&\n" + " emb_val->embval_index < (0 != emb_val->embval_array_reg ?\n" + " emb_val->embval_array_reg->size_of() : emb_val->embval_array_opt->size_of())) {\n" + " if (0 != emb_val->embval_array_reg) {\n" + " (*emb_val->embval_array_reg)[emb_val->embval_index].XER_encode(\n" + " UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n" + " }\n" + " else {\n" + " (*emb_val->embval_array_opt)[emb_val->embval_index].XER_encode(\n" + " UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n" + " }\n" " ++emb_val->embval_index;\n" - " }\n" - temporarily removed in RT1 */ - " ec_1.set_msg(\"%%d: \", i);\n" + " }\n" + " ec_1.set_msg(\"%d: \", i);\n" " if (e_xer && (p_td.xer_bits & XER_LIST) && i>0) p_buf.put_c(' ');\n" - " value_elements[i].XER_encode(%s_xer_, p_buf, p_flavor, p_indent+own_tag, emb_val);\n" + " value_elements[i].XER_encode(*p_td.oftype_descr, p_buf, p_flavor, p_indent+own_tag, emb_val);\n" " }\n" - " if (indenting && !is_exerlist(p_flavor)) {\n", - sdef->oftypedescrname + " if (indenting && !is_exerlist(p_flavor)) {\n" ); if (sdef->xmlValueList) { src=mputstr(src, " if (!e_xer) p_buf.put_c('\\n');\n"); /* !e_xer or GDMO */ @@ -2722,10 +2749,11 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct src=mputstr(src, " do_indent(p_buf, p_indent);\n" " }\n"); - if (sdef->xerAttribute) { - src=mputstr(src, - " if (e_xer) p_buf.put_c('\\'');\n" - " else\n"); + if (force_gen_seof || sdef->xerAttribute) { + src=mputprintf(src, + " if (e_xer%s) p_buf.put_c('\\'');\n" + " else\n" + , force_gen_seof ? " && (p_td.xer_bits & XER_ATTRIBUTE)" : ""); } src=mputstr(src, " if (own_tag){\n" @@ -2787,7 +2815,7 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct , name ); - src = mputprintf(src, + src = mputstr(src, " if (e_xer && (p_td.xer_bits & XER_LIST)) {\n" /* LIST decoding*/ " char *x_val = (char*)p_reader.NewValue();\n" /* we own it */ " size_t x_pos = 0;\n" @@ -2801,13 +2829,13 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " x_pos += strlen(str) + 1;\n" " TTCN_Buffer buf_2;\n" " buf_2.put_c('<');\n" - " write_ns_prefix(%s_xer_, buf_2);\n" - " const char * const exer_name = %s_xer_.names[1];\n" - " boolean i_can_has_ns = %s_xer_.my_module != 0 && %s_xer_.ns_index != -1;\n" + " write_ns_prefix(*p_td.oftype_descr, buf_2);\n" + " const char * const exer_name = p_td.oftype_descr->names[1];\n" + " boolean i_can_has_ns = p_td.oftype_descr->my_module != 0 && p_td.oftype_descr->ns_index != -1;\n" /* If it has a namespace, chop off the '>' from the end */ - " buf_2.put_s((size_t)%s_xer_.namelens[1]-1-i_can_has_ns, (cbyte*)exer_name);\n" + " buf_2.put_s((size_t)p_td.oftype_descr->namelens[1]-1-i_can_has_ns, (cbyte*)exer_name);\n" " if (i_can_has_ns) {\n" - " const namespace_t * const pns = %s_xer_.my_module->get_ns(%s_xer_.ns_index);\n" + " const namespace_t * const pns = p_td.oftype_descr->my_module->get_ns(p_td.oftype_descr->ns_index);\n" " buf_2.put_s(7 - (*pns->px == 0), (cbyte*)\" xmlns:\");\n" " buf_2.put_s(strlen(pns->px), (cbyte*)pns->px);\n" " buf_2.put_s(2, (cbyte*)\"='\");\n" @@ -2818,14 +2846,14 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " buf_2.put_s(strlen(str), (cbyte*)str);\n" " buf_2.put_c('<');\n" " buf_2.put_c('/');\n" - " write_ns_prefix(%s_xer_, buf_2);\n" - " buf_2.put_s((size_t)%s_xer_.namelens[1], (cbyte*)exer_name);\n" + " write_ns_prefix(*p_td.oftype_descr, buf_2);\n" + " buf_2.put_s((size_t)p_td.oftype_descr->namelens[1], (cbyte*)exer_name);\n" " XmlReaderWrap reader_2(buf_2);\n" " rd_ok = reader_2.Read();\n" /* Move to the start element. */ /* Don't move to the #text, that's the callee's responsibility. */ /* The call to the non-const operator[] creates a new element object, * then we call its XER_decode with the temporary XML reader. */ - " (*this)[n_elements].XER_decode(%s_xer_, reader_2, p_flavor, 0);\n" + " (*this)[n_elements].XER_decode(*p_td.oftype_descr, reader_2, p_flavor, 0);\n" " if (p_flavor & EXIT_ON_ERROR && !(*this)[n_elements - 1].is_bound()) {\n" " if (1 == n_elements) {\n" // Failed to decode even the first element @@ -2847,11 +2875,6 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " p_reader.Read();\n" /* past it */ " }\n" " }\n" - , sdef->oftypedescrname, sdef->oftypedescrname - , sdef->oftypedescrname, sdef->oftypedescrname - , sdef->oftypedescrname, sdef->oftypedescrname - , sdef->oftypedescrname, sdef->oftypedescrname - , sdef->oftypedescrname, sdef->oftypedescrname ); src = mputprintf(src, @@ -2881,17 +2904,17 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " if (p_reader.NodeType() != XML_READER_TYPE_ELEMENT) rd_ok = p_reader.Read();\n" " } else"); } - src = mputprintf(src, + src = mputstr(src, " {\n" /* An untagged record-of ends if it encounters an element with a name * that doesn't match its component */ " if (!own_tag && !can_start((const char*)p_reader.LocalName(), " - "(const char*)p_reader.NamespaceUri(), %s_xer_, p_flavor)) {\n" + "(const char*)p_reader.NamespaceUri(), p_td, p_flavor)) {\n" " for (; rd_ok == 1 && p_reader.Depth() > xml_depth; rd_ok = p_reader.Read()) ;\n" " break;\n" " }\n" /* The call to the non-const operator[] creates the element */ - " operator [](n_elements).XER_decode(%s_xer_, p_reader, p_flavor, emb_val);\n" + " operator [](n_elements).XER_decode(*p_td.oftype_descr, p_reader, p_flavor, emb_val);\n" " if (0 != emb_val && !own_tag && n_elements > 1) {\n" " ++emb_val->embval_index;\n" " }\n" @@ -2905,11 +2928,16 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " }\n" " break;\n" " }\n" - /*" else if (XML_READER_TYPE_TEXT == type && 0 != emb_val && !own_tag && n_elements > 0) {\n" + " else if (XML_READER_TYPE_TEXT == type && 0 != emb_val && !own_tag && n_elements > 0) {\n" " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n" - " emb_val->embval_array->set_embedded_value(emb_val->embval_index, emb_ustr);\n" + " if (0 != emb_val->embval_array_reg) {\n" + " (*emb_val->embval_array_reg)[emb_val->embval_index] = emb_ustr;\n" + " }\n" + " else {\n" + " (*emb_val->embval_array_opt)[emb_val->embval_index] = emb_ustr;\n" + " }\n" " rd_ok = p_reader.Read();\n" - " }\n" - temporarily removed in RT1 */ + " }\n" " else {\n" " rd_ok = p_reader.Read();\n" " }\n" @@ -2918,13 +2946,12 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " }\n" /* if not LIST */ " return 1;\n" "}\n\n" - , sdef->oftypedescrname, sdef->oftypedescrname ); } if (json_needed) { // JSON encode, RT1, mem. alloc. optimised src = mputprintf(src, - "int %s::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const\n" + "int %s::JSON_encode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok) const\n" "{\n" " if (!is_bound()) {\n" " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,\n" @@ -2933,18 +2960,18 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " }\n\n" " int enc_len = p_tok.put_next_token(JSON_TOKEN_ARRAY_START, NULL);\n" " for(int i = 0; i < n_elements; ++i) {\n" - " int ret_val = value_elements[i].JSON_encode(%s_descr_, p_tok);\n" + " int ret_val = value_elements[i].JSON_encode(*p_td.oftype_descr, p_tok);\n" " if (0 > ret_val) break;\n" " enc_len += ret_val;\n" " }\n" " enc_len += p_tok.put_next_token(JSON_TOKEN_ARRAY_END, NULL);\n" " return enc_len;\n" "}\n\n" - , name, dispname, sdef->oftypedescrname); + , name, dispname); // JSON decode, RT1, mem. alloc. optimised src = mputprintf(src, - "int %s::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent)\n" + "int %s::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent)\n" "{\n" " json_token_t token = JSON_TOKEN_NONE;\n" " int dec_len = p_tok.get_next_token(&token, NULL, NULL);\n" @@ -2959,7 +2986,7 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " while (true) {\n" " size_t buf_pos = p_tok.get_buf_pos();\n" " %s val;\n" - " int ret_val = val.JSON_decode(%s_descr_, p_tok, p_silent);\n" + " int ret_val = val.JSON_decode(*p_td.oftype_descr, p_tok, p_silent);\n" " if (JSON_ERROR_INVALID_TOKEN == ret_val) {\n" " p_tok.set_buf_pos(buf_pos);\n" " break;\n" @@ -2984,7 +3011,7 @@ void defRecordOfClassMemAllocOptimized(const struct_of_def *sdef, output_struct " }\n\n" " return dec_len;\n" "}\n\n" - , name, type, sdef->oftypedescrname); + , name, type); } /* end of class */ def = mputstr(def, "};\n\n"); @@ -3024,8 +3051,8 @@ void defRecordOfClass2(const struct_of_def *sdef, output_struct *output) char *def = NULL, *src = NULL; const char *name = sdef->name; const char *type = sdef->type; - boolean raw_needed = sdef->hasRaw && enable_raw(); - boolean xer_needed = sdef->hasXer && enable_xer(); + boolean raw_needed = force_gen_seof || (sdef->hasRaw && enable_raw()); + boolean xer_needed = force_gen_seof || (sdef->hasXer && enable_xer()); /* Class definition */ def = mputprintf(def, @@ -3164,12 +3191,10 @@ void defRecordOfClass2(const struct_of_def *sdef, output_struct *output) src = mputprintf(src, "Base_Type* %s::create_elem() const { return new %s; }\n" "const Base_Type* %s::get_unbound_elem() const { return &UNBOUND_ELEM; }\n" - "const TTCN_Typedescriptor_t* %s::get_descriptor() const { return &%s_descr_; }\n" - "const TTCN_Typedescriptor_t* %s::get_elem_descr() const { return &%s_descr_; }\n\n", + "const TTCN_Typedescriptor_t* %s::get_descriptor() const { return &%s_descr_; }\n", name, type, name, - name, name, - name, sdef->oftypedescrname); + name, name); /* helper functions called by enc/dec members of the ancestor class */ if (raw_needed) { @@ -3194,13 +3219,20 @@ void defRecordOfClass2(const struct_of_def *sdef, output_struct *output) "boolean %s::can_start(const char *name, const char *uri, " "XERdescriptor_t const& xd, unsigned int flavor) {\n" " boolean e_xer = is_exer(flavor);\n" + /* if EXER and UNTAGGED, it can begin with the tag of the element, + * otherwise it must be the tag of the type itself, + * specified in the supplied parameter. + * If flavor contains UNTAGGED, that's a signal to go directly + * to the embedded type. */ + " if (!e_xer || !((xd.xer_bits|flavor) & UNTAGGED)) return " + "check_name(name, xd, e_xer) && (!e_xer || check_namespace(uri, xd));\n" /* a record-of with ANY-ELEMENT can start with any tag * :-( with some exceptions )-: */ - " if (e_xer && (xd.xer_bits & ANY_ELEMENT)) " + " if (e_xer && (xd.oftype_descr->xer_bits & ANY_ELEMENT)) " , name, name ); - if (sdef->nFollowers) { + if (!force_gen_seof && sdef->nFollowers) { size_t f; src = mputstr(src, "{\n"); for (f = 0; f < sdef->nFollowers; ++f) { @@ -3218,15 +3250,8 @@ void defRecordOfClass2(const struct_of_def *sdef, output_struct *output) src = mputstr(src, "return TRUE;\n"); } src = mputprintf(src, - /* if EXER and UNTAGGED, it can begin with the tag of the element, - * otherwise it must be the tag of the type itself, - * specified in the supplied parameter. - * If flavor contains UNTAGGED, that's a signal to go directly - * to the embedded type. */ - " if (!e_xer || !((xd.xer_bits|flavor) & UNTAGGED)) return " - "check_name(name, xd, e_xer) && (!e_xer || check_namespace(uri, xd));\n" - " else return %s::can_start(name, uri, %s_xer_, flavor | XER_RECOF);\n" - "}\n\n", sdef->type, sdef->oftypedescrname); + " return %s::can_start(name, uri, *xd.oftype_descr, flavor | XER_RECOF);\n" + "}\n\n", sdef->type); def = mputprintf(def, "boolean isXmlValueList() const { return %s; }\n\n", sdef->xmlValueList ? "TRUE" : "FALSE"); } diff --git a/compiler2/subtype.cc b/compiler2/subtype.cc index 29b023220..60f81ae5b 100644 --- a/compiler2/subtype.cc +++ b/compiler2/subtype.cc @@ -1930,6 +1930,9 @@ void SubType::chk_this_template(Template *templ) case Template::VALUE_RANGE: /* Should be canonical before */ break; + case Template::ALL_FROM: + case Template::VALUE_LIST_ALL_FROM: + break; case Template::SUPERSET_MATCH: case Template::SUBSET_MATCH: if (subtype!=ST_SETOF){ diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc index 7b0a70c77..8449e696b 100644 --- a/compiler2/ttcn3/AST_ttcn3.cc +++ b/compiler2/ttcn3/AST_ttcn3.cc @@ -205,7 +205,7 @@ namespace Ttcn { Node::set_fullname(p_fullname); for (size_t i = 0; i < refs.size(); i++) refs[i]->set_fullname(p_fullname + - ".<sub_reference" + Int2string(i + 1) + ">"); + ".<sub_reference" + Int2string(i + 1) + ">"); } void FieldOrArrayRefs::set_my_scope(Scope *p_scope) @@ -218,9 +218,9 @@ namespace Ttcn { for (size_t i = 0; i < refs.size(); i++) { FieldOrArrayRef *ref = refs[i]; if (ref->get_type() == FieldOrArrayRef::ARRAY_REF) { - Value *v = ref->get_val(); - v->set_lowerid_to_ref(); - if (v->is_unfoldable()) return true; + Value *v = ref->get_val(); + v->set_lowerid_to_ref(); + if (v->is_unfoldable()) return true; } } return false; @@ -312,38 +312,38 @@ namespace Ttcn { expr->expr = mputprintf(expr->expr, ".%s%s()", ((type!=0 && type->get_typetype()==Type::T_ANYTYPE) ? "AT_" : ""), id.get_name().c_str()); - if (type) { - CompField *cf = type->get_comp_byName(id); - // If the field is optional, the return type of the accessor is an - // OPTIONAL<T>. Write a call to OPTIONAL<T>::operator(), - // which "reaches into" the OPTIONAL to get the contained type T. - // Don't do this at the end of the reference chain. - // Accessor methods for a foo_template return a bar_template - // and OPTIONAL<> is not involved, hence no "()". - if (!is_template && i < n_refs - 1 && cf->get_is_optional()) - expr->expr = mputstr(expr->expr, "()"); + if (type) { + CompField *cf = type->get_comp_byName(id); + // If the field is optional, the return type of the accessor is an + // OPTIONAL<T>. Write a call to OPTIONAL<T>::operator(), + // which "reaches into" the OPTIONAL to get the contained type T. + // Don't do this at the end of the reference chain. + // Accessor methods for a foo_template return a bar_template + // and OPTIONAL<> is not involved, hence no "()". + if (!is_template && i < n_refs - 1 && cf->get_is_optional()) + expr->expr = mputstr(expr->expr, "()"); // Follow the field type. - type = cf->get_type(); - } + type = cf->get_type(); + } } else { // Generate code for array reference. expr->expr = mputc(expr->expr, '['); - ref->get_val()->generate_code_expr(expr); + ref->get_val()->generate_code_expr(expr); expr->expr = mputc(expr->expr, ']'); - if (type) { + if (type) { // Follow the embedded type. - switch (type->get_typetype()) { - case Type::T_SEQOF: - case Type::T_SETOF: - case Type::T_ARRAY: - type = type->get_ofType(); - break; - default: - // The index points to a string element. - // There are no further sub-references. - type = 0; - } // switch - } // if (type) + switch (type->get_typetype()) { + case Type::T_SEQOF: + case Type::T_SETOF: + case Type::T_ARRAY: + type = type->get_ofType(); + break; + default: + // The index points to a string element. + // There are no further sub-references. + type = 0; + } // switch + } // if (type) } // if (ref->get_type) } // next reference } @@ -451,10 +451,10 @@ namespace Ttcn { } /* Called by: - * Common::PortTypeBody::PortTypeBody - * Common::Type::Type - * Common::TypeMappingTarget::TypeMappingTarget - * Common::PatternString::ps_elem_t::chk_ref */ + * Common::PortTypeBody::PortTypeBody + * Common::Type::Type + * Common::TypeMappingTarget::TypeMappingTarget + * Common::PatternString::ps_elem_t::chk_ref */ Reference *Reference::clone() const { return new Reference(*this); @@ -465,8 +465,8 @@ namespace Ttcn { string ret_val; if (id) { if (modid) { - ret_val += modid->get_dispname(); - ret_val += '.'; + ret_val += modid->get_dispname(); + ret_val += '.'; } ret_val += id->get_dispname(); subrefs.append_stringRepr(ret_val); @@ -498,7 +498,7 @@ namespace Ttcn { parlist->set_my_scope(my_scope); } else { error("Reference to parameterized definition `%s' without " - "actual parameter list", ass->get_id().get_dispname().c_str()); + "actual parameter list", ass->get_id().get_dispname().c_str()); } } } @@ -531,7 +531,7 @@ namespace Ttcn { break; default: error("Reference to a variable or value parameter was " - "expected instead of %s", t_ass->get_description().c_str()); + "expected instead of %s", t_ass->get_description().c_str()); return 0; } FieldOrArrayRefs *t_subrefs = get_subrefs(); @@ -539,7 +539,7 @@ namespace Ttcn { Type::EXPECTED_DYNAMIC_VALUE); if (ret_val && t_subrefs && t_subrefs->refers_to_string_element()) { error("Reference to a string element of type `%s' cannot be used in " - "this context", ret_val->get_typename().c_str()); + "this context", ret_val->get_typename().c_str()); } return ret_val; } @@ -550,19 +550,19 @@ namespace Ttcn { if (ass) { if (ass->get_asstype() == Common::Assignment::A_TYPE) { Type *t = ass->get_Type()->get_type_refd_last(); - switch (t->get_typetype()) { - case Type::T_ERROR: - // remain silent - break; - case Type::T_COMPONENT: - return t; - default: - error("Reference `%s' does not refer to a component type", - get_dispname().c_str()); - } + switch (t->get_typetype()) { + case Type::T_ERROR: + // remain silent + break; + case Type::T_COMPONENT: + return t; + default: + error("Reference `%s' does not refer to a component type", + get_dispname().c_str()); + } } else { - error("Reference `%s' does not refer to a type", - get_dispname().c_str()); + error("Reference `%s' does not refer to a type", + get_dispname().c_str()); } } return 0; @@ -720,21 +720,21 @@ namespace Ttcn { FieldOrArrayRef *second_ref = subrefs.get_ref(1); if (second_ref->get_type() == FieldOrArrayRef::FIELD_REF) { // the reference begins with <id>.<id> (most complicated case) - // there are 3 possible situations: - // 1. first_id points to a local definition (this has the priority) - // modid: 0, id: first_id - // 2. first_id points to an imported module (trivial case) - // modid: first_id, id: second_id - // 3. none of the above (first_id might be an imported symbol) - // modid: 0, id: first_id - // Note: Rule 1 has the priority because it can be overridden using - // the notation <id>.objid { ... }.<id> (modid and id are set in the - // constructor), but there is no work-around in the reverse way. - if (!my_scope->has_ass_withId(*first_id) - && my_scope->is_valid_moduleid(*first_id)) { - // rule 1 is not fulfilled, but rule 2 is fulfilled - second_id = second_ref->get_id(); - } + // there are 3 possible situations: + // 1. first_id points to a local definition (this has the priority) + // modid: 0, id: first_id + // 2. first_id points to an imported module (trivial case) + // modid: first_id, id: second_id + // 3. none of the above (first_id might be an imported symbol) + // modid: 0, id: first_id + // Note: Rule 1 has the priority because it can be overridden using + // the notation <id>.objid { ... }.<id> (modid and id are set in the + // constructor), but there is no work-around in the reverse way. + if (!my_scope->has_ass_withId(*first_id) + && my_scope->is_valid_moduleid(*first_id)) { + // rule 1 is not fulfilled, but rule 2 is fulfilled + second_id = second_ref->get_id(); + } } // else: the reference begins with <id>[<arrayref>] -> there is no modid } // else: the reference consists of a single <id> -> there is no modid if (second_id) { @@ -804,14 +804,14 @@ namespace Ttcn { if (params_checked) { // used after semantic analysis for (size_t i = 0; i < parlist.get_nof_pars(); i++) { - if (i > 0) ret_val += ", "; - parlist.get_par(i)->append_stringRepr(ret_val); + if (i > 0) ret_val += ", "; + parlist.get_par(i)->append_stringRepr(ret_val); } } else { // used before semantic analysis for (size_t i = 0; i < params->get_nof_tis(); i++) { - if (i > 0) ret_val += ", "; - params->get_ti_byIndex(i)->append_stringRepr(ret_val); + if (i > 0) ret_val += ", "; + params->get_ti_byIndex(i)->append_stringRepr(ret_val); } } ret_val += ')'; @@ -826,17 +826,17 @@ namespace Ttcn { params_checked = true; FormalParList *fplist = ass->get_FormalParList(); if (fplist) { - Error_Context cntxt(params, "In actual parameter list of %s", - ass->get_description().c_str()); - is_erroneous = fplist->fold_named_and_chk(params, &parlist); - parlist.set_fullname(get_fullname()); - parlist.set_my_scope(my_scope); - // the parsed parameter list is no longer needed - delete params; - params = 0; + Error_Context cntxt(params, "In actual parameter list of %s", + ass->get_description().c_str()); + is_erroneous = fplist->fold_named_and_chk(params, &parlist); + parlist.set_fullname(get_fullname()); + parlist.set_my_scope(my_scope); + // the parsed parameter list is no longer needed + delete params; + params = 0; } else { params->error("The referenced %s cannot have actual parameters", - ass->get_description().c_str()); + ass->get_description().c_str()); } } return ass; @@ -864,7 +864,7 @@ namespace Ttcn { if (!t_ass) return false; if (t_ass->get_asstype() != Common::Assignment::A_ALTSTEP) { error("Reference to an altstep was expected in the argument instead of " - "%s", t_ass->get_description().c_str()); + "%s", t_ass->get_description().c_str()); return false; } my_scope->chk_runs_on_clause(t_ass, *this, "activate"); @@ -1048,11 +1048,11 @@ namespace Ttcn { const Identifier& id = comp_def->get_id(); if (parent_scope->has_ass_withId(id)) { comp_def->warning("Imported component element definition `%s' hides a " - "definition at module scope", comp_def->get_fullname().c_str()); - Reference ref(0, id.clone()); - Common::Assignment *hidden_ass = parent_scope->get_ass_bySRef(&ref); - hidden_ass->warning("Hidden definition `%s' is here", - hidden_ass->get_fullname().c_str()); + "definition at module scope", comp_def->get_fullname().c_str()); + Reference ref(0, id.clone()); + Common::Assignment *hidden_ass = parent_scope->get_ass_bySRef(&ref); + hidden_ass->warning("Hidden definition `%s' is here", + hidden_ass->get_fullname().c_str()); } } @@ -1424,12 +1424,12 @@ namespace Ttcn { duplicate_underscores ? module_name : modid->get_ttcnname().c_str()); target->functions.pre_init = mputprintf(target->functions.pre_init, - "%s%s.pre_init_module();\n", module_name, + "%s%s.pre_init_module();\n", module_name, "::module_object"); if (mod->get_moduletype() == Common::Module::MOD_TTCN) { target->functions.post_init = mputprintf(target->functions.post_init, - "%s%s.post_init_module();\n", module_name, + "%s%s.post_init_module();\n", module_name, "::module_object"); } @@ -1441,8 +1441,8 @@ namespace Ttcn { if (w_attrib_path) { MultiWithAttrib *attrib = w_attrib_path->get_with_attr(); if (attrib) { - DEBUG(level + 1, "Attributes:"); - attrib->dump(level + 2); + DEBUG(level + 1, "Attributes:"); + attrib->dump(level + 2); } } } @@ -1614,19 +1614,19 @@ namespace Ttcn { // imported module that imports m bool covered = false; for (size_t j = 0; j < impmods_v.size(); j++) { - // skip over the same import definition - if (j == i) continue; - ImpMod *im2 = impmods_v[j]; - Common::Module *m2 = im2->get_mod(); - // a module that is equivalent to the current module due to - // circular imports cannot be used to cover anything - if (m2->is_visible(my_mod)) continue; - if (m2->is_visible(m) && !m->is_visible(m2)) { - // m2 covers m (i.e. m is visible from m2) - // and they are not in the same import loop - covered = true; - break; - } + // skip over the same import definition + if (j == i) continue; + ImpMod *im2 = impmods_v[j]; + Common::Module *m2 = im2->get_mod(); + // a module that is equivalent to the current module due to + // circular imports cannot be used to cover anything + if (m2->is_visible(my_mod)) continue; + if (m2->is_visible(m) && !m->is_visible(m2)) { + // m2 covers m (i.e. m is visible from m2) + // and they are not in the same import loop + covered = true; + break; + } } // do not generate the #include if a covering module is found if (!covered) im->generate_code(target); @@ -1729,11 +1729,11 @@ namespace Ttcn { ass->error("Duplicate definition with name `%s'", dispname_str); ass_m[name]->note("Previous definition of `%s' is here", dispname_str); } else { - ass_m.add(name, ass); - if (parent_scope->is_valid_moduleid(id)) { - ass->warning("Definition with name `%s' hides a module identifier", - id.get_dispname().c_str()); - } + ass_m.add(name, ass); + if (parent_scope->is_valid_moduleid(id)) { + ass->warning("Definition with name `%s' hides a module identifier", + id.get_dispname().c_str()); + } } } checked = true; @@ -1756,26 +1756,26 @@ namespace Ttcn { const Identifier& id = def->get_id(); const string& name = id.get_name(); if (ass_m.has_key(name)) { - const char *dispname_str = id.get_dispname().c_str(); - def->error("Duplicate definition with name `%s'", dispname_str); - ass_m[name]->note("Previous definition of `%s' is here", dispname_str); + const char *dispname_str = id.get_dispname().c_str(); + def->error("Duplicate definition with name `%s'", dispname_str); + ass_m[name]->note("Previous definition of `%s' is here", dispname_str); } else { - ass_m.add(name, def); - if (parent_scope) { - if (parent_scope->has_ass_withId(id)) { - const char *dispname_str = id.get_dispname().c_str(); - def->error("Definition with identifier `%s' is not unique in the " - "scope hierarchy", dispname_str); - Reference ref(0, id.clone()); - Common::Assignment *ass = parent_scope->get_ass_bySRef(&ref); - if (!ass) FATAL_ERROR("OtherDefinitions::chk_for()"); - ass->note("Previous definition with identifier `%s' in higher " - "scope unit is here", dispname_str); - } else if (parent_scope->is_valid_moduleid(id)) { - def->warning("Definition with name `%s' hides a module identifier", - id.get_dispname().c_str()); - } - } + ass_m.add(name, def); + if (parent_scope) { + if (parent_scope->has_ass_withId(id)) { + const char *dispname_str = id.get_dispname().c_str(); + def->error("Definition with identifier `%s' is not unique in the " + "scope hierarchy", dispname_str); + Reference ref(0, id.clone()); + Common::Assignment *ass = parent_scope->get_ass_bySRef(&ref); + if (!ass) FATAL_ERROR("OtherDefinitions::chk_for()"); + ass->note("Previous definition with identifier `%s' in higher " + "scope unit is here", dispname_str); + } else if (parent_scope->is_valid_moduleid(id)) { + def->warning("Definition with name `%s' hides a module identifier", + id.get_dispname().c_str()); + } + } } def->chk(); } @@ -1914,15 +1914,15 @@ namespace Ttcn { const string& group_name = group_id.get_name(); if (ass_m.has_key(group_name)) { group->error("Group name `%s' clashes with a definition", - group_id.get_dispname().c_str()); + group_id.get_dispname().c_str()); ass_m[group_name]->note("Definition of `%s' is here", - group_id.get_dispname().c_str()); + group_id.get_dispname().c_str()); } if (group_m.has_key(group_name)) { group->error("Duplicate group with name `%s'", - group_id.get_dispname().c_str()); + group_id.get_dispname().c_str()); group_m[group_name]->note("Group `%s' is already defined here", - group_id.get_dispname().c_str()); + group_id.get_dispname().c_str()); } else group_m.add(group_name, group); } checked = true; @@ -1969,8 +1969,8 @@ namespace Ttcn { if (w_attrib_path) { MultiWithAttrib *attrib = w_attrib_path->get_with_attr(); if (attrib) { - DEBUG(level + 1, "Group Attributes:"); - attrib->dump(level + 2); + DEBUG(level + 1, "Group Attributes:"); + attrib->dump(level + 2); } } } @@ -2063,8 +2063,8 @@ namespace Ttcn { if (w_attrib_path) { MultiWithAttrib *attrib = w_attrib_path->get_with_attr(); if (attrib) { - DEBUG(level + 1, "Attributes:"); - attrib->dump(level + 2); + DEBUG(level + 1, "Attributes:"); + attrib->dump(level + 2); } } } @@ -2583,16 +2583,16 @@ namespace Ttcn { if(ass_m.has_key(group_name)) { group->error("Group name `%s' clashes with a definition", - group_id.get_dispname().c_str()); + group_id.get_dispname().c_str()); ass_m[group_name]->note("Definition of `%s' is here", - group_id.get_dispname().c_str()); + group_id.get_dispname().c_str()); } if(group_m.has_key(group_name)) { group->error("Duplicate group with name `%s'", - group_id.get_dispname().c_str()); + group_id.get_dispname().c_str()); group_m[group_name]->note("Group `%s' is already defined here", - group_id.get_dispname().c_str()); + group_id.get_dispname().c_str()); }else{ group_m.add(group_name,group_v[i]); } @@ -2645,8 +2645,8 @@ namespace Ttcn { if (w_attrib_path) { MultiWithAttrib *attrib = w_attrib_path->get_with_attr(); if (attrib) { - DEBUG(level, "Module Attributes:"); - attrib->dump(level + 1); + DEBUG(level, "Module Attributes:"); + attrib->dump(level + 1); } } } @@ -2920,8 +2920,8 @@ namespace Ttcn { if (w_attrib_path) { MultiWithAttrib *attrib = w_attrib_path->get_with_attr(); if (attrib) { - DEBUG(level + 1, "Definition Attributes:"); - attrib->dump(level + 2); + DEBUG(level + 1, "Definition Attributes:"); + attrib->dump(level + 2); } } if (erroneous_attrs) erroneous_attrs->dump(level+1); @@ -3260,7 +3260,7 @@ namespace Ttcn { if (p_def->get_asstype() != A_CONST) { const char *dispname_str = id->get_dispname().c_str(); error("Local definition `%s' is a constant, but the definition " - "inherited from component type `%s' is a %s", dispname_str, + "inherited from component type `%s' is a %s", dispname_str, p_def->get_my_scope()->get_fullname().c_str(), p_def->get_assname()); p_def->note("The inherited definition of `%s' is here", dispname_str); return false; @@ -3270,16 +3270,16 @@ namespace Ttcn { if (!type->is_identical(p_def_const->type)) { const char *dispname_str = id->get_dispname().c_str(); type->error("Local constant `%s' has type `%s', but the constant " - "inherited from component type `%s' has type `%s'", dispname_str, - type->get_typename().c_str(), + "inherited from component type `%s' has type `%s'", dispname_str, + type->get_typename().c_str(), p_def_const->get_my_scope()->get_fullname().c_str(), - p_def_const->type->get_typename().c_str()); + p_def_const->type->get_typename().c_str()); p_def_const->note("The inherited constant `%s' is here", dispname_str); return false; } else if (!(*value == *p_def_const->value)) { const char *dispname_str = id->get_dispname().c_str(); value->error("Local constant `%s' and the constant inherited from " - "component type `%s' have different values", dispname_str, + "component type `%s' have different values", dispname_str, p_def_const->get_my_scope()->get_fullname().c_str()); p_def_const->note("The inherited constant `%s' is here", dispname_str); return false; @@ -3515,8 +3515,6 @@ namespace Ttcn { map<Type*,void> type_chain; map<Type::typetype_t, void> not_allowed; not_allowed.add(Type::T_PORT, 0); - not_allowed.add(Type::T_COMPONENT, 0); - not_allowed.add(Type::T_DEFAULT, 0); Type *t = type->get_type_refd_last(); // if the type is valid the original will be returned Type::typetype_t tt = t->search_for_not_allowed_type(type_chain, not_allowed); @@ -3531,14 +3529,6 @@ namespace Ttcn { error("Type of module parameter cannot be signature `%s'", t->get_fullname().c_str()); break; - case Type::T_COMPONENT: - error("Type of module parameter cannot be or embed component `%s'", - t->get_fullname().c_str()); - break; - case Type::T_DEFAULT: - error("Type of module parameter cannot be or embed default `%s'", - t->get_fullname().c_str()); - break; case Type::T_FUNCTION: case Type::T_ALTSTEP: case Type::T_TESTCASE: @@ -3599,11 +3589,11 @@ namespace Ttcn { if (target->functions.log_param) { // this is not the first modulepar target->functions.log_param = mputprintf(target->functions.log_param, - "TTCN_Logger::log_event_str(\", %s := \");\n", dispname); + "TTCN_Logger::log_event_str(\", %s := \");\n", dispname); } else { // this is the first modulepar target->functions.log_param = mputprintf(target->functions.log_param, - "TTCN_Logger::log_event_str(\"%s := \");\n", dispname); + "TTCN_Logger::log_event_str(\"%s := \");\n", dispname); } target->functions.log_param = mputprintf(target->functions.log_param, "%s.log();\n", name); @@ -3767,11 +3757,11 @@ namespace Ttcn { if (target->functions.log_param) { // this is not the first modulepar target->functions.log_param = mputprintf(target->functions.log_param, - "TTCN_Logger::log_event_str(\", %s := \");\n", dispname); + "TTCN_Logger::log_event_str(\", %s := \");\n", dispname); } else { // this is the first modulepar target->functions.log_param = mputprintf(target->functions.log_param, - "TTCN_Logger::log_event_str(\"%s := \");\n", dispname); + "TTCN_Logger::log_event_str(\"%s := \");\n", dispname); } target->functions.log_param = mputprintf(target->functions.log_param, "%s.log();\n", name); @@ -4148,8 +4138,8 @@ namespace Ttcn { { if (iter->recurs_deriv_checked) break; else if (refch.add(iter->get_fullname())) - iter->recurs_deriv_checked = true; - else break; + iter->recurs_deriv_checked = true; + else break; } } recurs_deriv_checked = true; @@ -4170,8 +4160,8 @@ namespace Ttcn { fp_list->generate_code_defval(target); target->header.function_prototypes = mputprintf(target->header.function_prototypes, - "extern %s %s(%s);\n", - type_genname_str, template_name, formal_par_list); + "extern %s %s(%s);\n", + type_genname_str, template_name, formal_par_list); char *function_body = mprintf("%s %s(%s)\n" "{\n", type_genname_str, template_name, formal_par_list); function_body = create_location_object(function_body, "TEMPLATE", @@ -4179,24 +4169,24 @@ namespace Ttcn { if (base_template) { // modified template function_body = mputprintf(function_body, "%s ret_val(%s", - type_genname_str, - base_template->get_genname_from_scope(my_scope).c_str()); - if (base_template->fp_list) { - // the base template is also parameterized - function_body = mputc(function_body, '('); - size_t nof_base_pars = base_template->fp_list->get_nof_fps(); - for (size_t i = 0; i < nof_base_pars; i++) { - if (i > 0) function_body = mputstr(function_body, ", "); - function_body = mputstr(function_body, - fp_list->get_fp_byIndex(i)->get_id().get_name().c_str()); - } - function_body = mputc(function_body, ')'); - } - function_body = mputstr(function_body, ");\n"); + type_genname_str, + base_template->get_genname_from_scope(my_scope).c_str()); + if (base_template->fp_list) { + // the base template is also parameterized + function_body = mputc(function_body, '('); + size_t nof_base_pars = base_template->fp_list->get_nof_fps(); + for (size_t i = 0; i < nof_base_pars; i++) { + if (i > 0) function_body = mputstr(function_body, ", "); + function_body = mputstr(function_body, + fp_list->get_fp_byIndex(i)->get_id().get_name().c_str()); + } + function_body = mputc(function_body, ')'); + } + function_body = mputstr(function_body, ");\n"); } else { // simple template function_body = mputprintf(function_body, "%s ret_val;\n", - type_genname_str); + type_genname_str); } if (erroneous_attrs && erroneous_attrs->get_err_descr()) { function_body = erroneous_attrs->get_err_descr()-> @@ -4347,19 +4337,19 @@ namespace Ttcn { if (fp_list) { const char *dispname_str = id->get_dispname().c_str(); NOTSUPP("Code generation for parameterized local template `%s'", - dispname_str); + dispname_str); def = mputprintf(def, "/* NOT SUPPORTED: template %s */\n", dispname_str); init = mputprintf(init, "/* NOT SUPPORTED: template %s */\n", - dispname_str); + dispname_str); } else { // non-parameterized template // use the default constructor for initialization def = mputprintf(def, "%s %s;\n", - type->get_genname_template(my_scope).c_str(), genname_str); + type->get_genname_template(my_scope).c_str(), genname_str); if (base_template) { - // copy the base template with an assignment - init = mputprintf(init, "%s = %s;\n", genname_str, - base_template->get_genname_from_scope(my_scope).c_str()); + // copy the base template with an assignment + init = mputprintf(init, "%s = %s;\n", genname_str, + base_template->get_genname_from_scope(my_scope).c_str()); } // finally assign the body init = body->generate_code_init(init, genname_str); @@ -4471,7 +4461,7 @@ namespace Ttcn { if (p_def->get_asstype() != A_VAR) { const char *dispname_str = id->get_dispname().c_str(); error("Local definition `%s' is a variable, but the definition " - "inherited from component type `%s' is a %s", dispname_str, + "inherited from component type `%s' is a %s", dispname_str, p_def->get_my_scope()->get_fullname().c_str(), p_def->get_assname()); p_def->note("The inherited definition of `%s' is here", dispname_str); return false; @@ -4481,36 +4471,36 @@ namespace Ttcn { if (!type->is_identical(p_def_var->type)) { const char *dispname_str = id->get_dispname().c_str(); type->error("Local variable `%s' has type `%s', but the variable " - "inherited from component type `%s' has type `%s'", dispname_str, - type->get_typename().c_str(), + "inherited from component type `%s' has type `%s'", dispname_str, + type->get_typename().c_str(), p_def_var->get_my_scope()->get_fullname().c_str(), - p_def_var->type->get_typename().c_str()); + p_def_var->type->get_typename().c_str()); p_def_var->note("The inherited variable `%s' is here", dispname_str); return false; } if (initial_value) { if (p_def_var->initial_value) { if (!initial_value->is_unfoldable() && - !p_def_var->initial_value->is_unfoldable() && - !(*initial_value == *p_def_var->initial_value)) { - const char *dispname_str = id->get_dispname().c_str(); - initial_value->warning("Local variable `%s' and the variable " - "inherited from component type `%s' have different initial values", - dispname_str, p_def_var->get_my_scope()->get_fullname().c_str()); - p_def_var->note("The inherited variable `%s' is here", dispname_str); - } + !p_def_var->initial_value->is_unfoldable() && + !(*initial_value == *p_def_var->initial_value)) { + const char *dispname_str = id->get_dispname().c_str(); + initial_value->warning("Local variable `%s' and the variable " + "inherited from component type `%s' have different initial values", + dispname_str, p_def_var->get_my_scope()->get_fullname().c_str()); + p_def_var->note("The inherited variable `%s' is here", dispname_str); + } } else { - const char *dispname_str = id->get_dispname().c_str(); - initial_value->warning("Local variable `%s' has initial value, but " - "the variable inherited from component type `%s' does not", - dispname_str, p_def_var->get_my_scope()->get_fullname().c_str()); - p_def_var->note("The inherited variable `%s' is here", dispname_str); + const char *dispname_str = id->get_dispname().c_str(); + initial_value->warning("Local variable `%s' has initial value, but " + "the variable inherited from component type `%s' does not", + dispname_str, p_def_var->get_my_scope()->get_fullname().c_str()); + p_def_var->note("The inherited variable `%s' is here", dispname_str); } } else if (p_def_var->initial_value) { const char *dispname_str = id->get_dispname().c_str(); warning("Local variable `%s' does not have initial value, but the " - "variable inherited from component type `%s' has", dispname_str, - p_def_var->get_my_scope()->get_fullname().c_str()); + "variable inherited from component type `%s' has", dispname_str, + p_def_var->get_my_scope()->get_fullname().c_str()); p_def_var->note("The inherited variable `%s' is here", dispname_str); } return true; @@ -4547,15 +4537,15 @@ namespace Ttcn { // the initial value can be represented by a single C++ expression // the object is initialized by the constructor str = mputprintf(str, "%s %s(%s);\n", - type->get_genname_value(my_scope).c_str(), genname_str, - initial_value->get_single_expr().c_str()); + type->get_genname_value(my_scope).c_str(), genname_str, + initial_value->get_single_expr().c_str()); } else { // use the default constructor str = mputprintf(str, "%s %s;\n", - type->get_genname_value(my_scope).c_str(), genname_str); + type->get_genname_value(my_scope).c_str(), genname_str); if (initial_value) { - // the initial value is assigned using subsequent statements - str = initial_value->generate_code_init(str, genname_str); + // the initial value is assigned using subsequent statements + str = initial_value->generate_code_init(str, genname_str); } } return str; @@ -4577,7 +4567,7 @@ namespace Ttcn { { if (initial_value) { str = initial_value->generate_code_init(str, - base_defn->get_genname_from_scope(my_scope).c_str()); + base_defn->get_genname_from_scope(my_scope).c_str()); } return str; } @@ -4685,7 +4675,7 @@ namespace Ttcn { if (p_def->get_asstype() != A_VAR_TEMPLATE) { const char *dispname_str = id->get_dispname().c_str(); error("Local definition `%s' is a template variable, but the definition " - "inherited from component type `%s' is a %s", dispname_str, + "inherited from component type `%s' is a %s", dispname_str, p_def->get_my_scope()->get_fullname().c_str(), p_def->get_assname()); p_def->note("The inherited definition of `%s' is here", dispname_str); return false; @@ -4696,32 +4686,32 @@ namespace Ttcn { if (!type->is_identical(p_def_var_template->type)) { const char *dispname_str = id->get_dispname().c_str(); type->error("Local template variable `%s' has type `%s', but the " - "template variable inherited from component type `%s' has type `%s'", - dispname_str, type->get_typename().c_str(), + "template variable inherited from component type `%s' has type `%s'", + dispname_str, type->get_typename().c_str(), p_def_var_template->get_my_scope()->get_fullname().c_str(), - p_def_var_template->type->get_typename().c_str()); + p_def_var_template->type->get_typename().c_str()); p_def_var_template->note("The inherited template variable `%s' is here", - dispname_str); + dispname_str); return false; } if (initial_value) { if (!p_def_var_template->initial_value) { - const char *dispname_str = id->get_dispname().c_str(); - initial_value->warning("Local template variable `%s' has initial " - "value, but the template variable inherited from component type " - "`%s' does not", dispname_str, - p_def_var_template->get_my_scope()->get_fullname().c_str()); - p_def_var_template->note("The inherited template variable `%s' is here", - dispname_str); + const char *dispname_str = id->get_dispname().c_str(); + initial_value->warning("Local template variable `%s' has initial " + "value, but the template variable inherited from component type " + "`%s' does not", dispname_str, + p_def_var_template->get_my_scope()->get_fullname().c_str()); + p_def_var_template->note("The inherited template variable `%s' is here", + dispname_str); } } else if (p_def_var_template->initial_value) { const char *dispname_str = id->get_dispname().c_str(); warning("Local template variable `%s' does not have initial value, but " - "the template variable inherited from component type `%s' has", - dispname_str, - p_def_var_template->get_my_scope()->get_fullname().c_str()); + "the template variable inherited from component type `%s' has", + dispname_str, + p_def_var_template->get_my_scope()->get_fullname().c_str()); p_def_var_template->note("The inherited template variable `%s' is here", - dispname_str); + dispname_str); } return true; } @@ -4809,7 +4799,7 @@ namespace Ttcn { { if (initial_value) { str = initial_value->generate_code_init(str, - base_defn->get_genname_from_scope(my_scope).c_str()); + base_defn->get_genname_from_scope(my_scope).c_str()); if (template_restriction != TR_NONE && gen_restriction_check) str = Template::generate_restriction_check_code(str, base_defn->get_genname_from_scope(my_scope).c_str(), @@ -4892,7 +4882,7 @@ namespace Ttcn { if (p_def->get_asstype() != A_TIMER) { const char *dispname_str = id->get_dispname().c_str(); error("Local definition `%s' is a timer, but the definition inherited " - "from component type `%s' is a %s", dispname_str, + "from component type `%s' is a %s", dispname_str, p_def->get_my_scope()->get_fullname().c_str(), p_def->get_assname()); p_def->note("The inherited definition of `%s' is here", dispname_str); return false; @@ -4902,25 +4892,25 @@ namespace Ttcn { if (dimensions) { if (p_def_timer->dimensions) { if (!dimensions->is_identical(p_def_timer->dimensions)) { - const char *dispname_str = id->get_dispname().c_str(); - error("Local timer `%s' and the timer inherited from component type " - "`%s' have different array dimensions", dispname_str, + const char *dispname_str = id->get_dispname().c_str(); + error("Local timer `%s' and the timer inherited from component type " + "`%s' have different array dimensions", dispname_str, p_def_timer->get_my_scope()->get_fullname().c_str()); - p_def_timer->note("The inherited timer `%s' is here", dispname_str); - return false; - } + p_def_timer->note("The inherited timer `%s' is here", dispname_str); + return false; + } } else { - const char *dispname_str = id->get_dispname().c_str(); - error("Local definition `%s' is a timer array, but the definition " - "inherited from component type `%s' is a single timer", dispname_str, + const char *dispname_str = id->get_dispname().c_str(); + error("Local definition `%s' is a timer array, but the definition " + "inherited from component type `%s' is a single timer", dispname_str, p_def_timer->get_my_scope()->get_fullname().c_str()); - p_def_timer->note("The inherited timer `%s' is here", dispname_str); - return false; + p_def_timer->note("The inherited timer `%s' is here", dispname_str); + return false; } } else if (p_def_timer->dimensions) { const char *dispname_str = id->get_dispname().c_str(); error("Local definition `%s' is a single timer, but the definition " - "inherited from component type `%s' is a timer array", dispname_str, + "inherited from component type `%s' is a timer array", dispname_str, p_def_timer->get_my_scope()->get_fullname().c_str()); p_def_timer->note("The inherited timer `%s' is here", dispname_str); return false; @@ -4928,27 +4918,27 @@ namespace Ttcn { if (default_duration) { if (p_def_timer->default_duration) { if (!default_duration->is_unfoldable() && - !p_def_timer->default_duration->is_unfoldable() && - !(*default_duration == *p_def_timer->default_duration)) { - const char *dispname_str = id->get_dispname().c_str(); - default_duration->warning("Local timer `%s' and the timer inherited " - "from component type `%s' have different default durations", - dispname_str, p_def_timer->get_my_scope()->get_fullname().c_str()); - p_def_timer->note("The inherited timer `%s' is here", dispname_str); - } + !p_def_timer->default_duration->is_unfoldable() && + !(*default_duration == *p_def_timer->default_duration)) { + const char *dispname_str = id->get_dispname().c_str(); + default_duration->warning("Local timer `%s' and the timer inherited " + "from component type `%s' have different default durations", + dispname_str, p_def_timer->get_my_scope()->get_fullname().c_str()); + p_def_timer->note("The inherited timer `%s' is here", dispname_str); + } } else { - const char *dispname_str = id->get_dispname().c_str(); - default_duration->error("Local timer `%s' has default duration, but " - "the timer inherited from component type `%s' does not", dispname_str, + const char *dispname_str = id->get_dispname().c_str(); + default_duration->error("Local timer `%s' has default duration, but " + "the timer inherited from component type `%s' does not", dispname_str, p_def_timer->get_my_scope()->get_fullname().c_str()); - p_def_timer->note("The inherited timer `%s' is here", dispname_str); - return false; + p_def_timer->note("The inherited timer `%s' is here", dispname_str); + return false; } } else if (p_def_timer->default_duration) { const char *dispname_str = id->get_dispname().c_str(); error("Local timer `%s' does not have default duration, but the timer " - "inherited from component type `%s' has", dispname_str, - p_def_timer->get_my_scope()->get_fullname().c_str()); + "inherited from component type `%s' has", dispname_str, + p_def_timer->get_my_scope()->get_fullname().c_str()); p_def_timer->note("The inherited timer `%s' is here", dispname_str); return false; } @@ -5094,49 +5084,49 @@ namespace Ttcn { const string& array_type = dimensions->get_timer_type(); const char *array_type_str = array_type.c_str(); target->header.global_vars = mputprintf(target->header.global_vars, - "extern %s %s;\n", array_type_str, genname_str); + "extern %s %s;\n", array_type_str, genname_str); target->source.global_vars = mputprintf(target->source.global_vars, - "%s %s;\n", array_type_str, genname_str); + "%s %s;\n", array_type_str, genname_str); target->functions.pre_init = mputstr(target->functions.pre_init, "{\n" - "static const char * const timer_name = \""); + "static const char * const timer_name = \""); target->functions.pre_init = mputstr(target->functions.pre_init, - dispname.c_str()); + dispname.c_str()); target->functions.pre_init = mputprintf(target->functions.pre_init, - "\";\n" + "\";\n" "%s.set_name(timer_name);\n" - "}\n", genname_str); + "}\n", genname_str); if (default_duration) target->functions.post_init = - generate_code_array_duration(target->functions.post_init, genname_str, - default_duration); + generate_code_array_duration(target->functions.post_init, genname_str, + default_duration); } else { // single timer target->header.global_vars = mputprintf(target->header.global_vars, - "extern TIMER %s;\n", genname_str); + "extern TIMER %s;\n", genname_str); if (default_duration) { - // has default duration - Value *v = default_duration->get_value_refd_last(); - if (v->get_valuetype() == Value::V_REAL) { - // duration is known at compilation time -> set in the constructor - target->source.global_vars = mputprintf(target->source.global_vars, - "TIMER %s(\"%s\", %s);\n", genname_str, dispname.c_str(), - v->get_single_expr().c_str()); - } else { - // duration is known only at runtime -> set in post_init - target->source.global_vars = mputprintf(target->source.global_vars, - "TIMER %s(\"%s\");\n", genname_str, dispname.c_str()); - expression_struct expr; - Code::init_expr(&expr); - expr.expr = mputprintf(expr.expr, "%s.set_default_duration(", - genname_str); - default_duration->generate_code_expr(&expr); - expr.expr = mputc(expr.expr, ')'); - target->functions.post_init = - Code::merge_free_expr(target->functions.post_init, &expr); - } + // has default duration + Value *v = default_duration->get_value_refd_last(); + if (v->get_valuetype() == Value::V_REAL) { + // duration is known at compilation time -> set in the constructor + target->source.global_vars = mputprintf(target->source.global_vars, + "TIMER %s(\"%s\", %s);\n", genname_str, dispname.c_str(), + v->get_single_expr().c_str()); + } else { + // duration is known only at runtime -> set in post_init + target->source.global_vars = mputprintf(target->source.global_vars, + "TIMER %s(\"%s\");\n", genname_str, dispname.c_str()); + expression_struct expr; + Code::init_expr(&expr); + expr.expr = mputprintf(expr.expr, "%s.set_default_duration(", + genname_str); + default_duration->generate_code_expr(&expr); + expr.expr = mputc(expr.expr, ')'); + target->functions.post_init = + Code::merge_free_expr(target->functions.post_init, &expr); + } } else { - // does not have default duration - target->source.global_vars = mputprintf(target->source.global_vars, - "TIMER %s(\"%s\");\n", genname_str, dispname.c_str()); + // does not have default duration + target->source.global_vars = mputprintf(target->source.global_vars, + "TIMER %s(\"%s\");\n", genname_str, dispname.c_str()); } } } @@ -5274,33 +5264,33 @@ namespace Ttcn { const char *array_type_str = array_type.c_str(); str = mputprintf(str, "%s %s;\n", array_type_str, genname_str); str = mputstr(str, "{\n" - "static const char * const timer_name = \""); + "static const char * const timer_name = \""); str = mputstr(str, dispname.c_str()); str = mputprintf(str, "\";\n" "%s.set_name(timer_name);\n" - "}\n", genname_str); + "}\n", genname_str); if (default_duration) str = generate_code_array_duration(str, - genname_str, default_duration); + genname_str, default_duration); } else { // single timer if (default_duration && default_duration->has_single_expr()) { - // the default duration can be passed to the constructor - str = mputprintf(str, "TIMER %s(\"%s\", %s);\n", genname_str, - dispname.c_str(), default_duration->get_single_expr().c_str()); + // the default duration can be passed to the constructor + str = mputprintf(str, "TIMER %s(\"%s\", %s);\n", genname_str, + dispname.c_str(), default_duration->get_single_expr().c_str()); } else { - // only the name is passed to the constructor - str = mputprintf(str, "TIMER %s(\"%s\");\n", genname_str, - dispname.c_str()); - if (default_duration) { - // the default duration is set explicitly - expression_struct expr; - Code::init_expr(&expr); - expr.expr = mputprintf(expr.expr, "%s.set_default_duration(", - genname_str); - default_duration->generate_code_expr(&expr); - expr.expr = mputc(expr.expr, ')'); - str = Code::merge_free_expr(str, &expr); - } + // only the name is passed to the constructor + str = mputprintf(str, "TIMER %s(\"%s\");\n", genname_str, + dispname.c_str()); + if (default_duration) { + // the default duration is set explicitly + expression_struct expr; + Code::init_expr(&expr); + expr.expr = mputprintf(expr.expr, "%s.set_default_duration(", + genname_str); + default_duration->generate_code_expr(&expr); + expr.expr = mputc(expr.expr, ')'); + str = Code::merge_free_expr(str, &expr); + } } } return str; @@ -5321,39 +5311,39 @@ namespace Ttcn { const char *array_type_str = array_type.c_str(); def = mputprintf(def, "%s %s;\n", array_type_str, genname_str); def = mputstr(def, "{\n" - "static const char * const timer_names[] = { "); + "static const char * const timer_names[] = { "); def = dimensions->generate_element_names(def, dispname); def = mputprintf(def, " };\n" "%s.set_name(%lu, timer_names);\n" - "}\n", genname_str, (unsigned long) dimensions->get_array_size()); + "}\n", genname_str, (unsigned long) dimensions->get_array_size()); if (default_duration) init = generate_code_array_duration(init, - genname_str, default_duration); + genname_str, default_duration); } else { // single timer if (default_duration) { - // has default duration - Value *v = default_duration->get_value_refd_last(); - if (v->get_valuetype() == Value::V_REAL) { - // duration is known at compilation time -> set in the constructor - def = mputprintf(def, "TIMER %s(\"%s\", %s);\n", genname_str, - dispname.c_str(), v->get_single_expr().c_str()); - } else { - // duration is known only at runtime -> set when control reaches the - // timer definition - def = mputprintf(def, "TIMER %s(\"%s\");\n", genname_str, - dispname.c_str()); + // has default duration + Value *v = default_duration->get_value_refd_last(); + if (v->get_valuetype() == Value::V_REAL) { + // duration is known at compilation time -> set in the constructor + def = mputprintf(def, "TIMER %s(\"%s\", %s);\n", genname_str, + dispname.c_str(), v->get_single_expr().c_str()); + } else { + // duration is known only at runtime -> set when control reaches the + // timer definition + def = mputprintf(def, "TIMER %s(\"%s\");\n", genname_str, + dispname.c_str()); expression_struct expr; Code::init_expr(&expr); - expr.expr = mputprintf(expr.expr, "%s.set_default_duration(", - genname_str); - default_duration->generate_code_expr(&expr); - expr.expr = mputc(expr.expr, ')'); - init = Code::merge_free_expr(init, &expr); - } + expr.expr = mputprintf(expr.expr, "%s.set_default_duration(", + genname_str); + default_duration->generate_code_expr(&expr); + expr.expr = mputc(expr.expr, ')'); + init = Code::merge_free_expr(init, &expr); + } } else { - // does not have default duration - def = mputprintf(def, "TIMER %s(\"%s\");\n", genname_str, - dispname.c_str()); + // does not have default duration + def = mputprintf(def, "TIMER %s(\"%s\");\n", genname_str, + dispname.c_str()); } } } @@ -5363,25 +5353,25 @@ namespace Ttcn { if (default_duration) { Def_Timer *base_timer_defn = dynamic_cast<Def_Timer*>(base_defn); if (!base_timer_defn || !base_timer_defn->default_duration) - FATAL_ERROR("Def_Timer::generate_code_init_comp()"); + FATAL_ERROR("Def_Timer::generate_code_init_comp()"); // initializer is not needed if the default durations are the same // constants in both timers if (default_duration->is_unfoldable() || - base_timer_defn->default_duration->is_unfoldable() || - !(*default_duration == *base_timer_defn->default_duration)) { - if (dimensions) { - str = generate_code_array_duration(str, - base_timer_defn->get_genname_from_scope(my_scope).c_str(), - default_duration); - } else { - expression_struct expr; - Code::init_expr(&expr); - expr.expr = mputprintf(expr.expr, "%s.set_default_duration(", - base_timer_defn->get_genname_from_scope(my_scope).c_str()); - default_duration->generate_code_expr(&expr); - expr.expr = mputc(expr.expr, ')'); - str = Code::merge_free_expr(str, &expr); - } + base_timer_defn->default_duration->is_unfoldable() || + !(*default_duration == *base_timer_defn->default_duration)) { + if (dimensions) { + str = generate_code_array_duration(str, + base_timer_defn->get_genname_from_scope(my_scope).c_str(), + default_duration); + } else { + expression_struct expr; + Code::init_expr(&expr); + expr.expr = mputprintf(expr.expr, "%s.set_default_duration(", + base_timer_defn->get_genname_from_scope(my_scope).c_str()); + default_duration->generate_code_expr(&expr); + expr.expr = mputc(expr.expr, ')'); + str = Code::merge_free_expr(str, &expr); + } } } return str; @@ -5456,9 +5446,9 @@ namespace Ttcn { if (ass) { if (ass->get_asstype() == A_TYPE) { Type *t = ass->get_Type()->get_type_refd_last(); - if (t->get_typetype() == Type::T_PORT) port_type = t; - else type_ref->error("Type reference `%s' does not refer to a " - "port type", type_ref->get_dispname().c_str()); + if (t->get_typetype() == Type::T_PORT) port_type = t; + else type_ref->error("Type reference `%s' does not refer to a " + "port type", type_ref->get_dispname().c_str()); } else type_ref->error("Reference `%s' does not refer to a " "type", type_ref->get_dispname().c_str()); } @@ -5476,7 +5466,7 @@ namespace Ttcn { if (p_def->get_asstype() != A_PORT) { const char *dispname_str = id->get_dispname().c_str(); error("Local definition `%s' is a port, but the definition inherited " - "from component type `%s' is a %s", dispname_str, + "from component type `%s' is a %s", dispname_str, p_def->get_my_scope()->get_fullname().c_str(), p_def->get_assname()); p_def->note("The inherited definition of `%s' is here", dispname_str); return false; @@ -5484,38 +5474,38 @@ namespace Ttcn { Def_Port *p_def_port = dynamic_cast<Def_Port*>(p_def); if (!p_def_port) FATAL_ERROR("Def_Port::chk_identical()"); if (port_type && p_def_port->port_type && - port_type != p_def_port->port_type) { + port_type != p_def_port->port_type) { const char *dispname_str = id->get_dispname().c_str(); type_ref->error("Local port `%s' has type `%s', but the port inherited " - "from component type `%s' has type `%s'", dispname_str, - port_type->get_typename().c_str(), + "from component type `%s' has type `%s'", dispname_str, + port_type->get_typename().c_str(), p_def_port->get_my_scope()->get_fullname().c_str(), - p_def_port->port_type->get_typename().c_str()); + p_def_port->port_type->get_typename().c_str()); p_def_port->note("The inherited port `%s' is here", dispname_str); return false; } if (dimensions) { if (p_def_port->dimensions) { if (!dimensions->is_identical(p_def_port->dimensions)) { - const char *dispname_str = id->get_dispname().c_str(); - error("Local port `%s' and the port inherited from component type " - "`%s' have different array dimensions", dispname_str, + const char *dispname_str = id->get_dispname().c_str(); + error("Local port `%s' and the port inherited from component type " + "`%s' have different array dimensions", dispname_str, p_def_port->get_my_scope()->get_fullname().c_str()); - p_def_port->note("The inherited port `%s' is here", dispname_str); - return false; - } + p_def_port->note("The inherited port `%s' is here", dispname_str); + return false; + } } else { - const char *dispname_str = id->get_dispname().c_str(); - error("Local definition `%s' is a port array, but the definition " - "inherited from component type `%s' is a single port", dispname_str, + const char *dispname_str = id->get_dispname().c_str(); + error("Local definition `%s' is a port array, but the definition " + "inherited from component type `%s' is a single port", dispname_str, p_def_port->get_my_scope()->get_fullname().c_str()); - p_def_port->note("The inherited port `%s' is here", dispname_str); - return false; + p_def_port->note("The inherited port `%s' is here", dispname_str); + return false; } } else if (p_def_port->dimensions) { const char *dispname_str = id->get_dispname().c_str(); error("Local definition `%s' is a single port, but the definition " - "inherited from component type `%s' is a port array", dispname_str, + "inherited from component type `%s' is a port array", dispname_str, p_def_port->get_my_scope()->get_fullname().c_str()); p_def_port->note("The inherited port `%s' is here", dispname_str); return false; @@ -5534,24 +5524,24 @@ namespace Ttcn { const string& array_type = dimensions->get_port_type(type_genname); const char *array_type_str = array_type.c_str(); target->header.global_vars = mputprintf(target->header.global_vars, - "extern %s %s;\n", array_type_str, genname_str); + "extern %s %s;\n", array_type_str, genname_str); target->source.global_vars = mputprintf(target->source.global_vars, - "%s %s;\n", array_type_str, genname_str); + "%s %s;\n", array_type_str, genname_str); target->functions.pre_init = mputstr(target->functions.pre_init, "{\n" - "static const char * const port_name = \""); + "static const char * const port_name = \""); target->functions.pre_init = mputstr(target->functions.pre_init, - dispname.c_str()); + dispname.c_str()); target->functions.pre_init = mputprintf(target->functions.pre_init, - "\";\n" + "\";\n" "%s.set_name(port_name);\n" - "}\n", genname_str); + "}\n", genname_str); } else { // single port const char *type_genname_str = type_genname.c_str(); target->header.global_vars = mputprintf(target->header.global_vars, - "extern %s %s;\n", type_genname_str, genname_str); + "extern %s %s;\n", type_genname_str, genname_str); target->source.global_vars = mputprintf(target->source.global_vars, - "%s %s(\"%s\");\n", type_genname_str, genname_str, dispname.c_str()); + "%s %s(\"%s\");\n", type_genname_str, genname_str, dispname.c_str()); } target->functions.init_comp = mputprintf(target->functions.init_comp, "%s.activate_port();\n", genname_str); @@ -5584,21 +5574,21 @@ namespace Ttcn { { if (is_external) { if (has_return_type) { - if (returns_template) return A_EXT_FUNCTION_RTEMP; - else return A_EXT_FUNCTION_RVAL; + if (returns_template) return A_EXT_FUNCTION_RTEMP; + else return A_EXT_FUNCTION_RVAL; } else { - if (returns_template) - FATAL_ERROR("Def_Function_Base::determine_asstype()"); - return A_EXT_FUNCTION; + if (returns_template) + FATAL_ERROR("Def_Function_Base::determine_asstype()"); + return A_EXT_FUNCTION; } } else { // not an external function if (has_return_type) { - if (returns_template) return A_FUNCTION_RTEMP; - else return A_FUNCTION_RVAL; + if (returns_template) return A_FUNCTION_RTEMP; + else return A_FUNCTION_RVAL; } else { - if (returns_template) - FATAL_ERROR("Def_Function_Base::determine_asstype()"); - return A_FUNCTION; + if (returns_template) + FATAL_ERROR("Def_Function_Base::determine_asstype()"); + return A_FUNCTION; } } } @@ -5616,8 +5606,8 @@ namespace Ttcn { FormalParList *p_fpl, Type *p_return_type, bool returns_template, template_restriction_t p_template_restriction) : Definition(determine_asstype(is_external, p_return_type != 0, - returns_template), p_id), fp_list(p_fpl), return_type(p_return_type), - prototype(PROTOTYPE_NONE), input_type(0), output_type(0), + returns_template), p_id), fp_list(p_fpl), return_type(p_return_type), + prototype(PROTOTYPE_NONE), input_type(0), output_type(0), template_restriction(p_template_restriction) { if (!p_fpl) FATAL_ERROR("Def_Function_Base::Def_Function_Base()"); @@ -5693,100 +5683,100 @@ namespace Ttcn { // checking the formal parameter list if (prototype == PROTOTYPE_CONVERT) { if (fp_list->get_nof_fps() == 1) { - FormalPar *par = fp_list->get_fp_byIndex(0); - if (par->get_asstype() == A_PAR_VAL_IN) { - input_type = par->get_Type(); - } else { - par->error("The parameter must be an `in' value parameter for " - "attribute `prototype(%s)' instead of %s", get_prototype_name(), - par->get_assname()); - } + FormalPar *par = fp_list->get_fp_byIndex(0); + if (par->get_asstype() == A_PAR_VAL_IN) { + input_type = par->get_Type(); + } else { + par->error("The parameter must be an `in' value parameter for " + "attribute `prototype(%s)' instead of %s", get_prototype_name(), + par->get_assname()); + } } else { - fp_list->error("The function must have one parameter instead of %lu " - "for attribute `prototype(%s)'", (unsigned long) fp_list->get_nof_fps(), - get_prototype_name()); + fp_list->error("The function must have one parameter instead of %lu " + "for attribute `prototype(%s)'", (unsigned long) fp_list->get_nof_fps(), + get_prototype_name()); } } else { // not PROTOTYPE_CONVERT if (fp_list->get_nof_fps() == 2) { - FormalPar *first_par = fp_list->get_fp_byIndex(0); - if (prototype == PROTOTYPE_SLIDING) { - if (first_par->get_asstype() == A_PAR_VAL_INOUT) { - Type *first_par_type = first_par->get_Type(); - switch (first_par_type->get_type_refd_last() - ->get_typetype_ttcn3()) { - case Type::T_ERROR: - case Type::T_OSTR: - case Type::T_CSTR: - case Type::T_BSTR: - input_type = first_par_type; - break; - default: - first_par_type->error("The type of the first parameter must be " - "`octetstring' or `charstring' or `bitstring' for attribute " - "`prototype(%s)' instead of `%s'", get_prototype_name(), - first_par_type->get_typename().c_str()); - } - } else { - first_par->error("The first parameter must be an `inout' value " - "parameter for attribute `prototype(%s)' instead of %s", - get_prototype_name(), first_par->get_assname()); - } - } else { - if (first_par->get_asstype() == A_PAR_VAL_IN) { - input_type = first_par->get_Type(); - } else { - first_par->error("The first parameter must be an `in' value " - "parameter for attribute `prototype(%s)' instead of %s", - get_prototype_name(), first_par->get_assname()); - } - } - FormalPar *second_par = fp_list->get_fp_byIndex(1); - if (second_par->get_asstype() == A_PAR_VAL_OUT) { - output_type = second_par->get_Type(); - } else { - second_par->error("The second parameter must be an `out' value " - "parameter for attribute `prototype(%s)' instead of %s", - get_prototype_name(), second_par->get_assname()); - } + FormalPar *first_par = fp_list->get_fp_byIndex(0); + if (prototype == PROTOTYPE_SLIDING) { + if (first_par->get_asstype() == A_PAR_VAL_INOUT) { + Type *first_par_type = first_par->get_Type(); + switch (first_par_type->get_type_refd_last() + ->get_typetype_ttcn3()) { + case Type::T_ERROR: + case Type::T_OSTR: + case Type::T_CSTR: + case Type::T_BSTR: + input_type = first_par_type; + break; + default: + first_par_type->error("The type of the first parameter must be " + "`octetstring' or `charstring' or `bitstring' for attribute " + "`prototype(%s)' instead of `%s'", get_prototype_name(), + first_par_type->get_typename().c_str()); + } + } else { + first_par->error("The first parameter must be an `inout' value " + "parameter for attribute `prototype(%s)' instead of %s", + get_prototype_name(), first_par->get_assname()); + } + } else { + if (first_par->get_asstype() == A_PAR_VAL_IN) { + input_type = first_par->get_Type(); + } else { + first_par->error("The first parameter must be an `in' value " + "parameter for attribute `prototype(%s)' instead of %s", + get_prototype_name(), first_par->get_assname()); + } + } + FormalPar *second_par = fp_list->get_fp_byIndex(1); + if (second_par->get_asstype() == A_PAR_VAL_OUT) { + output_type = second_par->get_Type(); + } else { + second_par->error("The second parameter must be an `out' value " + "parameter for attribute `prototype(%s)' instead of %s", + get_prototype_name(), second_par->get_assname()); + } } else { - fp_list->error("The function must have two parameters for attribute " - "`prototype(%s)' instead of %lu", get_prototype_name(), - (unsigned long) fp_list->get_nof_fps()); + fp_list->error("The function must have two parameters for attribute " + "`prototype(%s)' instead of %lu", get_prototype_name(), + (unsigned long) fp_list->get_nof_fps()); } } // checking the return type if (prototype == PROTOTYPE_FAST) { if (return_type) { - return_type->error("The function cannot have return type for " - "attribute `prototype(%s)'", get_prototype_name()); + return_type->error("The function cannot have return type for " + "attribute `prototype(%s)'", get_prototype_name()); } } else { if (return_type) { - if (asstype == A_FUNCTION_RTEMP || asstype == A_EXT_FUNCTION_RTEMP) - return_type->error("The function must return a value instead of a " - "template for attribute `prototype(%s)'", get_prototype_name()); - if (prototype == PROTOTYPE_CONVERT) { - output_type = return_type; - } else { - switch (return_type->get_type_refd_last()->get_typetype_ttcn3()) { - case Type::T_ERROR: - case Type::T_INT: - break; - default: - return_type->error("The return type of the function must be " - "`integer' instead of `%s' for attribute `prototype(%s)'", - return_type->get_typename().c_str(), get_prototype_name()); - } - } + if (asstype == A_FUNCTION_RTEMP || asstype == A_EXT_FUNCTION_RTEMP) + return_type->error("The function must return a value instead of a " + "template for attribute `prototype(%s)'", get_prototype_name()); + if (prototype == PROTOTYPE_CONVERT) { + output_type = return_type; + } else { + switch (return_type->get_type_refd_last()->get_typetype_ttcn3()) { + case Type::T_ERROR: + case Type::T_INT: + break; + default: + return_type->error("The return type of the function must be " + "`integer' instead of `%s' for attribute `prototype(%s)'", + return_type->get_typename().c_str(), get_prototype_name()); + } + } } else { - error("The function must have return type for attribute " - "`prototype(%s)'", get_prototype_name()); + error("The function must have return type for attribute " + "`prototype(%s)'", get_prototype_name()); } } // checking the 'runs on' clause if (get_RunsOnType()) { error("The function cannot have `runs on' clause for attribute " - "`prototype(%s)'", get_prototype_name()); + "`prototype(%s)'", get_prototype_name()); } } @@ -5814,8 +5804,8 @@ namespace Ttcn { StatementBlock *p_block) : Def_Function_Base(false, p_id, p_fpl, p_return_type, returns_template, p_template_restriction), - runs_on_ref(p_runs_on_ref), runs_on_type(0), block(p_block), - is_startable(false), transparent(false) + runs_on_ref(p_runs_on_ref), runs_on_type(0), block(p_block), + is_startable(false), transparent(false) { if (!p_block) FATAL_ERROR("Def_Function::Def_Function()"); block->set_my_def(this); @@ -5891,7 +5881,7 @@ namespace Ttcn { is_startable = runs_on_ref != 0; if (is_startable && !fp_list->get_startability()) is_startable = false; if (is_startable && return_type && return_type->is_component_internal()) - is_startable = false; + is_startable = false; // checking of statement block block->chk(); if (return_type) { @@ -5899,13 +5889,13 @@ namespace Ttcn { switch (block->has_return()) { case StatementBlock::RS_NO: error("The function has return type, but it does not have any return " - "statement"); + "statement"); break; case StatementBlock::RS_MAYBE: - error("The function has return type, but control might leave it " - "without reaching a return statement"); + error("The function has return type, but control might leave it " + "without reaching a return statement"); default: - break; + break; } } if (!semantic_check_only) { @@ -6002,7 +5992,7 @@ namespace Ttcn { // function prototype target->header.function_prototypes = mputprintf(target->header.function_prototypes, "extern %s %s(%s);\n", - return_type_str, genname_str, formal_par_list); + return_type_str, genname_str, formal_par_list); // function body char *body = mprintf("%s %s(%s)\n" @@ -6020,107 +6010,107 @@ namespace Ttcn { if (is_startable) { size_t nof_fps = fp_list->get_nof_fps(); // starter function (stub) - // function prototype - target->header.function_prototypes = - mputprintf(target->header.function_prototypes, - "extern void start_%s(const COMPONENT& component_reference%s%s);\n", - genname_str, nof_fps>0?", ":"", formal_par_list); - // function body - body = mprintf("void start_%s(const COMPONENT& component_reference%s" - "%s)\n" - "{\n" - "TTCN_Logger::begin_event(TTCN_Logger::PARALLEL_PTC);\n" - "TTCN_Logger::log_event_str(\"Starting function %s(\");\n", - genname_str, nof_fps>0?", ":"", formal_par_list, dispname_str); - for (size_t i = 0; i < nof_fps; i++) { - if (i > 0) body = mputstr(body, + // function prototype + target->header.function_prototypes = + mputprintf(target->header.function_prototypes, + "extern void start_%s(const COMPONENT& component_reference%s%s);\n", + genname_str, nof_fps>0?", ":"", formal_par_list); + // function body + body = mprintf("void start_%s(const COMPONENT& component_reference%s" + "%s)\n" + "{\n" + "TTCN_Logger::begin_event(TTCN_Logger::PARALLEL_PTC);\n" + "TTCN_Logger::log_event_str(\"Starting function %s(\");\n", + genname_str, nof_fps>0?", ":"", formal_par_list, dispname_str); + for (size_t i = 0; i < nof_fps; i++) { + if (i > 0) body = mputstr(body, "TTCN_Logger::log_event_str(\", \");\n"); - body = mputprintf(body, "%s.log();\n", - fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str()); - } - body = mputprintf(body, - "TTCN_Logger::log_event_str(\") on component \");\n" - "component_reference.log();\n" - "TTCN_Logger::log_char('.');\n" - "TTCN_Logger::end_event();\n" - "Text_Buf text_buf;\n" - "TTCN_Runtime::prepare_start_component(component_reference, " - "\"%s\", \"%s\", text_buf);\n", - my_scope->get_scope_mod()->get_modid().get_dispname().c_str(), - dispname_str); - for (size_t i = 0; i < nof_fps; i++) { - body = mputprintf(body, "%s.encode_text(text_buf);\n", - fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str()); - } - body = mputstr(body, "TTCN_Runtime::send_start_component(text_buf);\n" - "}\n\n"); - target->source.function_bodies = mputstr(target->source.function_bodies, - body); - Free(body); + body = mputprintf(body, "%s.log();\n", + fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str()); + } + body = mputprintf(body, + "TTCN_Logger::log_event_str(\") on component \");\n" + "component_reference.log();\n" + "TTCN_Logger::log_char('.');\n" + "TTCN_Logger::end_event();\n" + "Text_Buf text_buf;\n" + "TTCN_Runtime::prepare_start_component(component_reference, " + "\"%s\", \"%s\", text_buf);\n", + my_scope->get_scope_mod()->get_modid().get_dispname().c_str(), + dispname_str); + for (size_t i = 0; i < nof_fps; i++) { + body = mputprintf(body, "%s.encode_text(text_buf);\n", + fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str()); + } + body = mputstr(body, "TTCN_Runtime::send_start_component(text_buf);\n" + "}\n\n"); + target->source.function_bodies = mputstr(target->source.function_bodies, + body); + Free(body); // an entry in start_ptc_function body = mprintf("if (!strcmp(function_name, \"%s\")) {\n", - dispname_str); + dispname_str); if (nof_fps > 0) { - body = fp_list->generate_code_object(body, "", ' '); - for (size_t i = 0; i < nof_fps; i++) { - body = mputprintf(body, "%s.decode_text(function_arguments);\n", - fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str()); - } - body = mputprintf(body, - "TTCN_Logger::begin_event(TTCN_Logger::PARALLEL_PTC);\n" - "TTCN_Logger::log_event_str(\"Starting function %s(\");\n", - dispname_str); - for (size_t i = 0; i < nof_fps; i++) { - if (i > 0) body = mputstr(body, + body = fp_list->generate_code_object(body, "", ' '); + for (size_t i = 0; i < nof_fps; i++) { + body = mputprintf(body, "%s.decode_text(function_arguments);\n", + fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str()); + } + body = mputprintf(body, + "TTCN_Logger::begin_event(TTCN_Logger::PARALLEL_PTC);\n" + "TTCN_Logger::log_event_str(\"Starting function %s(\");\n", + dispname_str); + for (size_t i = 0; i < nof_fps; i++) { + if (i > 0) body = mputstr(body, "TTCN_Logger::log_event_str(\", \");\n"); - body = mputprintf(body, "%s.log();\n", - fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str()); - } - body = mputstr(body, "TTCN_Logger::log_event_str(\").\");\n" - "TTCN_Logger::end_event();\n"); + body = mputprintf(body, "%s.log();\n", + fp_list->get_fp_byIndex(i)->get_reference_name(my_scope).c_str()); + } + body = mputstr(body, "TTCN_Logger::log_event_str(\").\");\n" + "TTCN_Logger::end_event();\n"); } else { - body = mputprintf(body, - "TTCN_Logger::log_str(TTCN_Logger::PARALLEL_PTC, \"Starting function " + body = mputprintf(body, + "TTCN_Logger::log_str(TTCN_Logger::PARALLEL_PTC, \"Starting function " "%s().\");\n", dispname_str); } body = mputstr(body, - "TTCN_Runtime::function_started(function_arguments);\n"); + "TTCN_Runtime::function_started(function_arguments);\n"); char *actual_par_list = - fp_list->generate_code_actual_parlist(memptystr(), ""); + fp_list->generate_code_actual_parlist(memptystr(), ""); bool return_value_kept = false; if (asstype == A_FUNCTION_RVAL) { - // the return value is kept only if the function returns a value - // (rather than a template) and the return type has the "done" - // extension attribute - for (Type *t = return_type; ; t = t->get_type_refd()) { - if (t->has_done_attribute()) { - return_value_kept = true; - break; - } else if (!t->is_ref()) break; - } + // the return value is kept only if the function returns a value + // (rather than a template) and the return type has the "done" + // extension attribute + for (Type *t = return_type; ; t = t->get_type_refd()) { + if (t->has_done_attribute()) { + return_value_kept = true; + break; + } else if (!t->is_ref()) break; + } } if (return_value_kept) { - const string& return_type_dispname = return_type->get_typename(); - const char *return_type_dispname_str = return_type_dispname.c_str(); - body = mputprintf(body, "%s ret_val(%s(%s));\n" - "TTCN_Logger::begin_event(TTCN_PARALLEL);\n" - "TTCN_Logger::log_event_str(\"Function %s returned %s : \");\n" - "ret_val.log();\n" - "Text_Buf text_buf;\n" - "TTCN_Runtime::prepare_function_finished(\"%s\", text_buf);\n" - "ret_val.encode_text(text_buf);\n" - "TTCN_Runtime::send_function_finished(text_buf);\n", - return_type_str, genname_str, actual_par_list, dispname_str, - return_type_dispname_str, return_type_dispname_str); + const string& return_type_dispname = return_type->get_typename(); + const char *return_type_dispname_str = return_type_dispname.c_str(); + body = mputprintf(body, "%s ret_val(%s(%s));\n" + "TTCN_Logger::begin_event(TTCN_PARALLEL);\n" + "TTCN_Logger::log_event_str(\"Function %s returned %s : \");\n" + "ret_val.log();\n" + "Text_Buf text_buf;\n" + "TTCN_Runtime::prepare_function_finished(\"%s\", text_buf);\n" + "ret_val.encode_text(text_buf);\n" + "TTCN_Runtime::send_function_finished(text_buf);\n", + return_type_str, genname_str, actual_par_list, dispname_str, + return_type_dispname_str, return_type_dispname_str); } else { - body = mputprintf(body, "%s(%s);\n" - "TTCN_Runtime::function_finished(\"%s\");\n", - genname_str, actual_par_list, dispname_str); + body = mputprintf(body, "%s(%s);\n" + "TTCN_Runtime::function_finished(\"%s\");\n", + genname_str, actual_par_list, dispname_str); } Free(actual_par_list); body = mputstr(body, "return TRUE;\n" - "} else "); + "} else "); target->functions.start = mputstr(target->functions.start, body); Free(body); } @@ -6225,20 +6215,20 @@ namespace Ttcn { switch (function_type) { case EXTFUNC_MANUAL: if (eb_list) { - eb_list->error("Attribute `errorbehavior' can only be used together " - "with `encode' or `decode'"); - eb_list->chk(); + eb_list->error("Attribute `errorbehavior' can only be used together " + "with `encode' or `decode'"); + eb_list->chk(); } break; case EXTFUNC_ENCODE: switch (prototype) { case PROTOTYPE_NONE: - error("Attribute `encode' cannot be used without `prototype'"); - break; + error("Attribute `encode' cannot be used without `prototype'"); + break; case PROTOTYPE_BACKTRACK: case PROTOTYPE_SLIDING: - error("Attribute `encode' cannot be used with `prototype(%s)'", - get_prototype_name()); + error("Attribute `encode' cannot be used with `prototype(%s)'", + get_prototype_name()); default: /* CONVERT and FAST allowed */ break; } @@ -6256,34 +6246,59 @@ namespace Ttcn { } } if (output_type) { - Type *stream_type = Type::get_stream_type(encoding_type); - if (!stream_type->is_identical(output_type)) { - output_type->error("The output type of %s encoding should be `%s' " - "instead of `%s'", Type::get_encoding_name(encoding_type), - stream_type->get_typename().c_str(), - output_type->get_typename().c_str()); - } + if(encoding_type == Common::Type::CT_TEXT){ // the TEXT encoding support both octetstring ans charstring stream type + Type *stream_type = Type::get_stream_type(encoding_type,0); + Type *stream_type2 = Type::get_stream_type(encoding_type,1); + if ( (!stream_type->is_identical(output_type)) && (!stream_type2->is_identical(output_type)) ) { + input_type->error("The output type of %s encoding should be `%s' or `%s' " + "instead of `%s'", Type::get_encoding_name(encoding_type), + stream_type->get_typename().c_str(), + stream_type2->get_typename().c_str(), + input_type->get_typename().c_str()); + } + } else { + Type *stream_type = Type::get_stream_type(encoding_type); + if (!stream_type->is_identical(output_type)) { + input_type->error("The output type of %s encoding should be `%s' " + "instead of `%s'", Type::get_encoding_name(encoding_type), + stream_type->get_typename().c_str(), + input_type->get_typename().c_str()); + } + } } if (eb_list) eb_list->chk(); chk_allowed_encode(); break; case EXTFUNC_DECODE: if (prototype == PROTOTYPE_NONE) { - error("Attribute `decode' cannot be used without `prototype'"); + error("Attribute `decode' cannot be used without `prototype'"); } if (input_type) { - Type *stream_type = Type::get_stream_type(encoding_type); - if (!stream_type->is_identical(input_type)) { - input_type->error("The input type of %s encoding should be `%s' " - "instead of `%s'", Type::get_encoding_name(encoding_type), - stream_type->get_typename().c_str(), - input_type->get_typename().c_str()); - } + if(encoding_type == Common::Type::CT_TEXT){ // the TEXT encoding support both octetstring ans charstring stream type + Type *stream_type = Type::get_stream_type(encoding_type,0); + Type *stream_type2 = Type::get_stream_type(encoding_type,1); + if ( (!stream_type->is_identical(input_type)) && (!stream_type2->is_identical(input_type)) ) { + input_type->error("The input type of %s encoding should be `%s' or `%s' " + "instead of `%s'", Type::get_encoding_name(encoding_type), + stream_type->get_typename().c_str(), + stream_type2->get_typename().c_str(), + input_type->get_typename().c_str()); + } + } else { + Type *stream_type = Type::get_stream_type(encoding_type); + if (!stream_type->is_identical(input_type)) { + input_type->error("The input type of %s encoding should be `%s' " + "instead of `%s'", Type::get_encoding_name(encoding_type), + stream_type->get_typename().c_str(), + input_type->get_typename().c_str()); + } + } + } if (output_type && !output_type->has_encoding(encoding_type)) { - output_type->error("Output type `%s' does not support %s encoding", - output_type->get_typename().c_str(), - Type::get_encoding_name(encoding_type)); + output_type->error("Output type `%s' does not support %s encoding", + output_type->get_typename().c_str(), + Type::get_encoding_name(encoding_type)); } if (eb_list) eb_list->chk(); chk_allowed_encode(); @@ -6334,7 +6349,7 @@ namespace Ttcn { Error_Context cntxt2(return_type, "In return type"); return_type->chk(); return_type->chk_as_return_type(asstype == A_EXT_FUNCTION_RVAL, - "external function"); + "external function"); } if (!semantic_check_only) fp_list->set_genname(get_genname()); if (w_attrib_path) { @@ -6477,7 +6492,7 @@ namespace Ttcn { result_name = "ret_val"; // creating a local variable for the result stream str = mputprintf(str, "%s ret_val;\n", - output_type->get_genname_value(my_scope).c_str()); + output_type->get_genname_value(my_scope).c_str()); break; case PROTOTYPE_FAST: result_name = fp_list->get_fp_byIndex(1)->get_id().get_name().c_str(); @@ -6522,7 +6537,7 @@ namespace Ttcn { // setting error behavior if (eb_list) str = eb_list->generate_code(str); else if (prototype == PROTOTYPE_BACKTRACK || prototype == PROTOTYPE_SLIDING) { - str = mputstr(str, "TTCN_EncDec::set_error_behavior(" + str = mputstr(str, "TTCN_EncDec::set_error_behavior(" "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"); } else str = mputstr(str, "TTCN_EncDec::set_error_behavior(" "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_DEFAULT);\n"); @@ -6533,7 +6548,7 @@ namespace Ttcn { if (prototype == PROTOTYPE_CONVERT) { // creating a local variable for the result str = mputprintf(str, "%s ret_val;\n", - output_type->get_genname_value(my_scope).c_str()); + output_type->get_genname_value(my_scope).c_str()); result_name = "ret_val"; } else { result_name = fp_list->get_fp_byIndex(1)->get_id().get_name().c_str(); @@ -6562,47 +6577,47 @@ namespace Ttcn { if (prototype != PROTOTYPE_SLIDING) { // checking for remaining data in the buffer if decoding was successful str = mputprintf(str, "if (TTCN_EncDec::get_last_error_type() == " - "TTCN_EncDec::ET_NONE) {\n" - "if (ttcn_buffer.get_pos() < ttcn_buffer.get_len()-1 && " - "TTCN_Logger::log_this_event(TTCN_WARNING)) {\n" - "ttcn_buffer.cut();\n" - "%s remaining_stream;\n" - "ttcn_buffer.get_string(remaining_stream);\n" - "TTCN_Logger::begin_event(TTCN_WARNING);\n" - "TTCN_Logger::log_event_str(\"%s(): Warning: Data remained at the end " - "of the stream after successful decoding: \");\n" - "remaining_stream.log();\n" - "TTCN_Logger::end_event();\n" - "}\n", input_type->get_genname_value(my_scope).c_str(), function_name); + "TTCN_EncDec::ET_NONE) {\n" + "if (ttcn_buffer.get_pos() < ttcn_buffer.get_len()-1 && " + "TTCN_Logger::log_this_event(TTCN_WARNING)) {\n" + "ttcn_buffer.cut();\n" + "%s remaining_stream;\n" + "ttcn_buffer.get_string(remaining_stream);\n" + "TTCN_Logger::begin_event(TTCN_WARNING);\n" + "TTCN_Logger::log_event_str(\"%s(): Warning: Data remained at the end " + "of the stream after successful decoding: \");\n" + "remaining_stream.log();\n" + "TTCN_Logger::end_event();\n" + "}\n", input_type->get_genname_value(my_scope).c_str(), function_name); // closing the block and returning the appropriate result or status code if (prototype == PROTOTYPE_BACKTRACK) { - str = mputstr(str, "return 0;\n" - "} else return 1;\n"); + str = mputstr(str, "return 0;\n" + "} else return 1;\n"); } else { - str = mputstr(str, "}\n"); - if (prototype == PROTOTYPE_CONVERT) + str = mputstr(str, "}\n"); + if (prototype == PROTOTYPE_CONVERT) str = mputstr(str, "return ret_val;\n"); } } else { // result handling and debug printout for sliding decoders str = mputprintf(str, "switch (TTCN_EncDec::get_last_error_type()) {\n" - "case TTCN_EncDec::ET_NONE:\n" - // TTCN_Buffer::get_string will call OCTETSTRING::clean_up() - "ttcn_buffer.cut();\n" - "ttcn_buffer.get_string(%s);\n" - "if (TTCN_Logger::log_this_event(TTCN_Logger::DEBUG_ENCDEC)) {\n" - "TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);\n" - "TTCN_Logger::log_event_str(\"%s(): Stream after decoding: \");\n" - "%s.log();\n" - "TTCN_Logger::end_event();\n" - "}\n" - "return 0;\n" + "case TTCN_EncDec::ET_NONE:\n" + // TTCN_Buffer::get_string will call OCTETSTRING::clean_up() + "ttcn_buffer.cut();\n" + "ttcn_buffer.get_string(%s);\n" + "if (TTCN_Logger::log_this_event(TTCN_Logger::DEBUG_ENCDEC)) {\n" + "TTCN_Logger::begin_event(TTCN_Logger::DEBUG_ENCDEC);\n" + "TTCN_Logger::log_event_str(\"%s(): Stream after decoding: \");\n" + "%s.log();\n" + "TTCN_Logger::end_event();\n" + "}\n" + "return 0;\n" "case TTCN_EncDec::ET_INCOMPL_MSG:\n" - "case TTCN_EncDec::ET_LEN_ERR:\n" - "return 2;\n" - "default:\n" - "return 1;\n" - "}\n", first_par_name, function_name, first_par_name); + "case TTCN_EncDec::ET_LEN_ERR:\n" + "return 2;\n" + "default:\n" + "return 1;\n" + "}\n", first_par_name, function_name, first_par_name); } return str; } @@ -6631,7 +6646,7 @@ namespace Ttcn { // function prototype target->header.function_prototypes = mputprintf(target->header.function_prototypes, "extern %s %s(%s);\n", - return_type_str, genname_str, formal_par_list); + return_type_str, genname_str, formal_par_list); if (function_type != EXTFUNC_MANUAL) { // function body written by the compiler @@ -6641,22 +6656,22 @@ namespace Ttcn { , __FUNCTION__, __LINE__); #endif body = mputprintf(body, - "%s %s(%s)\n" - "{\n" - , return_type_str, genname_str, formal_par_list); + "%s %s(%s)\n" + "{\n" + , return_type_str, genname_str, formal_par_list); switch (function_type) { case EXTFUNC_ENCODE: body = generate_code_encode(body); - break; + break; case EXTFUNC_DECODE: body = generate_code_decode(body); - break; + break; default: FATAL_ERROR("Def_ExtFunction::generate_code()"); } body = mputstr(body, "}\n\n"); target->source.function_bodies = mputstr(target->source.function_bodies, - body); + body); Free(body); } @@ -6685,11 +6700,11 @@ namespace Ttcn { DEBUG(level + 1, "Prototype: %s", get_prototype_name()); if (function_type != EXTFUNC_MANUAL) { DEBUG(level + 1, "Automatically generated: %s", - function_type == EXTFUNC_ENCODE ? "encoder" : "decoder"); + function_type == EXTFUNC_ENCODE ? "encoder" : "decoder"); DEBUG(level + 2, "Encoding type: %s", - Type::get_encoding_name(encoding_type)); + Type::get_encoding_name(encoding_type)); if (encoding_options) - DEBUG(level + 2, "Encoding options: %s", encoding_options->c_str()); + DEBUG(level + 2, "Encoding options: %s", encoding_options->c_str()); } if (eb_list) eb_list->dump(level + 1); } @@ -6925,7 +6940,7 @@ namespace Ttcn { // function for altstep instance: prototype target->header.function_prototypes = mputprintf(target->header.function_prototypes, - "extern alt_status %s_instance(%s);\n", genname_str, formal_par_list); + "extern alt_status %s_instance(%s);\n", genname_str, formal_par_list); // function for altstep instance: body char *str = mprintf("alt_status %s_instance(%s)\n" @@ -6945,34 +6960,34 @@ namespace Ttcn { // wrapper function for stand-alone instantiation: prototype target->header.function_prototypes = mputprintf(target->header.function_prototypes, - "extern void %s(%s);\n", genname_str, formal_par_list); + "extern void %s(%s);\n", genname_str, formal_par_list); // wrapper function for stand-alone instantiation: body target->source.function_bodies = mputprintf(target->source.function_bodies, "void %s(%s)\n" - "{\n" - "altstep_begin:\n" - "boolean block_flag = FALSE;\n" - "alt_status altstep_flag = ALT_UNCHECKED, " - "default_flag = ALT_UNCHECKED;\n" - "for ( ; ; ) {\n" - "TTCN_Snapshot::take_new(block_flag);\n" - "if (altstep_flag != ALT_NO) {\n" - "altstep_flag = %s_instance(%s);\n" - "if (altstep_flag == ALT_YES || altstep_flag == ALT_BREAK) return;\n" - "else if (altstep_flag == ALT_REPEAT) goto altstep_begin;\n" - "}\n" - "if (default_flag != ALT_NO) {\n" - "default_flag = TTCN_Default::try_altsteps();\n" - "if (default_flag == ALT_YES || default_flag == ALT_BREAK) return;\n" - "else if (default_flag == ALT_REPEAT) goto altstep_begin;\n" - "}\n" - "if (altstep_flag == ALT_NO && default_flag == ALT_NO) " - "TTCN_error(\"None of the branches can be chosen in altstep %s.\");\n" - "else block_flag = TRUE;\n" - "}\n" - "}\n\n", genname_str, formal_par_list, genname_str, actual_par_list, - dispname_str); + "{\n" + "altstep_begin:\n" + "boolean block_flag = FALSE;\n" + "alt_status altstep_flag = ALT_UNCHECKED, " + "default_flag = ALT_UNCHECKED;\n" + "for ( ; ; ) {\n" + "TTCN_Snapshot::take_new(block_flag);\n" + "if (altstep_flag != ALT_NO) {\n" + "altstep_flag = %s_instance(%s);\n" + "if (altstep_flag == ALT_YES || altstep_flag == ALT_BREAK) return;\n" + "else if (altstep_flag == ALT_REPEAT) goto altstep_begin;\n" + "}\n" + "if (default_flag != ALT_NO) {\n" + "default_flag = TTCN_Default::try_altsteps();\n" + "if (default_flag == ALT_YES || default_flag == ALT_BREAK) return;\n" + "else if (default_flag == ALT_REPEAT) goto altstep_begin;\n" + "}\n" + "if (altstep_flag == ALT_NO && default_flag == ALT_NO) " + "TTCN_error(\"None of the branches can be chosen in altstep %s.\");\n" + "else block_flag = TRUE;\n" + "}\n" + "}\n\n", genname_str, formal_par_list, genname_str, actual_par_list, + dispname_str); // class for keeping the altstep in the default context // the class is for internal use, we do not need to publish it in the @@ -6987,11 +7002,11 @@ namespace Ttcn { Free(str); // member functions of the class str = mprintf("%s_Default::%s_Default(%s)\n" - " : Default_Base(\"%s\")", genname_str, genname_str, formal_par_list, - dispname_str); + " : Default_Base(\"%s\")", genname_str, genname_str, formal_par_list, + dispname_str); for (size_t i = 0; i < fp_list->get_nof_fps(); i++) { const char *fp_name_str = - fp_list->get_fp_byIndex(i)->get_id().get_name().c_str(); + fp_list->get_fp_byIndex(i)->get_id().get_name().c_str(); str = mputprintf(str, ", par_%s(%s)", fp_name_str, fp_name_str); } str = mputstr(str, "\n{\n}\n\n"); @@ -7008,8 +7023,8 @@ namespace Ttcn { // function for default activation: prototype target->header.function_prototypes = mputprintf(target->header.function_prototypes, - "extern Default_Base *activate_%s(%s);\n", genname_str, - formal_par_list); + "extern Default_Base *activate_%s(%s);\n", genname_str, + formal_par_list); // function for default activation: body str = mprintf("Default_Base *activate_%s(%s)\n" @@ -7025,7 +7040,7 @@ namespace Ttcn { target->functions.pre_init = mputprintf(target->functions.pre_init, "%s.add_altstep(\"%s\", (genericfunc_t)&%s_instance, (genericfunc_t )&activate_%s, " - "(genericfunc_t )&%s);\n", get_module_object_name(), dispname_str, genname_str, + "(genericfunc_t )&%s);\n", get_module_object_name(), dispname_str, genname_str, genname_str, genname_str); } @@ -7179,7 +7194,7 @@ namespace Ttcn { // function prototype target->header.function_prototypes = mputprintf(target->header.function_prototypes, - "extern verdicttype testcase_%s(%s);\n", genname_str, formal_par_list); + "extern verdicttype testcase_%s(%s);\n", genname_str, formal_par_list); // function body char *body = mprintf("verdicttype testcase_%s(%s)\n" @@ -7189,7 +7204,7 @@ namespace Ttcn { // At this point the location information should refer to the execute() // statement rather than this testcase. body = mputstr(body, "TTCN_Runtime::check_begin_testcase(has_timer, " - "timer_value);\n"); + "timer_value);\n"); body = create_location_object(body, "TESTCASE", dispname_str); body = fp_list->generate_shadow_objects(body); body = mputprintf(body, "try {\n" @@ -7218,8 +7233,8 @@ namespace Ttcn { if (fp_list->get_nof_fps() == 0) { // adding to the list of startable testcases target->functions.pre_init = mputprintf(target->functions.pre_init, - "%s.add_testcase_nonpard(\"%s\", testcase_%s);\n", - get_module_object_name(), dispname_str, genname_str); + "%s.add_testcase_nonpard(\"%s\", testcase_%s);\n", + get_module_object_name(), dispname_str, genname_str); } else { target->functions.pre_init = mputprintf(target->functions.pre_init, "%s.add_testcase_pard(\"%s\", (genericfunc_t)&testcase_%s);\n", @@ -7441,36 +7456,36 @@ namespace Ttcn { switch (t->get_typetype()) { case Type::T_PORT: switch (asstype) { - case A_PAR_VAL: - case A_PAR_VAL_INOUT: - asstype = A_PAR_PORT; - break; - default: - error("Port type `%s' cannot be used as %s", - t->get_fullname().c_str(), get_assname()); - } - break; + case A_PAR_VAL: + case A_PAR_VAL_INOUT: + asstype = A_PAR_PORT; + break; + default: + error("Port type `%s' cannot be used as %s", + t->get_fullname().c_str(), get_assname()); + } + break; case Type::T_SIGNATURE: switch (asstype) { - case A_PAR_TEMPL_IN: - case A_PAR_TEMPL_OUT: - case A_PAR_TEMPL_INOUT: - break; - default: - error("Signature `%s' cannot be used as %s", - t->get_fullname().c_str(), get_assname()); - } - break; + case A_PAR_TEMPL_IN: + case A_PAR_TEMPL_OUT: + case A_PAR_TEMPL_INOUT: + break; + default: + error("Signature `%s' cannot be used as %s", + t->get_fullname().c_str(), get_assname()); + } + break; default: switch (asstype) { - case A_PAR_PORT: - case A_PAR_TIMER: - FATAL_ERROR("FormalPar::chk()"); - case A_PAR_VAL: - asstype = A_PAR_VAL_IN; - default: + case A_PAR_PORT: + case A_PAR_TIMER: + FATAL_ERROR("FormalPar::chk()"); + case A_PAR_VAL: + asstype = A_PAR_VAL_IN; + default: break; - } + } } } else if (asstype != A_PAR_TIMER) FATAL_ERROR("FormalPar::chk()"); @@ -7479,7 +7494,7 @@ namespace Ttcn { defval.ap = chk_actual_par(default_value, Type::EXPECTED_STATIC_VALUE); delete default_value; if (!semantic_check_only) - defval.ap->set_code_section(GovernedSimple::CS_POST_INIT); + defval.ap->set_code_section(GovernedSimple::CS_POST_INIT); } } @@ -7583,7 +7598,7 @@ namespace Ttcn { return new ActualPar(v); } else { actual_par->error("A specific value without matching symbols " - "was expected for a %s", get_assname()); + "was expected for a %s", get_assname()); return new ActualPar(); } } @@ -7785,13 +7800,13 @@ namespace Ttcn { Type *ap_type = actual_par->get_Type(); if (ap_type) { ap_type->warning("Explicit type specification is useless for an %s", - get_assname()); + get_assname()); actual_par->chk_Type(type); } Ref_base *derived_ref = actual_par->get_DerivedRef(); if (derived_ref) { derived_ref->error("An in-line modified template cannot be used as %s", - get_assname()); + get_assname()); actual_par->chk_DerivedRef(type); } // needed for the error messages @@ -7803,59 +7818,59 @@ namespace Ttcn { Ref_base *ref = ap_template->get_Ref(); Common::Assignment *ass = ref->get_refd_assignment(); if (!ass) { - delete ref; - return new ActualPar(); + delete ref; + return new ActualPar(); } bool asstype_correct = false; switch (ass->get_asstype()) { case A_PAR_VAL_IN: - ass->use_as_lvalue(*ref); - if (get_asstype() == A_PAR_VAL_OUT || get_asstype() == A_PAR_TEMPL_OUT) { - ass->warning("Passing an `in' parameter as another function's `out' parameter"); - } - // no break + ass->use_as_lvalue(*ref); + if (get_asstype() == A_PAR_VAL_OUT || get_asstype() == A_PAR_TEMPL_OUT) { + ass->warning("Passing an `in' parameter as another function's `out' parameter"); + } + // no break case A_VAR: case A_PAR_VAL_OUT: case A_PAR_VAL_INOUT: if (!is_template) asstype_correct = true; - break; + break; case A_PAR_TEMPL_IN: - ass->use_as_lvalue(*ref); - if (get_asstype() == A_PAR_VAL_OUT || get_asstype() == A_PAR_TEMPL_OUT) { - ass->warning("Passing an `in' parameter as another function's `out' parameter"); - } - // no break + ass->use_as_lvalue(*ref); + if (get_asstype() == A_PAR_VAL_OUT || get_asstype() == A_PAR_TEMPL_OUT) { + ass->warning("Passing an `in' parameter as another function's `out' parameter"); + } + // no break case A_VAR_TEMPLATE: case A_PAR_TEMPL_OUT: case A_PAR_TEMPL_INOUT: if (is_template) asstype_correct = true; - break; + break; default: - break; + break; } if (asstype_correct) { - FieldOrArrayRefs *t_subrefs = ref->get_subrefs(); - Type *ref_type = ass->get_Type()->get_field_type(t_subrefs, exp_val); - if (ref_type) { - if (!type->is_identical(ref_type)) { - ref->error("Type mismatch: Reference to a %s of type " - "`%s' was expected instead of `%s'", expected_string, - type->get_typename().c_str(), ref_type->get_typename().c_str()); - } else if (type->get_sub_type() && ref_type->get_sub_type() && + FieldOrArrayRefs *t_subrefs = ref->get_subrefs(); + Type *ref_type = ass->get_Type()->get_field_type(t_subrefs, exp_val); + if (ref_type) { + if (!type->is_identical(ref_type)) { + ref->error("Type mismatch: Reference to a %s of type " + "`%s' was expected instead of `%s'", expected_string, + type->get_typename().c_str(), ref_type->get_typename().c_str()); + } else if (type->get_sub_type() && ref_type->get_sub_type() && (type->get_sub_type()->get_subtypetype()==ref_type->get_sub_type()->get_subtypetype()) && (!type->get_sub_type()->is_compatible(ref_type->get_sub_type()))) { ref->error("Subtype mismatch: subtype %s has no common value with subtype %s", type->get_sub_type()->to_string().c_str(), ref_type->get_sub_type()->to_string().c_str()); } - if (t_subrefs && t_subrefs->refers_to_string_element()) { - ref->error("Reference to a string element of type `%s' cannot be " - "used in this context", ref_type->get_typename().c_str()); - } - } + if (t_subrefs && t_subrefs->refers_to_string_element()) { + ref->error("Reference to a string element of type `%s' cannot be " + "used in this context", ref_type->get_typename().c_str()); + } + } } else { ref->error("Reference to a %s was expected for an %s instead of %s", - expected_string, get_assname(), ass->get_description().c_str()); + expected_string, get_assname(), ass->get_description().c_str()); } ActualPar* ret_val_ap = new ActualPar(ref); // restriction checking if this is a reference to a template variable @@ -7938,24 +7953,24 @@ namespace Ttcn { Ref_base *ref = ap_template->get_Ref(); Common::Assignment *ass = ref->get_refd_assignment(); if (!ass) { - delete ref; - return new ActualPar(); + delete ref; + return new ActualPar(); } switch (ass->get_asstype()) { case A_TIMER: { ArrayDimensions *dims = ass->get_Dimensions(); - if (dims) dims->chk_indices(ref, "timer", false, exp_val); - else if (ref->get_subrefs()) ref->error("Reference to single %s " - "cannot have field or array sub-references", - ass->get_description().c_str()); - break; } + if (dims) dims->chk_indices(ref, "timer", false, exp_val); + else if (ref->get_subrefs()) ref->error("Reference to single %s " + "cannot have field or array sub-references", + ass->get_description().c_str()); + break; } case A_PAR_TIMER: if (ref->get_subrefs()) ref->error("Reference to %s cannot have " - "field or array sub-references", ass->get_description().c_str()); - break; + "field or array sub-references", ass->get_description().c_str()); + break; default: ref->error("Reference to a timer or timer parameter was expected for " - "a timer parameter instead of %s", ass->get_description().c_str()); + "a timer parameter instead of %s", ass->get_description().c_str()); } return new ActualPar(ref); } else { @@ -7985,34 +8000,34 @@ namespace Ttcn { Ref_base *ref = ap_template->get_Ref(); Common::Assignment *ass = ref->get_refd_assignment(); if (!ass) { - delete ref; - return new ActualPar(); + delete ref; + return new ActualPar(); } bool asstype_correct = false; switch (ass->get_asstype()) { case A_PORT: { ArrayDimensions *dims = ass->get_Dimensions(); - if (dims) dims->chk_indices(ref, "port", false, exp_val); - else if (ref->get_subrefs()) ref->error("Reference to single %s " - "cannot have field or array sub-references", - ass->get_description().c_str()); + if (dims) dims->chk_indices(ref, "port", false, exp_val); + else if (ref->get_subrefs()) ref->error("Reference to single %s " + "cannot have field or array sub-references", + ass->get_description().c_str()); asstype_correct = true; - break; } + break; } case A_PAR_PORT: if (ref->get_subrefs()) ref->error("Reference to %s cannot have " - "field or array sub-references", ass->get_description().c_str()); + "field or array sub-references", ass->get_description().c_str()); asstype_correct = true; - break; + break; default: ref->error("Reference to a port or port parameter was expected for a " - "port parameter instead of %s", ass->get_description().c_str()); + "port parameter instead of %s", ass->get_description().c_str()); } if (asstype_correct) { - Type *ref_type = ass->get_Type(); - if (ref_type && !type->is_identical(ref_type)) - ref->error("Type mismatch: Reference to a port or port parameter " - "of type `%s' was expected instead of `%s'", - type->get_typename().c_str(), ref_type->get_typename().c_str()); + Type *ref_type = ass->get_Type(); + if (ref_type && !type->is_identical(ref_type)) + ref->error("Type mismatch: Reference to a port or port parameter " + "of type `%s' was expected instead of `%s'", + type->get_typename().c_str(), ref_type->get_typename().c_str()); } return new ActualPar(ref); } else { @@ -8035,15 +8050,15 @@ namespace Ttcn { Definition *my_def = my_parlist->get_my_def(); if (!my_def) FATAL_ERROR("FormalPar::use_as_lvalue()"); if (my_def->get_asstype() == A_TEMPLATE) - p_loc.error("Parameter `%s' of the template cannot be passed further " - "as `out' or `inout' parameter", id->get_dispname().c_str()); + p_loc.error("Parameter `%s' of the template cannot be passed further " + "as `out' or `inout' parameter", id->get_dispname().c_str()); else { - // update the genname so that all references in the generated code - // will point to the shadow object + // update the genname so that all references in the generated code + // will point to the shadow object if (!lazy_eval) { - set_genname(id->get_name() + "_shadow"); + set_genname(id->get_name() + "_shadow"); } - used_as_lvalue = true; + used_as_lvalue = true; } } } @@ -8122,7 +8137,7 @@ namespace Ttcn { case A_PAR_VAL_INOUT: case A_PAR_PORT: str = mputprintf(str, "%s& %s", type->get_genname_value(my_scope).c_str(), - name_str); + name_str); break; case A_PAR_TEMPL_IN: if (lazy_eval) { @@ -8134,7 +8149,7 @@ namespace Ttcn { case A_PAR_TEMPL_OUT: case A_PAR_TEMPL_INOUT: str = mputprintf(str, "%s& %s", - type->get_genname_template(my_scope).c_str(), name_str); + type->get_genname_template(my_scope).c_str(), name_str); break; case A_PAR_TIMER: str = mputprintf(str, "TIMER& %s", name_str); @@ -8182,7 +8197,7 @@ namespace Ttcn { case A_PAR_VAL_INOUT: case A_PAR_PORT: str = mputprintf(str, "%s%c %s%s;\n", - type->get_genname_value(my_scope).c_str(), refch, p_prefix, name_str); + type->get_genname_value(my_scope).c_str(), refch, p_prefix, name_str); break; case A_PAR_TEMPL_IN: if (lazy_eval) { @@ -8194,7 +8209,7 @@ namespace Ttcn { case A_PAR_TEMPL_OUT: case A_PAR_TEMPL_INOUT: str = mputprintf(str, "%s%c %s%s;\n", - type->get_genname_template(my_scope).c_str(), refch, p_prefix, name_str); + type->get_genname_template(my_scope).c_str(), refch, p_prefix, name_str); break; case A_PAR_TIMER: str = mputprintf(str, "TIMER& %s%s;\n", p_prefix, name_str); @@ -8213,15 +8228,15 @@ namespace Ttcn { const char *name_str = id->get_name().c_str(); switch (asstype) { case A_PAR_VAL_IN: - str = mputprintf(str, "%s %s(%s);\n", - type->get_genname_value(my_scope).c_str(), genname_str, name_str); - break; + str = mputprintf(str, "%s %s(%s);\n", + type->get_genname_value(my_scope).c_str(), genname_str, name_str); + break; case A_PAR_TEMPL_IN: - str = mputprintf(str, "%s %s(%s);\n", - type->get_genname_template(my_scope).c_str(), genname_str, name_str); - break; + str = mputprintf(str, "%s %s(%s);\n", + type->get_genname_template(my_scope).c_str(), genname_str, name_str); + break; default: - FATAL_ERROR("FormalPar::generate_shadow_object()"); + FATAL_ERROR("FormalPar::generate_shadow_object()"); } } return str; @@ -8362,27 +8377,27 @@ namespace Ttcn { FormalPar *par = pars_v[i]; const string& par_name = par->get_id().get_name(); if (par->get_asstype() != Definition::A_PAR_TIMER) - par->get_Type()->set_genname(p_prefix, par_name); + par->get_Type()->set_genname(p_prefix, par_name); if (par->has_defval()) { - string embedded_genname(p_prefix); - embedded_genname += '_'; - embedded_genname += par_name; - embedded_genname += "_defval"; + string embedded_genname(p_prefix); + embedded_genname += '_'; + embedded_genname += par_name; + embedded_genname += "_defval"; ActualPar *defval = par->get_defval(); switch (defval->get_selection()) { case ActualPar::AP_ERROR: case ActualPar::AP_REF: break; case ActualPar::AP_VALUE: { - Value *v = defval->get_Value(); + Value *v = defval->get_Value(); v->set_genname_prefix("const_"); - v->set_genname_recursive(embedded_genname); + v->set_genname_recursive(embedded_genname); break; } case ActualPar::AP_TEMPLATE: { - Template *t = defval->get_TemplateInstance()->get_Template(); - t->set_genname_prefix("template_"); - t->set_genname_recursive(embedded_genname); - break; } + Template *t = defval->get_TemplateInstance()->get_Template(); + t->set_genname_prefix("template_"); + t->set_genname_recursive(embedded_genname); + break; } default: FATAL_ERROR("FormalParList::set_genname()"); } @@ -8403,19 +8418,19 @@ namespace Ttcn { const string& name = id.get_name(); const char *dispname = id.get_dispname().c_str(); if (pars_m.has_key(name)) { - par->error("Duplicate parameter with name `%s'", dispname); - pars_m[name]->note("Previous definition of `%s' is here", dispname); + par->error("Duplicate parameter with name `%s'", dispname); + pars_m[name]->note("Previous definition of `%s' is here", dispname); } else { - pars_m.add(name, par); - if (parent_scope && parent_scope->has_ass_withId(id)) { - par->error("Parameter name `%s' is not unique in the scope " - "hierarchy", dispname); - Reference ref(0, id.clone()); - Common::Assignment *ass = parent_scope->get_ass_bySRef(&ref); - if (!ass) FATAL_ERROR("FormalParList::chk()"); - ass->note("Symbol `%s' is already defined here in a higher scope " - "unit", dispname); - } + pars_m.add(name, par); + if (parent_scope && parent_scope->has_ass_withId(id)) { + par->error("Parameter name `%s' is not unique in the scope " + "hierarchy", dispname); + Reference ref(0, id.clone()); + Common::Assignment *ass = parent_scope->get_ass_bySRef(&ref); + if (!ass) FATAL_ERROR("FormalParList::chk()"); + ass->note("Symbol `%s' is already defined here in a higher scope " + "unit", dispname); + } } Error_Context cntxt2(par, "In parameter `%s'", dispname); par->chk(); @@ -8423,23 +8438,23 @@ namespace Ttcn { switch (deftype) { case Definition::A_TEMPLATE: switch (par->get_asstype()) { - case Definition::A_PAR_VAL_IN: - case Definition::A_PAR_TEMPL_IN: - // these are allowed + case Definition::A_PAR_VAL_IN: + case Definition::A_PAR_TEMPL_IN: + // these are allowed break; - default: + default: par->error("A template cannot have %s", par->get_assname()); - } - break; + } + break; case Definition::A_TESTCASE: switch (par->get_asstype()) { - case Definition::A_PAR_TIMER: - case Definition::A_PAR_PORT: - // these are forbidden + case Definition::A_PAR_TIMER: + case Definition::A_PAR_PORT: + // these are forbidden par->error("A testcase cannot have %s", par->get_assname()); - default: + default: break; - } + } default: // everything is allowed for functions and altsteps break; @@ -8497,7 +8512,7 @@ namespace Ttcn { break; default: par->error("%s `%s' cannot be started on a parallel test component " - "because it has %s", p_what, p_name, par->get_description().c_str()); + "because it has %s", p_what, p_name, par->get_description().c_str()); } } } @@ -8510,8 +8525,8 @@ namespace Ttcn { // check for the number of parameters if (nof_type_pars != nof_function_pars) { p_fp_list->error("Too %s parameters: %lu was expected instead of %lu", - nof_type_pars < nof_function_pars ? "many" : "few", - (unsigned long) nof_type_pars, (unsigned long) nof_function_pars); + nof_type_pars < nof_function_pars ? "many" : "few", + (unsigned long) nof_type_pars, (unsigned long) nof_function_pars); } size_t upper_limit = nof_type_pars < nof_function_pars ? nof_type_pars : nof_function_pars; @@ -8525,21 +8540,21 @@ namespace Ttcn { // check for parameter kind equivalence // (in, out or inout / value or template) if (type_par_asstype != function_par_asstype) { - function_par->error("The kind of the parameter is not the same as in " - "type `%s': %s was expected instead of %s", where, - type_par->get_assname(), function_par->get_assname()); + function_par->error("The kind of the parameter is not the same as in " + "type `%s': %s was expected instead of %s", where, + type_par->get_assname(), function_par->get_assname()); } // check for type equivalence if (type_par_asstype != FormalPar::A_PAR_TIMER && - function_par_asstype != FormalPar::A_PAR_TIMER) { - Type *type_par_type = type_par->get_Type(); - Type *function_par_type = function_par->get_Type(); - if (!type_par_type->is_identical(function_par_type)) { - function_par_type->error("The type of the parameter is not the same " - "as in type `%s': `%s' was expected instead of `%s'", where, - type_par_type->get_typename().c_str(), - function_par_type->get_typename().c_str()); - } else if (type_par_type->get_sub_type() && function_par_type->get_sub_type() && + function_par_asstype != FormalPar::A_PAR_TIMER) { + Type *type_par_type = type_par->get_Type(); + Type *function_par_type = function_par->get_Type(); + if (!type_par_type->is_identical(function_par_type)) { + function_par_type->error("The type of the parameter is not the same " + "as in type `%s': `%s' was expected instead of `%s'", where, + type_par_type->get_typename().c_str(), + function_par_type->get_typename().c_str()); + } else if (type_par_type->get_sub_type() && function_par_type->get_sub_type() && (type_par_type->get_sub_type()->get_subtypetype()==function_par_type->get_sub_type()->get_subtypetype()) && (!type_par_type->get_sub_type()->is_compatible(function_par_type->get_sub_type()))) { // TODO: maybe equivalence should be checked, or maybe that is too strict @@ -8555,7 +8570,7 @@ namespace Ttcn { function_par->error("The template restriction of the parameter is " "not the same as in type `%s': %s restriction was expected instead " "of %s restriction", where, - type_par->get_template_restriction()==TR_NONE ? "no" : + type_par->get_template_restriction()==TR_NONE ? "no" : Template::get_restriction_name(type_par->get_template_restriction()), function_par->get_template_restriction()==TR_NONE ? "no" : Template::get_restriction_name(function_par-> @@ -8569,10 +8584,10 @@ namespace Ttcn { const Identifier& type_par_id = type_par->get_id(); const Identifier& function_par_id = function_par->get_id(); if (type_par_id != function_par_id) { - function_par->warning("The name of the parameter is not the same " - "as in type `%s': `%s' was expected instead of `%s'", where, - type_par_id.get_dispname().c_str(), - function_par_id.get_dispname().c_str()); + function_par->warning("The name of the parameter is not the same " + "as in type `%s': `%s' was expected instead of `%s'", where, + type_par_id.get_dispname().c_str(), + function_par_id.get_dispname().c_str()); } } } @@ -8600,82 +8615,82 @@ namespace Ttcn { // We are now responsible for np. if (has_fp_withName(*np->get_name())) { - // there is a formal parameter with that name - FormalPar *fp = get_fp_byName(*np->get_name()); - const size_t is_at = *formalpar_map[fp]; // the index of the formal par - if (is_at >= num_actual) { - // There is no actual par in the unnamed part. - // Create one from the named param. - - // First, pad the gap with '-' - for (; num_actual < is_at; ++num_actual) { - Template *not_used; - if (pars_v[num_actual]->has_defval()) { - not_used = new Template(Template::TEMPLATE_NOTUSED); - } - else { // cannot use '-' if no default value - not_used = new Template(Template::TEMPLATE_ERROR); - } - TemplateInstance *new_ti = new TemplateInstance(0, 0, not_used); - // Conjure a location info at the beginning of the unnamed part - // (that is, the beginning of the actual parameter list) - new_ti->set_location(p_paps->get_tis()->get_filename(), - p_paps->get_tis()->get_first_line(), - p_paps->get_tis()->get_first_column(), 0, 0); - p_paps->get_tis()->add_ti(new_ti); - } - TemplateInstance * namedti = np->extract_ti(); - p_paps->get_tis()->add_ti(namedti); - ++num_actual; - } else { - // There is already an actual par at that position, fetch it - TemplateInstance * ti = p_paps->get_tis()->get_ti_byIndex(is_at); - Template::templatetype_t tt = ti->get_Template()->get_templatetype(); - - if (is_at >= num_unnamed && !ti->get_Type() && !ti->get_DerivedRef() - && (tt == Template::TEMPLATE_NOTUSED || tt == Template::TEMPLATE_ERROR)) { - // NotUsed in the named part => padding - np->error("Named parameter `%s' out of order", - np->get_name()->get_dispname().c_str()); - } else { - // attempt to override an original unnamed param with a named one - np->error("Formal parameter `%s' assigned more than once", - np->get_name()->get_dispname().c_str()); - } - } + // there is a formal parameter with that name + FormalPar *fp = get_fp_byName(*np->get_name()); + const size_t is_at = *formalpar_map[fp]; // the index of the formal par + if (is_at >= num_actual) { + // There is no actual par in the unnamed part. + // Create one from the named param. + + // First, pad the gap with '-' + for (; num_actual < is_at; ++num_actual) { + Template *not_used; + if (pars_v[num_actual]->has_defval()) { + not_used = new Template(Template::TEMPLATE_NOTUSED); + } + else { // cannot use '-' if no default value + not_used = new Template(Template::TEMPLATE_ERROR); + } + TemplateInstance *new_ti = new TemplateInstance(0, 0, not_used); + // Conjure a location info at the beginning of the unnamed part + // (that is, the beginning of the actual parameter list) + new_ti->set_location(p_paps->get_tis()->get_filename(), + p_paps->get_tis()->get_first_line(), + p_paps->get_tis()->get_first_column(), 0, 0); + p_paps->get_tis()->add_ti(new_ti); + } + TemplateInstance * namedti = np->extract_ti(); + p_paps->get_tis()->add_ti(namedti); + ++num_actual; + } else { + // There is already an actual par at that position, fetch it + TemplateInstance * ti = p_paps->get_tis()->get_ti_byIndex(is_at); + Template::templatetype_t tt = ti->get_Template()->get_templatetype(); + + if (is_at >= num_unnamed && !ti->get_Type() && !ti->get_DerivedRef() + && (tt == Template::TEMPLATE_NOTUSED || tt == Template::TEMPLATE_ERROR)) { + // NotUsed in the named part => padding + np->error("Named parameter `%s' out of order", + np->get_name()->get_dispname().c_str()); + } else { + // attempt to override an original unnamed param with a named one + np->error("Formal parameter `%s' assigned more than once", + np->get_name()->get_dispname().c_str()); + } + } } else { // no formal parameter with that name - char * nam = 0; - switch (my_def->get_asstype()) { - case Common::Assignment::A_TYPE: { - Type *t = my_def->get_Type(); - - switch (t ? t->get_typetype() : 0) { - case Type::T_FUNCTION: - nam = mcopystr("Function reference"); - break; - case Type::T_ALTSTEP: - nam = mcopystr("Altstep reference"); - break; - case Type::T_TESTCASE: - nam = mcopystr("Testcase reference"); - break; - default: - FATAL_ERROR("FormalParList::chk_actual_parlist() " - "Unexpected type %s", t->get_typename().c_str()); - } // switch(typetype) - break; } - default: - nam = mcopystr(my_def->get_assname()); - break; - } // switch(asstype) - - *nam &= ~('a'-'A'); // Make the first letter uppercase - p_paps->get_tis()->error("%s `%s' has no formal parameter `%s'", - nam, - my_def->get_fullname().c_str(), - np->get_name()->get_dispname().c_str()); - Free(nam); + char * nam = 0; + switch (my_def->get_asstype()) { + case Common::Assignment::A_TYPE: { + Type *t = my_def->get_Type(); + + switch (t ? t->get_typetype() : 0) { + case Type::T_FUNCTION: + nam = mcopystr("Function reference"); + break; + case Type::T_ALTSTEP: + nam = mcopystr("Altstep reference"); + break; + case Type::T_TESTCASE: + nam = mcopystr("Testcase reference"); + break; + default: + FATAL_ERROR("FormalParList::chk_actual_parlist() " + "Unexpected type %s", t->get_typename().c_str()); + } // switch(typetype) + break; } + default: + nam = mcopystr(my_def->get_assname()); + break; + } // switch(asstype) + + *nam &= ~('a'-'A'); // Make the first letter uppercase + p_paps->get_tis()->error("%s `%s' has no formal parameter `%s'", + nam, + my_def->get_fullname().c_str(), + np->get_name()->get_dispname().c_str()); + Free(nam); } delete np; } @@ -8728,22 +8743,22 @@ namespace Ttcn { // the formal parameter for the current actual parameter FormalPar *fp = pars_v[i]; Error_Context cntxt(ti, "In parameter #%lu for `%s'", - (unsigned long) (i + 1), fp->get_id().get_dispname().c_str()); + (unsigned long) (i + 1), fp->get_id().get_dispname().c_str()); if (!ti->get_Type() && !ti->get_DerivedRef() && ti->get_Template() - ->get_templatetype() == Template::TEMPLATE_NOTUSED) { - if (fp->has_defval()) { - ActualPar *defval = fp->get_defval(); - p_aplist->add(new ActualPar(defval)); - if (defval->is_erroneous()) error_flag = true; - } else { - ti->error("Not used symbol (`-') cannot be used for parameter " - "that does not have default value"); - p_aplist->add(new ActualPar()); - error_flag = true; - } + ->get_templatetype() == Template::TEMPLATE_NOTUSED) { + if (fp->has_defval()) { + ActualPar *defval = fp->get_defval(); + p_aplist->add(new ActualPar(defval)); + if (defval->is_erroneous()) error_flag = true; + } else { + ti->error("Not used symbol (`-') cannot be used for parameter " + "that does not have default value"); + p_aplist->add(new ActualPar()); + error_flag = true; + } } else if (!ti->get_Type() && !ti->get_DerivedRef() && ti->get_Template() - ->get_templatetype() == Template::TEMPLATE_ERROR) { - ti->error("Parameter not specified"); + ->get_templatetype() == Template::TEMPLATE_ERROR) { + ti->error("Parameter not specified"); } else { ActualPar *ap = fp->chk_actual_par(ti, Type::EXPECTED_DYNAMIC_VALUE); p_aplist->add(ap); @@ -8757,7 +8772,7 @@ namespace Ttcn { for (size_t i = upper_limit; i < formal_pars; i++) { FormalPar *fp = pars_v[i]; if (fp->has_defval()) { - ActualPar *defval = fp->get_defval(); + ActualPar *defval = fp->get_defval(); p_aplist->add(new ActualPar(defval)); if (defval->is_erroneous()) error_flag = true; } else { @@ -8798,17 +8813,17 @@ namespace Ttcn { case Common::Assignment::A_VAR: case Common::Assignment::A_VAR_TEMPLATE: case Common::Assignment::A_TIMER: - // it is not allowed to pass references of local variables or timers - if (t_par_ass->is_local()) { - t_ref->error("Parameter #%lu of %s refers to %s, which is a local " - "definition within a statement block and may have shorter " - "lifespan than the activated default. Only references to " - "variables and timers defined in the component type can be passed " - "to activated defaults", (unsigned long) (i + 1), p_description, - t_par_ass->get_description().c_str()); - ret_val = false; - } - break; + // it is not allowed to pass references of local variables or timers + if (t_par_ass->is_local()) { + t_ref->error("Parameter #%lu of %s refers to %s, which is a local " + "definition within a statement block and may have shorter " + "lifespan than the activated default. Only references to " + "variables and timers defined in the component type can be passed " + "to activated defaults", (unsigned long) (i + 1), p_description, + t_par_ass->get_description().c_str()); + ret_val = false; + } + break; case Common::Assignment::A_PAR_VAL_IN: case Common::Assignment::A_PAR_VAL_OUT: case Common::Assignment::A_PAR_VAL_INOUT: @@ -8816,24 +8831,24 @@ namespace Ttcn { case Common::Assignment::A_PAR_TEMPL_OUT: case Common::Assignment::A_PAR_TEMPL_INOUT: case Common::Assignment::A_PAR_TIMER: { - // it is not allowed to pass references pointing to formal parameters - // except for activate() statements within testcases - // note: all defaults are deactivated at the end of the testcase - FormalPar *t_refd_fp = dynamic_cast<FormalPar*>(t_par_ass); - if (!t_refd_fp) FATAL_ERROR("FormalParList::chk_activate_argument()"); - FormalParList *t_fpl = t_refd_fp->get_my_parlist(); - if (!t_fpl || !t_fpl->my_def) - FATAL_ERROR("FormalParList::chk_activate_argument()"); - if (t_fpl->my_def->get_asstype() != Common::Assignment::A_TESTCASE) { + // it is not allowed to pass references pointing to formal parameters + // except for activate() statements within testcases + // note: all defaults are deactivated at the end of the testcase + FormalPar *t_refd_fp = dynamic_cast<FormalPar*>(t_par_ass); + if (!t_refd_fp) FATAL_ERROR("FormalParList::chk_activate_argument()"); + FormalParList *t_fpl = t_refd_fp->get_my_parlist(); + if (!t_fpl || !t_fpl->my_def) + FATAL_ERROR("FormalParList::chk_activate_argument()"); + if (t_fpl->my_def->get_asstype() != Common::Assignment::A_TESTCASE) { t_ref->error("Parameter #%lu of %s refers to %s, which may have " - "shorter lifespan than the activated default. Only references to " - "variables and timers defined in the component type can be passed " - "to activated defaults", (unsigned long) (i + 1), p_description, - t_par_ass->get_description().c_str()); + "shorter lifespan than the activated default. Only references to " + "variables and timers defined in the component type can be passed " + "to activated defaults", (unsigned long) (i + 1), p_description, + t_par_ass->get_description().c_str()); ret_val = false; - } } + } } default: - break; + break; } } return ret_val; @@ -9351,7 +9366,7 @@ namespace Ttcn { size_t nof_pars = params.size(); for(size_t i = 0; i < nof_pars; i++) params[i]->set_fullname(p_fullname + - ".<parameter" + Int2string(i + 1) + ">"); + ".<parameter" + Int2string(i + 1) + ">"); } void ActualParList::set_my_scope(Scope *p_scope) @@ -9385,24 +9400,24 @@ namespace Ttcn { for (size_t i = 0; i < nof_pars; i++) { ActualPar *par = params[i]; if (par->get_selection() == ActualPar::AP_DEFAULT) - par = par->get_ActualPar(); + par = par->get_ActualPar(); if (par->get_selection() == ActualPar::AP_REF) { - Common::Assignment *ass = par->get_Ref()->get_refd_assignment(); - switch (ass->get_asstype()) { - case Common::Assignment::A_VAR: - case Common::Assignment::A_PAR_VAL_IN: - case Common::Assignment::A_PAR_VAL_OUT: - case Common::Assignment::A_PAR_VAL_INOUT: - if (!value_refs.has_key(ass)) value_refs.add(ass, 0); - break; - case Common::Assignment::A_VAR_TEMPLATE: - case Common::Assignment::A_PAR_TEMPL_IN: - case Common::Assignment::A_PAR_TEMPL_OUT: - case Common::Assignment::A_PAR_TEMPL_INOUT: - if (!template_refs.has_key(ass)) template_refs.add(ass, 0); - default: - break; - } + Common::Assignment *ass = par->get_Ref()->get_refd_assignment(); + switch (ass->get_asstype()) { + case Common::Assignment::A_VAR: + case Common::Assignment::A_PAR_VAL_IN: + case Common::Assignment::A_PAR_VAL_OUT: + case Common::Assignment::A_PAR_VAL_INOUT: + if (!value_refs.has_key(ass)) value_refs.add(ass, 0); + break; + case Common::Assignment::A_VAR_TEMPLATE: + case Common::Assignment::A_PAR_TEMPL_IN: + case Common::Assignment::A_PAR_TEMPL_OUT: + case Common::Assignment::A_PAR_TEMPL_INOUT: + if (!template_refs.has_key(ass)) template_refs.add(ass, 0); + default: + break; + } } } // walk through the parameter list and generate the code @@ -9416,72 +9431,72 @@ namespace Ttcn { // the copy constructor call is not needed if the parameter is copied // into a shadow object in the body of the called function if (!p_fpl || !p_fpl->get_fp_byIndex(i)->get_used_as_lvalue()) { - switch (par->get_selection()) { - case ActualPar::AP_VALUE: { - Value *v = par->get_Value(); - if (v->get_valuetype() == Value::V_REFD) { - Common::Assignment *t_ass = - v->get_reference()->get_refd_assignment(); - if (value_refs.has_key(t_ass)) { - // a reference to the same variable is also passed to the called - // definition - copy_needed = true; - } else if (p_comptype || p_compself) { - // the called definition has a 'runs on' clause so it can access - // component variables - switch (t_ass->get_asstype()) { - case Common::Assignment::A_PAR_VAL_OUT: - case Common::Assignment::A_PAR_VAL_INOUT: - // the parameter may be an alias of a component variable - copy_needed = true; - break; - case Common::Assignment::A_VAR: - // copy is needed if t_ass is a component variable that is - // visible by the called definition - if (!t_ass->is_local()) copy_needed = true; - /** \todo component type compatibility: check whether t_ass is - * visible from p_comptype (otherwise copy is not needed) */ - default: - break; - } - } - } - break; } - case ActualPar::AP_TEMPLATE: { - TemplateInstance *ti = par->get_TemplateInstance(); - if (!ti->get_DerivedRef()) { - Template *t = ti->get_Template(); - if (t->get_templatetype() == Template::TEMPLATE_REFD) { - Common::Assignment *t_ass = - t->get_reference()->get_refd_assignment(); - if (template_refs.has_key(t_ass)) { - // a reference to the same variable is also passed to the called - // definition - copy_needed = true; - } else if (p_comptype || p_compself) { - // the called definition has a 'runs on' clause so it can access - // component variables - switch (t_ass->get_asstype()) { - case Common::Assignment::A_PAR_TEMPL_OUT: - case Common::Assignment::A_PAR_TEMPL_INOUT: - // the parameter may be an alias of a component variable - copy_needed = true; - break; - case Common::Assignment::A_VAR_TEMPLATE: - // copy is needed if t_ass is a component variable that is - // visible by the called definition - if (!t_ass->is_local()) copy_needed = true; - /** \todo component type compatibility: check whether t_ass is - * visible from p_comptype (otherwise copy is not needed) */ - default: - break; - } - } - } - } } - default: - break; - } + switch (par->get_selection()) { + case ActualPar::AP_VALUE: { + Value *v = par->get_Value(); + if (v->get_valuetype() == Value::V_REFD) { + Common::Assignment *t_ass = + v->get_reference()->get_refd_assignment(); + if (value_refs.has_key(t_ass)) { + // a reference to the same variable is also passed to the called + // definition + copy_needed = true; + } else if (p_comptype || p_compself) { + // the called definition has a 'runs on' clause so it can access + // component variables + switch (t_ass->get_asstype()) { + case Common::Assignment::A_PAR_VAL_OUT: + case Common::Assignment::A_PAR_VAL_INOUT: + // the parameter may be an alias of a component variable + copy_needed = true; + break; + case Common::Assignment::A_VAR: + // copy is needed if t_ass is a component variable that is + // visible by the called definition + if (!t_ass->is_local()) copy_needed = true; + /** \todo component type compatibility: check whether t_ass is + * visible from p_comptype (otherwise copy is not needed) */ + default: + break; + } + } + } + break; } + case ActualPar::AP_TEMPLATE: { + TemplateInstance *ti = par->get_TemplateInstance(); + if (!ti->get_DerivedRef()) { + Template *t = ti->get_Template(); + if (t->get_templatetype() == Template::TEMPLATE_REFD) { + Common::Assignment *t_ass = + t->get_reference()->get_refd_assignment(); + if (template_refs.has_key(t_ass)) { + // a reference to the same variable is also passed to the called + // definition + copy_needed = true; + } else if (p_comptype || p_compself) { + // the called definition has a 'runs on' clause so it can access + // component variables + switch (t_ass->get_asstype()) { + case Common::Assignment::A_PAR_TEMPL_OUT: + case Common::Assignment::A_PAR_TEMPL_INOUT: + // the parameter may be an alias of a component variable + copy_needed = true; + break; + case Common::Assignment::A_VAR_TEMPLATE: + // copy is needed if t_ass is a component variable that is + // visible by the called definition + if (!t_ass->is_local()) copy_needed = true; + /** \todo component type compatibility: check whether t_ass is + * visible from p_comptype (otherwise copy is not needed) */ + default: + break; + } + } + } + } } + default: + break; + } } if (use_runtime_2 && ActualPar::AP_REF == par->get_selection()) { @@ -9521,13 +9536,12 @@ namespace Ttcn { } // let the array object know that the index is referenced before // calling the function, and let it know that it's now longer - // referenced after the function call + // referenced after the function call (this is done with the help + // of the RefdIndexHandler's constructor and destructor) + string tmp_id = ref->get_my_scope()->get_scope_mod_gen()->get_temporary_id(); expr->preamble = mputprintf(expr->preamble, - "%s.add_refd_index(%s);\n", - array_expr.expr, index_expr.expr); - expr->postamble = mputprintf(expr->postamble, - "%s.remove_refd_index(%s);\n", - array_expr.expr, index_expr.expr); + "RefdIndexHandler %s(&%s, %s);\n", + tmp_id.c_str(), array_expr.expr, index_expr.expr); // insert any postambles the array object or the index might have if (array_expr.postamble != NULL) { expr->preamble = mputstr(expr->preamble, array_expr.postamble); diff --git a/compiler2/ttcn3/Makefile b/compiler2/ttcn3/Makefile index fecfc9d10..cdac82771 100644 --- a/compiler2/ttcn3/Makefile +++ b/compiler2/ttcn3/Makefile @@ -38,7 +38,7 @@ GENERATED_OTHERS := compiler.output rawAST.output coding_attrib_p.output lex.bac STATIC_SOURCES := ArrayDimensions.cc AST_ttcn3.cc Attributes.cc ILT.cc PatternString.cc \ RawAST.cc Statement.cc TtcnTemplate.cc Templatestuff.cc TextAST.cc Ttcnstuff.cc \ -compiler.c port.c signature.c BerAST.cc JsonAST.cc Ttcn2Json.cc +compiler.c port.c signature.c BerAST.cc JsonAST.cc Ttcn2Json.cc profiler.c SOURCES := $(STATIC_SOURCES) $(GENERATED_SOURCES) diff --git a/compiler2/ttcn3/Statement.cc b/compiler2/ttcn3/Statement.cc index 2a452a902..02d28a669 100644 --- a/compiler2/ttcn3/Statement.cc +++ b/compiler2/ttcn3/Statement.cc @@ -468,6 +468,8 @@ namespace Ttcn { case S_CONTINUE: case S_STOP_EXEC: case S_REPEAT: + case S_START_PROFILER: + case S_STOP_PROFILER: break; case S_START_UNDEF: case S_STOP_UNDEF: @@ -689,6 +691,8 @@ namespace Ttcn { ags=0; case S_ERROR: case S_STOP_EXEC: + case S_START_PROFILER: + case S_STOP_PROFILER: break; case S_BREAK: case S_CONTINUE: @@ -1451,6 +1455,8 @@ namespace Ttcn { case S_TESTCASE_INSTANCE_REFD: return "execute"; case S_STRING2TTCN: return "string2ttcn"; + case S_START_PROFILER: return "@profiler.start"; + case S_STOP_PROFILER: return "@profiler.stop"; default: FATAL_ERROR("Statement::get_stmt_name()"); return ""; @@ -1529,6 +1535,8 @@ namespace Ttcn { case S_CONTINUE: case S_STOP_EXEC: case S_REPEAT: + case S_START_PROFILER: + case S_STOP_PROFILER: break; case S_START_UNDEF: case S_STOP_UNDEF: @@ -1756,6 +1764,8 @@ namespace Ttcn { case S_CONTINUE: case S_STOP_EXEC: case S_REPEAT: + case S_START_PROFILER: + case S_STOP_PROFILER: break; case S_START_UNDEF: case S_STOP_UNDEF: @@ -2256,6 +2266,8 @@ namespace Ttcn { case S_SETVERDICT: case S_TESTCASE_INSTANCE: case S_TESTCASE_INSTANCE_REFD: + case S_START_PROFILER: + case S_STOP_PROFILER: return false; case S_ALT: case S_INTERLEAVE: @@ -2496,6 +2508,10 @@ namespace Ttcn { case S_STRING2TTCN: chk_string2ttcn(); break; + case S_START_PROFILER: + case S_STOP_PROFILER: + // do nothing + break; default: FATAL_ERROR("Statement::chk()"); } // switch statementtype @@ -5079,6 +5095,8 @@ error: case S_CONTINUE: case S_STOP_EXEC: case S_REPEAT: + case S_START_PROFILER: + case S_STOP_PROFILER: break; case S_ASSIGNMENT: ass->set_code_section(p_code_section); @@ -5467,6 +5485,12 @@ error: case S_STRING2TTCN: str=generate_code_string2ttcn(str); break; + case S_START_PROFILER: + str = mputstr(str, "ttcn3_prof.start();\n"); + break; + case S_STOP_PROFILER: + str = mputstr(str, "ttcn3_prof.stop();\n"); + break; default: FATAL_ERROR("Statement::generate_code()"); } // switch @@ -7124,6 +7148,8 @@ error: case S_FUNCTION_INVOKED: case S_ALTSTEP_INVOKED: case S_STRING2TTCN: + case S_START_PROFILER: + case S_STOP_PROFILER: break; default: FATAL_ERROR("Statement::set_parent_path()"); @@ -9086,22 +9112,32 @@ error: for(size_t i=0; i<tis->get_nof_tis(); i++) { TemplateInstance *ti=tis->get_ti_byIndex(i); Template *tb=ti->get_Template(); - bool specval = tb->is_Value(); + bool is_value = NULL == ti->get_DerivedRef() && tb->is_Value(); expression_struct exprs; Code::init_expr(&exprs); - if (!specval) ti->generate_code(&exprs); - else if (tb->get_templatetype() == Template::SPECIFIC_VALUE) { - tb->get_specific_value()->generate_code_expr_mandatory(&exprs); + if (is_value) { + if (tb->get_templatetype() == Template::SPECIFIC_VALUE) { + tb->get_specific_value()->generate_code_expr_mandatory(&exprs); + } + else { + Value* val = tb->get_Value(); + if (NULL == val->get_my_governor()) { + // the value's governor could not be determined, treat it as a non-value template + is_value = false; + } + else { + val->generate_code_expr_mandatory(&exprs); + } + delete val; + } } - else { - Value* val = tb->get_Value(); - val->generate_code_expr_mandatory(&exprs); - delete val; + if (!is_value) { + ti->generate_code(&exprs); } str=tb->update_location_object(str); if(!exprs.preamble && !exprs.postamble) { str=mputstr(str, "if("); - if(!specval) + if(!is_value) str=mputprintf(str, "%s.match(%s)", exprs.expr, expr_name); else str=mputprintf(str, "%s == %s", expr_name, exprs.expr); str=mputprintf(str, ") goto %s_%lu;\n", tmp_prefix, @@ -9113,7 +9149,7 @@ error: (unsigned long) idx); char *s=exprs.expr; exprs.expr=mprintf("%s_%lub = ", tmp_prefix, (unsigned long) idx); - if(!specval) + if(!is_value) exprs.expr=mputprintf(exprs.expr, "%s.match(%s)", s, expr_name); else exprs.expr=mputprintf(exprs.expr, "(%s == %s)", expr_name, s); Free(s); diff --git a/compiler2/ttcn3/Statement.hh b/compiler2/ttcn3/Statement.hh index 1c1aa6c17..7abce565f 100644 --- a/compiler2/ttcn3/Statement.hh +++ b/compiler2/ttcn3/Statement.hh @@ -235,7 +235,10 @@ namespace Ttcn { /* control statement */ S_TESTCASE_INSTANCE, // testcase_inst S_TESTCASE_INSTANCE_REFD, //execute_refd - S_STRING2TTCN // str2ttcn + S_STRING2TTCN, // str2ttcn + /* TTCN-3 Profiler statements */ + S_START_PROFILER, + S_STOP_PROFILER }; enum component_t { @@ -437,8 +440,8 @@ namespace Ttcn { Statement& operator=(const Statement& p); ///< assignment disabled void clean_up(); public: - /** Constructor used by S_ERROR, S_STOP_EXEC and S_REPEAT, S_BREAK and - * S_CONTINUE */ + /** Constructor used by S_ERROR, S_STOP_EXEC and S_REPEAT, S_BREAK, + * S_CONTINUE, S_START_PROFILER and S_STOP_PROFILER */ Statement(statementtype_t p_st); /** Constructor used by S_START_UNDEF and S_STOP_UNDEF */ Statement(statementtype_t p_st, Ref_base *p_ref, Value *p_val); diff --git a/compiler2/ttcn3/TtcnTemplate.cc b/compiler2/ttcn3/TtcnTemplate.cc index bf646c6ac..03f6d5ee0 100644 --- a/compiler2/ttcn3/TtcnTemplate.cc +++ b/compiler2/ttcn3/TtcnTemplate.cc @@ -1964,6 +1964,21 @@ end: // Cannot flatten at compile time if the template has parameters. can_flatten = false; } + + // check for subreferences in the 'all from' target + FieldOrArrayRefs* subrefs = ref->get_subrefs(); + if (NULL != subrefs) { + // flattening values/templates with subreferences is not implemented yet + can_flatten = false; + for (size_t i = 0; i < subrefs->get_nof_refs(); ++i) { + FieldOrArrayRef* subref = subrefs->get_ref(i); + if (FieldOrArrayRef::ARRAY_REF == subref->get_type()) { + // set any array indexes from undefined lowerID to reference + subref->get_val()->set_lowerid_to_ref(); + } + } + } + Common::Assignment *ass = ref->get_refd_assignment(); if (ass == NULL) { // perhaps erroneous break; @@ -2073,11 +2088,18 @@ end: switch (val->get_valuetype()) { case Common::Value::V_SEQOF: case Common::Value::V_SETOF: case Common::Value::V_ARRAY: { - const size_t ncomp = val->get_nof_comps(); - for (size_t i = 0; i < ncomp; ++i) { - Value *v = val->get_comp_byIndex(i); - Template *newt = new Template(v->clone()); - new_templates->add_t(newt); + if (can_flatten) { + const size_t ncomp = val->get_nof_comps(); + for (size_t i = 0; i < ncomp; ++i) { + Value *v = val->get_comp_byIndex(i); + Template *newt = new Template(v->clone()); + new_templates->add_t(newt); + } + } + else { + delete new_templates; + new_templates = 0; + killer = false; } break; } @@ -2095,7 +2117,9 @@ end: case Common::Assignment::A_MODULEPAR: // all from a module parameter case Common::Assignment::A_VAR: // all from a variable case Common::Assignment::A_PAR_VAL_IN: - case Common::Assignment::A_PAR_VAL_INOUT: { + case Common::Assignment::A_PAR_VAL_INOUT: + case Common::Assignment::A_FUNCTION_RVAL: + case Common::Assignment::A_EXT_FUNCTION_RVAL: { delete new_templates; // cannot flatten at compile time new_templates = 0; break; } @@ -3232,7 +3256,6 @@ end: // variable part for (size_t i = 0; i < nof_ts; i++) { Template *t = u.templates->get_t_byIndex(i); - printf("generate_code_init_seof ALL_FROM: temptype %u\n", t->templatetype); for (size_t k = 0, v = variables.size(); k < v; ++k) { if (t->templatetype == ALL_FROM) { Value *refv = t->u.all_from->u.specific_value; diff --git a/compiler2/ttcn3/compiler.c b/compiler2/ttcn3/compiler.c index ce428baaa..b9cb1af8a 100644 --- a/compiler2/ttcn3/compiler.c +++ b/compiler2/ttcn3/compiler.c @@ -21,6 +21,7 @@ #include "compiler.h" #include "../main.hh" #include "../error.h" +#include "profiler.h" #ifdef LICENSE #include "../../common/license.h" @@ -310,10 +311,6 @@ void write_output(output_struct *output, const char *module_name, COPYRIGHT_STRING "\n\n" "// Do not edit this file unless you know what you are doing.\n", is_ttcn ? "TTCN-3" : "ASN.1", user_info); - - if (profiler_enabled) { - output->source.includes = mputstr(output->source.includes, "#include \"Profiler.hh\"\n"); - } if (output->source.includes != NULL) { fputs("\n/* Including header files */\n\n", fp); diff --git a/compiler2/ttcn3/compiler.l b/compiler2/ttcn3/compiler.l index 3746fb370..4497b6ca7 100644 --- a/compiler2/ttcn3/compiler.l +++ b/compiler2/ttcn3/compiler.l @@ -504,6 +504,7 @@ xor4b RETURN(Xor4bKeyword); "@try" RETURN(TitanSpecificTryKeyword); "@catch" RETURN(TitanSpecificCatchKeyword); "@lazy" RETURN(TitanSpecificLazyKeyword); +"@profiler" RETURN(TitanSpecificProfilerKeyword); /* Predefined function identifiers */ diff --git a/compiler2/ttcn3/compiler.y b/compiler2/ttcn3/compiler.y index dc5a760fe..5f07d0285 100644 --- a/compiler2/ttcn3/compiler.y +++ b/compiler2/ttcn3/compiler.y @@ -706,6 +706,7 @@ static const string anyname("anytype"); %token TitanSpecificTryKeyword %token TitanSpecificCatchKeyword %token TitanSpecificLazyKeyword +%token TitanSpecificProfilerKeyword /* Keywords combined with a leading dot */ @@ -900,7 +901,7 @@ static const string anyname("anytype"); StartTimerStatement StopExecutionStatement StopStatement StopTCStatement StopTimerStatement TimeoutStatement TimerStatements TriggerStatement UnmapStatement VerdictStatements WhileStatement SelectCaseConstruct - StopTestcaseStatement String2TtcnStatement + StopTestcaseStatement String2TtcnStatement ProfilerStatement %type <statementblock> StatementBlock optElseClause FunctionStatementOrDefList ControlStatementOrDefList ModuleControlBody %type <subtypeparse> ValueOrRange @@ -940,7 +941,7 @@ static const string anyname("anytype"); PredefinedValue ReadTimerOp ReferOp ReferencedValue RunningOp RunningTimerOp SelfOp SingleExpression SingleLowerBound SystemOp TemplateOps TimerOps TimerValue UpperBound Value ValueofOp VerdictOps VerdictValue optReplyValue - optTestcaseTimerValue optToClause + optTestcaseTimerValue optToClause ProfilerRunningOp %type <values> ArrayElementExpressionList seqArrayExpressionSpec %type <variableentries> VariableList %type <variableentry> VariableEntry @@ -1204,6 +1205,8 @@ PortType PredefOrIdentifier PredefinedOps PredefinedValue +ProfilerRunningOp +ProfilerStatement RaiseStatement Range ReadTimerOp @@ -1711,12 +1714,12 @@ optRunsOnComprefOrSelf %left '*' '/' ModKeyword RemKeyword %left UnarySign -%expect 24 +%expect 25 %start GrammarRoot /* -XXX Source of conflicts (24 S/R): +XXX Source of conflicts (25 S/R): 1.) 8 conflicts in one state The Expression after 'return' keyword is optional in ReturnStatement. @@ -1754,9 +1757,14 @@ non-standard language extension. 6.) 1 Conflict due to pattern concatenation +7.) 1 conflict +The TitanSpecificProfilerKeyword following the ReturnKeyword in a ReturnStatement +can either be the returned boolean value if followed by the DotRunningKeyword (shift) +or the next statement if followed by the DotStartKeyword or the DotStopKeyword (reduce). + Note that the parser implemented by bison always chooses to shift instead of reduce in case of conflicts. This is the desired behaviour in situations 1.), -2.) and 4.) since the opposite alternative can be forced by the correct usage +2.), 4.) and 7.) since the opposite alternative can be forced by the correct usage of semi-colons. Situation 3.) does not cause any problems as anytype is not supported at the moment. */ @@ -3910,6 +3918,7 @@ FunctionStatement: // 180 | SUTStatements {$$=$1;} | StopExecutionStatement { $$ = $1; } | StopTestcaseStatement { $$ = $1; } +| ProfilerStatement { $$ = $1; } ; FunctionInstance: /* refpard */ // 181 @@ -5078,6 +5087,7 @@ ControlStatement: /* Statement *stmt */ // 295 | BehaviourStatements { $$ = $1; } | SUTStatements { $$ = $1; } | StopExecutionStatement { $$ = $1; } +| ProfilerStatement { $$ = $1; } ; /* A.1.6.2.1 Variable instantiation */ @@ -7538,6 +7548,26 @@ StopTestcaseStatement: } ; + /* these deliberately don't have their locations set */ +ProfilerStatement: + TitanSpecificProfilerKeyword DotStartKeyword + { + $$ = new Statement(Statement::S_START_PROFILER); + } +| TitanSpecificProfilerKeyword DotStopKeyword + { + $$ = new Statement(Statement::S_STOP_PROFILER); + } +; + +ProfilerRunningOp: + TitanSpecificProfilerKeyword DotRunningKeyword + { + $$ = new Value(Value::OPTYPE_PROF_RUNNING); + $$->set_location(infile, @$); + } +; + ReturnStatement: // 552 ReturnKeyword { @@ -8336,6 +8366,7 @@ OpCall: // 611 else $$ = new Value(Value::V_ERROR); $$->set_location(infile, @$); } +| ProfilerRunningOp { $$ = $1; } ; PredefinedOps: diff --git a/compiler2/ttcn3/profiler.c b/compiler2/ttcn3/profiler.c new file mode 100644 index 000000000..4c09a3e16 --- /dev/null +++ b/compiler2/ttcn3/profiler.c @@ -0,0 +1,126 @@ +/****************************************************************************** + * Copyright (c) 2000-2015 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 + ******************************************************************************/ + +#include "profiler.h" +#include "../../common/memory.h" +#include <string.h> +#include <stdio.h> + +/** The file list */ +static tcov_file_list *the_files = 0; + +/** The database */ +static profiler_data_t *the_data = 0; + +/** The current database index for the next get_profiler_code_line() call */ +static int current_index = 0; + +/** The file parameter for the last get_profiler_code_line() call */ +static char* last_file_name = 0; + +void init_profiler_data(tcov_file_list* p_file_list) +{ + the_files = p_file_list; + the_data = (profiler_data_t*)Malloc(sizeof(profiler_data_t)); + the_data->nof_lines = 0; + the_data->size = 4; + the_data->lines = (profiler_code_line_t*)Malloc( + the_data->size * sizeof(profiler_code_line_t)); +} + +boolean is_file_profiled(const char* p_file_name) +{ + tcov_file_list* file_walker = the_files; + while (0 != file_walker) { + if (0 == strcmp(p_file_name, file_walker->file_name)) { + return TRUE; + } + /* check for .ttcnpp instead of .ttcn */ + size_t file_name_len = strlen(file_walker->file_name); + if ('p' == file_walker->file_name[file_name_len - 1] && + 'p' == file_walker->file_name[file_name_len - 2] && + 0 == strncmp(p_file_name, file_walker->file_name, file_name_len - 2)) { + return TRUE; + } + file_walker = file_walker->next; + } + return FALSE; +} + +void insert_profiler_code_line(const char* p_file_name, + const char* p_function_name, int p_line_no) +{ + /* check if the entry already exists */ + int i; + for (i = 0; i < the_data->nof_lines; ++i) { + if (0 == strcmp(p_file_name,the_data->lines[i].file_name) && + p_line_no == the_data->lines[i].line_no) { + if (0 == the_data->lines[i].function_name && 0 != p_function_name) { + the_data->lines[i].function_name = mcopystr(p_function_name); + } + return; + } + } + if (the_data->nof_lines == the_data->size) { + /* database size reached, increase the buffer size (exponentially) */ + the_data->size *= 2; + the_data->lines = (profiler_code_line_t*)Realloc(the_data->lines, + the_data->size * sizeof(profiler_code_line_t)); + } + the_data->lines[the_data->nof_lines].file_name = mcopystr(p_file_name); + if (0 != p_function_name) { + the_data->lines[the_data->nof_lines].function_name = mcopystr(p_function_name); + } + else { + the_data->lines[the_data->nof_lines].function_name = 0; + } + the_data->lines[the_data->nof_lines].line_no = p_line_no; + ++the_data->nof_lines; +} + +boolean get_profiler_code_line(const char *p_file_name, + char **p_function_name, int *p_line_no) +{ + if (0 == last_file_name || 0 != strcmp(last_file_name, p_file_name)) { + /* file parameter changed, reset the current index and store the new file name */ + current_index = 0; + Free(last_file_name); + last_file_name = mcopystr(p_file_name); + } + while (current_index < the_data->nof_lines) { + /* find the first entry in the specified file and return it */ + if (0 == strcmp(p_file_name, the_data->lines[current_index].file_name)) { + *p_function_name = the_data->lines[current_index].function_name; + *p_line_no = the_data->lines[current_index].line_no; + ++current_index; + return TRUE; + } + ++current_index; + } + /* no entry found with the specified file name */ + return FALSE; +} + +void free_profiler_data() +{ + int i; + for (i = 0; i < the_data->nof_lines; ++i) { + Free(the_data->lines[i].file_name); + Free(the_data->lines[i].function_name); + } + Free(the_data->lines); + Free(the_data); + Free(last_file_name); + + while (0 != the_files) { + tcov_file_list *next_file = the_files->next; + Free(the_files->file_name); + Free(the_files); + the_files = next_file; + } +} diff --git a/compiler2/ttcn3/profiler.h b/compiler2/ttcn3/profiler.h new file mode 100644 index 000000000..ab00cccd0 --- /dev/null +++ b/compiler2/ttcn3/profiler.h @@ -0,0 +1,74 @@ +/****************************************************************************** + * Copyright (c) 2000-2015 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 + ******************************************************************************/ + +#ifndef PROFILER_H +#define PROFILER_H + +#include "../main.hh" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Structure containing one code line or function for the profiler */ +typedef struct profiler_code_line_t { + /** Name of the file containing this line */ + char* file_name; + /** Name of the function that starts at this line (or null if no function starts here) */ + char* function_name; + /** Code line number */ + int line_no; +} profiler_code_line_t; + +/** Profiler database + * + * Contains entries for the code lines in the processed TTCN-3 files. + * Used for initializing the TTCN3_Profiler (in runtime) with all the code + * lines and functions in the processed files, so it can determine which the + * unused lines and functions. */ +typedef struct profiler_data_t { + profiler_code_line_t *lines; + int nof_lines; + int size; +} profiler_data_t; + +/** Initializes the database (must be called once, at the start of compilation) */ +void init_profiler_data(tcov_file_list* p_file_list); + +/** Returns 1 if the specified file is in the profiler's file list, + * otherwise returns 0.*/ +boolean is_file_profiled(const char* p_file_name); + +/** Inserts one code line or function to the database + * @param p_file_name [in] name of the file containing the line/function + * @param p_function_name [in] name of the function (for functions) or null (for lines) + * @param p_line_no [in] line number (for lines) or the function's starting line + * (for functions) */ +void insert_profiler_code_line(const char* p_file_name, + const char* p_function_name, int p_line_no); + +/** Retrieves the next code line or function from the specified file. Calling this + * function with the same file parameter will keep returning the next code line + * or function until the end of the database is reached. If the file parameter is + * changed, the function will start again from the beginning of the database. + * @param p_file_name [in] name of the file to search for + * @param p_function_name [out] contains the function name if a function was found + * @param p_line_no [out] contains the line number of function start line + * @return 1 if a line or function was found, otherwise 0 */ +boolean get_profiler_code_line(const char *p_file_name, + char **p_function_name, int *p_line_no); + +/** Frees the database (must be called once, at the end of compilation) */ +void free_profiler_data(); + +#ifdef __cplusplus +} +#endif + +#endif /* PROFILER_H */ + diff --git a/core/ASN_CharacterString.cc b/core/ASN_CharacterString.cc index f4ae4a5d7..edbd97a36 100644 --- a/core/ASN_CharacterString.cc +++ b/core/ASN_CharacterString.cc @@ -37,55 +37,55 @@ make the type descriptors of embedded types static static const ASN_Tag_t CHARACTER_STRING_identification_tag_[] = { { ASN_TAG_CONT, 0u }}; static const ASN_BERdescriptor_t CHARACTER_STRING_identification_ber_ = { 1u, CHARACTER_STRING_identification_tag_ }; -static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_descr_ = { "CHARACTER STRING.identification", &CHARACTER_STRING_identification_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; +static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_descr_ = { "CHARACTER STRING.identification", &CHARACTER_STRING_identification_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t CHARACTER_STRING_identification_syntaxes_abstract_tag_[] = { { ASN_TAG_CONT, 0u }}; static const ASN_BERdescriptor_t CHARACTER_STRING_identification_syntaxes_abstract_ber_ = { 1u, CHARACTER_STRING_identification_syntaxes_abstract_tag_ }; -static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_syntaxes_abstract_descr_ = { "CHARACTER STRING.identification.syntaxes.abstract", &CHARACTER_STRING_identification_syntaxes_abstract_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; +static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_syntaxes_abstract_descr_ = { "CHARACTER STRING.identification.syntaxes.abstract", &CHARACTER_STRING_identification_syntaxes_abstract_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; static const ASN_Tag_t CHARACTER_STRING_identification_syntaxes_transfer_tag_[] = { { ASN_TAG_CONT, 1u }}; const ASN_BERdescriptor_t CHARACTER_STRING_identification_syntaxes_transfer_ber_ = { 1u, CHARACTER_STRING_identification_syntaxes_transfer_tag_ }; -const TTCN_Typedescriptor_t CHARACTER_STRING_identification_syntaxes_transfer_descr_ = { "CHARACTER STRING.identification.syntaxes.transfer", &CHARACTER_STRING_identification_syntaxes_transfer_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; +const TTCN_Typedescriptor_t CHARACTER_STRING_identification_syntaxes_transfer_descr_ = { "CHARACTER STRING.identification.syntaxes.transfer", &CHARACTER_STRING_identification_syntaxes_transfer_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; static const ASN_Tag_t CHARACTER_STRING_identification_syntaxes_tag_[] = { { ASN_TAG_CONT, 0u }}; static const ASN_BERdescriptor_t CHARACTER_STRING_identification_syntaxes_ber_ = { 1u, CHARACTER_STRING_identification_syntaxes_tag_ }; -static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_syntaxes_descr_ = { "CHARACTER STRING.identification.syntaxes", &CHARACTER_STRING_identification_syntaxes_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; +static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_syntaxes_descr_ = { "CHARACTER STRING.identification.syntaxes", &CHARACTER_STRING_identification_syntaxes_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t CHARACTER_STRING_identification_syntax_tag_[] = { { ASN_TAG_CONT, 1u }}; static const ASN_BERdescriptor_t CHARACTER_STRING_identification_syntax_ber_ = { 1u, CHARACTER_STRING_identification_syntax_tag_ }; -static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_syntax_descr_ = { "CHARACTER STRING.identification.syntax", &CHARACTER_STRING_identification_syntax_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; +static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_syntax_descr_ = { "CHARACTER STRING.identification.syntax", &CHARACTER_STRING_identification_syntax_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; static const ASN_Tag_t CHARACTER_STRING_identification_presentation__context__id_tag_[] = { { ASN_TAG_CONT, 2u }}; static const ASN_BERdescriptor_t CHARACTER_STRING_identification_presentation__context__id_ber_ = { 1u, CHARACTER_STRING_identification_presentation__context__id_tag_ }; -static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_presentation__context__id_descr_ = { "CHARACTER STRING.identification.presentation-context-id", &CHARACTER_STRING_identification_presentation__context__id_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; +static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_presentation__context__id_descr_ = { "CHARACTER STRING.identification.presentation-context-id", &CHARACTER_STRING_identification_presentation__context__id_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t CHARACTER_STRING_identification_context__negotiation_presentation__context__id_tag_[] = { { ASN_TAG_CONT, 0u }}; static const ASN_BERdescriptor_t CHARACTER_STRING_identification_context__negotiation_presentation__context__id_ber_ = { 1u, CHARACTER_STRING_identification_context__negotiation_presentation__context__id_tag_ }; -static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_context__negotiation_presentation__context__id_descr_ = { "CHARACTER STRING.identification.context-negotiation.presentation-context-id", &CHARACTER_STRING_identification_context__negotiation_presentation__context__id_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; +static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_context__negotiation_presentation__context__id_descr_ = { "CHARACTER STRING.identification.context-negotiation.presentation-context-id", &CHARACTER_STRING_identification_context__negotiation_presentation__context__id_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t CHARACTER_STRING_identification_context__negotiation_transfer__syntax_tag_[] = { { ASN_TAG_CONT, 1u }}; static const ASN_BERdescriptor_t CHARACTER_STRING_identification_context__negotiation_transfer__syntax_ber_ = { 1u, CHARACTER_STRING_identification_context__negotiation_transfer__syntax_tag_ }; -static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_context__negotiation_transfer__syntax_descr_ = { "CHARACTER STRING.identification.context-negotiation.transfer-syntax", &CHARACTER_STRING_identification_context__negotiation_transfer__syntax_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; +static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_context__negotiation_transfer__syntax_descr_ = { "CHARACTER STRING.identification.context-negotiation.transfer-syntax", &CHARACTER_STRING_identification_context__negotiation_transfer__syntax_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; static const ASN_Tag_t CHARACTER_STRING_identification_context__negotiation_tag_[] = { { ASN_TAG_CONT, 3u }}; static const ASN_BERdescriptor_t CHARACTER_STRING_identification_context__negotiation_ber_ = { 1u, CHARACTER_STRING_identification_context__negotiation_tag_ }; -static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_context__negotiation_descr_ = { "CHARACTER STRING.identification.context-negotiation", &CHARACTER_STRING_identification_context__negotiation_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; +static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_context__negotiation_descr_ = { "CHARACTER STRING.identification.context-negotiation", &CHARACTER_STRING_identification_context__negotiation_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t CHARACTER_STRING_identification_transfer__syntax_tag_[] = { { ASN_TAG_CONT, 4u }}; static const ASN_BERdescriptor_t CHARACTER_STRING_identification_transfer__syntax_ber_ = { 1u, CHARACTER_STRING_identification_transfer__syntax_tag_ }; -static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_transfer__syntax_descr_ = { "CHARACTER STRING.identification.transfer-syntax", &CHARACTER_STRING_identification_transfer__syntax_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; +static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_transfer__syntax_descr_ = { "CHARACTER STRING.identification.transfer-syntax", &CHARACTER_STRING_identification_transfer__syntax_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; static const ASN_Tag_t CHARACTER_STRING_identification_fixed_tag_[] = { { ASN_TAG_CONT, 5u }}; static const ASN_BERdescriptor_t CHARACTER_STRING_identification_fixed_ber_ = { 1u, CHARACTER_STRING_identification_fixed_tag_ }; -static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_fixed_descr_ = { "CHARACTER STRING.identification.fixed", &CHARACTER_STRING_identification_fixed_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; +static const TTCN_Typedescriptor_t CHARACTER_STRING_identification_fixed_descr_ = { "CHARACTER STRING.identification.fixed", &CHARACTER_STRING_identification_fixed_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t CHARACTER_STRING_string__value_tag_[] = { { ASN_TAG_CONT, 2u }}; static const ASN_BERdescriptor_t CHARACTER_STRING_string__value_ber_ = { 1u, CHARACTER_STRING_string__value_tag_ }; -static const TTCN_Typedescriptor_t CHARACTER_STRING_string__value_descr_ = { "CHARACTER STRING.string-value", &CHARACTER_STRING_string__value_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; +static const TTCN_Typedescriptor_t CHARACTER_STRING_string__value_descr_ = { "CHARACTER STRING.string-value", &CHARACTER_STRING_string__value_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t CHARACTER_STRING_data__value__descriptor_tag_[] = { { ASN_TAG_CONT, 1u }}; static const ASN_BERdescriptor_t CHARACTER_STRING_data__value__descriptor_ber_ = { 1u, CHARACTER_STRING_data__value__descriptor_tag_ }; -static const TTCN_Typedescriptor_t CHARACTER_STRING_data__value__descriptor_descr_ = { "CHARACTER STRING.data-value-descriptor", &CHARACTER_STRING_data__value__descriptor_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::GRAPHICSTRING }; +static const TTCN_Typedescriptor_t CHARACTER_STRING_data__value__descriptor_descr_ = { "CHARACTER STRING.data-value-descriptor", &CHARACTER_STRING_data__value__descriptor_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::GRAPHICSTRING }; void CHARACTER_STRING_identification::clean_up() { diff --git a/core/ASN_EmbeddedPDV.cc b/core/ASN_EmbeddedPDV.cc index 7a05319d6..11cfeed96 100644 --- a/core/ASN_EmbeddedPDV.cc +++ b/core/ASN_EmbeddedPDV.cc @@ -37,55 +37,55 @@ make the type descriptors of embedded types static static const ASN_Tag_t EMBEDDED_PDV_identification_tag_[] = { { ASN_TAG_CONT, 0u }}; static const ASN_BERdescriptor_t EMBEDDED_PDV_identification_ber_ = { 1u, EMBEDDED_PDV_identification_tag_ }; -static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_descr_ = { "EMBEDDED PDV.identification", &EMBEDDED_PDV_identification_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; +static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_descr_ = { "EMBEDDED PDV.identification", &EMBEDDED_PDV_identification_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t EMBEDDED_PDV_identification_syntaxes_abstract_tag_[] = { { ASN_TAG_CONT, 0u }}; static const ASN_BERdescriptor_t EMBEDDED_PDV_identification_syntaxes_abstract_ber_ = { 1u, EMBEDDED_PDV_identification_syntaxes_abstract_tag_ }; -static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_syntaxes_abstract_descr_ = { "EMBEDDED PDV.identification.syntaxes.abstract", &EMBEDDED_PDV_identification_syntaxes_abstract_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; +static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_syntaxes_abstract_descr_ = { "EMBEDDED PDV.identification.syntaxes.abstract", &EMBEDDED_PDV_identification_syntaxes_abstract_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; static const ASN_Tag_t EMBEDDED_PDV_identification_syntaxes_transfer_tag_[] = { { ASN_TAG_CONT, 1u }}; static const ASN_BERdescriptor_t EMBEDDED_PDV_identification_syntaxes_transfer_ber_ = { 1u, EMBEDDED_PDV_identification_syntaxes_transfer_tag_ }; -static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_syntaxes_transfer_descr_ = { "EMBEDDED PDV.identification.syntaxes.transfer", &EMBEDDED_PDV_identification_syntaxes_transfer_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; +static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_syntaxes_transfer_descr_ = { "EMBEDDED PDV.identification.syntaxes.transfer", &EMBEDDED_PDV_identification_syntaxes_transfer_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; static const ASN_Tag_t EMBEDDED_PDV_identification_syntaxes_tag_[] = { { ASN_TAG_CONT, 0u }}; static const ASN_BERdescriptor_t EMBEDDED_PDV_identification_syntaxes_ber_ = { 1u, EMBEDDED_PDV_identification_syntaxes_tag_ }; -static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_syntaxes_descr_ = { "EMBEDDED PDV.identification.syntaxes", &EMBEDDED_PDV_identification_syntaxes_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; +static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_syntaxes_descr_ = { "EMBEDDED PDV.identification.syntaxes", &EMBEDDED_PDV_identification_syntaxes_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t EMBEDDED_PDV_identification_syntax_tag_[] = { { ASN_TAG_CONT, 1u }}; static const ASN_BERdescriptor_t EMBEDDED_PDV_identification_syntax_ber_ = { 1u, EMBEDDED_PDV_identification_syntax_tag_ }; -static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_syntax_descr_ = { "EMBEDDED PDV.identification.syntax", &EMBEDDED_PDV_identification_syntax_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; +static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_syntax_descr_ = { "EMBEDDED PDV.identification.syntax", &EMBEDDED_PDV_identification_syntax_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; static const ASN_Tag_t EMBEDDED_PDV_identification_presentation__context__id_tag_[] = { { ASN_TAG_CONT, 2u }}; static const ASN_BERdescriptor_t EMBEDDED_PDV_identification_presentation__context__id_ber_ = { 1u, EMBEDDED_PDV_identification_presentation__context__id_tag_ }; -static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_presentation__context__id_descr_ = { "EMBEDDED PDV.identification.presentation-context-id", &EMBEDDED_PDV_identification_presentation__context__id_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; +static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_presentation__context__id_descr_ = { "EMBEDDED PDV.identification.presentation-context-id", &EMBEDDED_PDV_identification_presentation__context__id_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t EMBEDDED_PDV_identification_context__negotiation_presentation__context__id_tag_[] = { { ASN_TAG_CONT, 0u }}; static const ASN_BERdescriptor_t EMBEDDED_PDV_identification_context__negotiation_presentation__context__id_ber_ = { 1u, EMBEDDED_PDV_identification_context__negotiation_presentation__context__id_tag_ }; -static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_context__negotiation_presentation__context__id_descr_ = { "EMBEDDED PDV.identification.context-negotiation.presentation-context-id", &EMBEDDED_PDV_identification_context__negotiation_presentation__context__id_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; +static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_context__negotiation_presentation__context__id_descr_ = { "EMBEDDED PDV.identification.context-negotiation.presentation-context-id", &EMBEDDED_PDV_identification_context__negotiation_presentation__context__id_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t EMBEDDED_PDV_identification_context__negotiation_transfer__syntax_tag_[] = { { ASN_TAG_CONT, 1u }}; static const ASN_BERdescriptor_t EMBEDDED_PDV_identification_context__negotiation_transfer__syntax_ber_ = { 1u, EMBEDDED_PDV_identification_context__negotiation_transfer__syntax_tag_ }; -static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_context__negotiation_transfer__syntax_descr_ = { "EMBEDDED PDV.identification.context-negotiation.transfer-syntax", &EMBEDDED_PDV_identification_context__negotiation_transfer__syntax_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; +static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_context__negotiation_transfer__syntax_descr_ = { "EMBEDDED PDV.identification.context-negotiation.transfer-syntax", &EMBEDDED_PDV_identification_context__negotiation_transfer__syntax_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; static const ASN_Tag_t EMBEDDED_PDV_identification_context__negotiation_tag_[] = { { ASN_TAG_CONT, 3u }}; static const ASN_BERdescriptor_t EMBEDDED_PDV_identification_context__negotiation_ber_ = { 1u, EMBEDDED_PDV_identification_context__negotiation_tag_ }; -static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_context__negotiation_descr_ = { "EMBEDDED PDV.identification.context-negotiation", &EMBEDDED_PDV_identification_context__negotiation_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; +static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_context__negotiation_descr_ = { "EMBEDDED PDV.identification.context-negotiation", &EMBEDDED_PDV_identification_context__negotiation_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t EMBEDDED_PDV_identification_transfer__syntax_tag_[] = { { ASN_TAG_CONT, 4u }}; static const ASN_BERdescriptor_t EMBEDDED_PDV_identification_transfer__syntax_ber_ = { 1u, EMBEDDED_PDV_identification_transfer__syntax_tag_ }; -static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_transfer__syntax_descr_ = { "EMBEDDED PDV.identification.transfer-syntax", &EMBEDDED_PDV_identification_transfer__syntax_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; +static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_transfer__syntax_descr_ = { "EMBEDDED PDV.identification.transfer-syntax", &EMBEDDED_PDV_identification_transfer__syntax_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::OBJID }; static const ASN_Tag_t EMBEDDED_PDV_identification_fixed_tag_[] = { { ASN_TAG_CONT, 5u }}; static const ASN_BERdescriptor_t EMBEDDED_PDV_identification_fixed_ber_ = { 1u, EMBEDDED_PDV_identification_fixed_tag_ }; -static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_fixed_descr_ = { "EMBEDDED PDV.identification.fixed", &EMBEDDED_PDV_identification_fixed_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; +static const TTCN_Typedescriptor_t EMBEDDED_PDV_identification_fixed_descr_ = { "EMBEDDED PDV.identification.fixed", &EMBEDDED_PDV_identification_fixed_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t EMBEDDED_PDV_data__value_tag_[] = { { ASN_TAG_CONT, 2u }}; static const ASN_BERdescriptor_t EMBEDDED_PDV_data__value_ber_ = { 1u, EMBEDDED_PDV_data__value_tag_ }; -static const TTCN_Typedescriptor_t EMBEDDED_PDV_data__value_descr_ = { "EMBEDDED PDV.data-value", &EMBEDDED_PDV_data__value_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; +static const TTCN_Typedescriptor_t EMBEDDED_PDV_data__value_descr_ = { "EMBEDDED PDV.data-value", &EMBEDDED_PDV_data__value_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t EMBEDDED_PDV_data__value__descriptor_tag_[] = { { ASN_TAG_CONT, 1u }}; static const ASN_BERdescriptor_t EMBEDDED_PDV_data__value__descriptor_ber_ = { 1u, EMBEDDED_PDV_data__value__descriptor_tag_ }; -static const TTCN_Typedescriptor_t EMBEDDED_PDV_data__value__descriptor_descr_ = { "EMBEDDED PDV.data-value-descriptor", &EMBEDDED_PDV_data__value__descriptor_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::GRAPHICSTRING }; +static const TTCN_Typedescriptor_t EMBEDDED_PDV_data__value__descriptor_descr_ = { "EMBEDDED PDV.data-value-descriptor", &EMBEDDED_PDV_data__value__descriptor_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::GRAPHICSTRING }; /******************** EMBEDDED_PDV_identification ********************/ diff --git a/core/ASN_External.cc b/core/ASN_External.cc index 65e7e3dd0..4cc701ff0 100644 --- a/core/ASN_External.cc +++ b/core/ASN_External.cc @@ -197,19 +197,19 @@ namespace { /* anonymous namespace */ field_encoding.octet__aligned()=ex.data__value(); } - static const TTCN_Typedescriptor_t EXTERNALtransfer_encoding_descr_ = { "EXTERNALtransfer.encoding", &CHOICE_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; + static const TTCN_Typedescriptor_t EXTERNALtransfer_encoding_descr_ = { "EXTERNALtransfer.encoding", &CHOICE_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t EXTERNALtransfer_encoding_single__ASN1__type_tag_[] = { { ASN_TAG_CONT, 0u } }; static const ASN_BERdescriptor_t EXTERNALtransfer_encoding_single__ASN1__type_ber_ = { 1u, EXTERNALtransfer_encoding_single__ASN1__type_tag_ }; - static const TTCN_Typedescriptor_t EXTERNALtransfer_encoding_single__ASN1__type_descr_ = { "EXTERNALtransfer.encoding.single-ASN1-type", &EXTERNALtransfer_encoding_single__ASN1__type_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; + static const TTCN_Typedescriptor_t EXTERNALtransfer_encoding_single__ASN1__type_descr_ = { "EXTERNALtransfer.encoding.single-ASN1-type", &EXTERNALtransfer_encoding_single__ASN1__type_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t EXTERNALtransfer_encoding_octet__aligned_tag_[] = { { ASN_TAG_CONT, 1u } }; static const ASN_BERdescriptor_t EXTERNALtransfer_encoding_octet__aligned_ber_ = { 1u, EXTERNALtransfer_encoding_octet__aligned_tag_ }; - static const TTCN_Typedescriptor_t EXTERNALtransfer_encoding_octet__aligned_descr_ = { "EXTERNALtransfer.encoding.octet-aligned", &EXTERNALtransfer_encoding_octet__aligned_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; + static const TTCN_Typedescriptor_t EXTERNALtransfer_encoding_octet__aligned_descr_ = { "EXTERNALtransfer.encoding.octet-aligned", &EXTERNALtransfer_encoding_octet__aligned_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; static const ASN_Tag_t EXTERNALtransfer_encoding_arbitrary_tag_[] = { { ASN_TAG_CONT, 2u } }; static const ASN_BERdescriptor_t EXTERNALtransfer_encoding_arbitrary_ber_ = { 1u, EXTERNALtransfer_encoding_arbitrary_tag_ }; - static const TTCN_Typedescriptor_t EXTERNALtransfer_encoding_arbitrary_descr_ = { "EXTERNALtransfer.encoding.arbitrary", &EXTERNALtransfer_encoding_arbitrary_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; + static const TTCN_Typedescriptor_t EXTERNALtransfer_encoding_arbitrary_descr_ = { "EXTERNALtransfer.encoding.arbitrary", &EXTERNALtransfer_encoding_arbitrary_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE }; /* Member functions of C++ classes */ diff --git a/core/Array.hh b/core/Array.hh index bfbfde7ea..bb34bb2a3 100644 --- a/core/Array.hh +++ b/core/Array.hh @@ -36,7 +36,11 @@ extern unsigned int get_timer_array_index(const INTEGER& index_value, * * */ template <typename T_type, unsigned int array_size, int index_offset> -class TIMER_ARRAY { +class TIMER_ARRAY +#ifdef TITAN_RUNTIME_2 + : public RefdIndexInterface +#endif +{ T_type array_elements[array_size]; char * names[array_size]; @@ -85,13 +89,6 @@ public: } TTCN_Logger::log_event_str(" }"); } - -#ifdef TITAN_RUNTIME_2 - // Dummy functions, only used in record of/set of in RT2 (the referenced indices - // cannot be deleted, since arrays have a fixed size) - void add_refd_index(int) {} - void remove_refd_index(int) {} -#endif }; extern unsigned int get_port_array_index(int index_value, @@ -100,7 +97,11 @@ extern unsigned int get_port_array_index(const INTEGER& index_value, unsigned int array_size, int index_offset); template <typename T_type, unsigned int array_size, int index_offset> -class PORT_ARRAY { +class PORT_ARRAY +#ifdef TITAN_RUNTIME_2 + : public RefdIndexInterface +#endif +{ T_type array_elements[array_size]; char * names[array_size]; @@ -152,13 +153,6 @@ public: } TTCN_Logger::log_event_str(" }"); } - -#ifdef TITAN_RUNTIME_2 - // Dummy functions, only used in record of/set of in RT2 (the referenced indices - // cannot be deleted, since arrays have a fixed size) - void add_refd_index(int) {} - void remove_refd_index(int) {} -#endif }; //////////////////////////////////////////////////////////////////////////////// @@ -170,6 +164,9 @@ extern unsigned int get_array_index(const INTEGER& index_value, template <typename T_type, unsigned int array_size, int index_offset> class VALUE_ARRAY : public Base_Type +#ifdef TITAN_RUNTIME_2 + , public RefdIndexInterface +#endif { T_type array_elements[array_size]; public: @@ -240,13 +237,6 @@ public: /** Decodes accordingly to the JSON encoding rules. * Returns the length of the decoded data. */ int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean); - -#ifdef TITAN_RUNTIME_2 - // Dummy functions, only used in record of/set of in RT2 (the referenced indices - // cannot be deleted, since arrays have a fixed size) - void add_refd_index(int) {} - void remove_refd_index(int) {} -#endif }; template <typename T_type, unsigned int array_size, int index_offset> diff --git a/core/Basetype.cc b/core/Basetype.cc index 104e6b0f9..c64c2f767 100644 --- a/core/Basetype.cc +++ b/core/Basetype.cc @@ -1086,101 +1086,101 @@ const Base_Type* TTCN_Type_list::get_nth(size_t pos) const } const TTCN_Typedescriptor_t BOOLEAN_descr_={"BOOLEAN", &BOOLEAN_ber_, - &BOOLEAN_raw_, &BOOLEAN_text_, &BOOLEAN_xer_, &BOOLEAN_json_, TTCN_Typedescriptor_t::DONTCARE}; + &BOOLEAN_raw_, &BOOLEAN_text_, &BOOLEAN_xer_, &BOOLEAN_json_, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t INTEGER_descr_={"INTEGER", &INTEGER_ber_, - &INTEGER_raw_, &INTEGER_text_, &INTEGER_xer_, &INTEGER_json_, TTCN_Typedescriptor_t::DONTCARE}; + &INTEGER_raw_, &INTEGER_text_, &INTEGER_xer_, &INTEGER_json_, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t FLOAT_descr_={"REAL", &FLOAT_ber_, &FLOAT_raw_, - NULL, &FLOAT_xer_, &FLOAT_json_, TTCN_Typedescriptor_t::DONTCARE}; + NULL, &FLOAT_xer_, &FLOAT_json_, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t VERDICTTYPE_descr_={"verdicttype", NULL, NULL, - NULL, &VERDICTTYPE_xer_, &VERDICTTYPE_json_, TTCN_Typedescriptor_t::DONTCARE}; + NULL, &VERDICTTYPE_xer_, &VERDICTTYPE_json_, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t OBJID_descr_={"OBJECT IDENTIFIER", &OBJID_ber_, - NULL, NULL, &OBJID_xer_, &OBJID_json_, TTCN_Typedescriptor_t::OBJID}; + NULL, NULL, &OBJID_xer_, &OBJID_json_, NULL, TTCN_Typedescriptor_t::OBJID}; const TTCN_Typedescriptor_t BITSTRING_descr_={"BIT STRING", &BITSTRING_ber_, - &BITSTRING_raw_, NULL, &BITSTRING_xer_, &BITSTRING_json_, TTCN_Typedescriptor_t::DONTCARE}; + &BITSTRING_raw_, NULL, &BITSTRING_xer_, &BITSTRING_json_, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t HEXSTRING_descr_={"hexstring", NULL, - &HEXSTRING_raw_, NULL, &HEXSTRING_xer_, &HEXSTRING_json_, TTCN_Typedescriptor_t::DONTCARE}; + &HEXSTRING_raw_, NULL, &HEXSTRING_xer_, &HEXSTRING_json_, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t OCTETSTRING_descr_={"OCTET STRING", - &OCTETSTRING_ber_, &OCTETSTRING_raw_, &OCTETSTRING_text_, &OCTETSTRING_xer_, &OCTETSTRING_json_, TTCN_Typedescriptor_t::DONTCARE}; + &OCTETSTRING_ber_, &OCTETSTRING_raw_, &OCTETSTRING_text_, &OCTETSTRING_xer_, &OCTETSTRING_json_, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t CHARSTRING_descr_={"charstring", NULL, - &CHARSTRING_raw_, &CHARSTRING_text_, &CHARSTRING_xer_, &CHARSTRING_json_, TTCN_Typedescriptor_t::DONTCARE}; + &CHARSTRING_raw_, &CHARSTRING_text_, &CHARSTRING_xer_, &CHARSTRING_json_, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t UNIVERSAL_CHARSTRING_descr_={"universal charstring", - NULL, NULL, NULL, &UNIVERSAL_CHARSTRING_xer_, &UNIVERSAL_CHARSTRING_json_, TTCN_Typedescriptor_t::DONTCARE}; + NULL, NULL, &UNIVERSAL_CHARSTRING_text_, &UNIVERSAL_CHARSTRING_xer_, &UNIVERSAL_CHARSTRING_json_, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t COMPONENT_descr_={"component", NULL, NULL, NULL, - NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; + NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t DEFAULT_descr_={"default", NULL, NULL, NULL, - NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; + NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t ASN_NULL_descr_={"NULL", &ASN_NULL_ber_, NULL, - NULL, &ASN_NULL_xer_, &ASN_NULL_json_, TTCN_Typedescriptor_t::DONTCARE}; + NULL, &ASN_NULL_xer_, &ASN_NULL_json_, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t ASN_ANY_descr_={"ANY", &ASN_ANY_ber_, NULL, - NULL, NULL, &ASN_ANY_json_, TTCN_Typedescriptor_t::DONTCARE}; + NULL, NULL, &ASN_ANY_json_, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t EXTERNAL_descr_={"EXTERNAL", &EXTERNAL_ber_, NULL, - NULL, &EXTERNAL_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE}; + NULL, &EXTERNAL_xer_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t EMBEDDED_PDV_descr_={"EMBEDDED PDV", - &EMBEDDED_PDV_ber_, NULL, NULL, &EMBEDDED_PDV_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE}; + &EMBEDDED_PDV_ber_, NULL, NULL, &EMBEDDED_PDV_xer_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t CHARACTER_STRING_descr_={"CHARACTER STRING", - &CHARACTER_STRING_ber_, NULL, NULL, &CHARACTER_STRING_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE}; + &CHARACTER_STRING_ber_, NULL, NULL, &CHARACTER_STRING_xer_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t ObjectDescriptor_descr_={"ObjectDescriptor", - &ObjectDescriptor_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::GRAPHICSTRING}; + &ObjectDescriptor_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::GRAPHICSTRING}; const TTCN_Typedescriptor_t UTF8String_descr_={"UTF8String", &UTF8String_ber_, - NULL, NULL, &UTF8String_xer_, NULL, TTCN_Typedescriptor_t::UTF8STRING}; + NULL, NULL, &UTF8String_xer_, NULL, NULL, TTCN_Typedescriptor_t::UTF8STRING}; const TTCN_Typedescriptor_t ASN_ROID_descr_={"RELATIVE-OID", &ASN_ROID_ber_, - NULL, NULL, &ASN_ROID_xer_, &ASN_ROID_json_, TTCN_Typedescriptor_t::ROID}; + NULL, NULL, &ASN_ROID_xer_, &ASN_ROID_json_, NULL, TTCN_Typedescriptor_t::ROID}; const TTCN_Typedescriptor_t NumericString_descr_={"NumericString", - &NumericString_ber_, NULL, NULL, &NumericString_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE}; + &NumericString_ber_, NULL, NULL, &NumericString_xer_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t PrintableString_descr_={"PrintableString", - &PrintableString_ber_, NULL, NULL, &PrintableString_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE}; + &PrintableString_ber_, NULL, NULL, &PrintableString_xer_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t TeletexString_descr_={"TeletexString", - &TeletexString_ber_, NULL, NULL, &TeletexString_xer_, NULL, TTCN_Typedescriptor_t::TELETEXSTRING}; + &TeletexString_ber_, NULL, NULL, &TeletexString_xer_, NULL, NULL, TTCN_Typedescriptor_t::TELETEXSTRING}; const TTCN_Typedescriptor_t& T61String_descr_=TeletexString_descr_; const TTCN_Typedescriptor_t VideotexString_descr_={"VideotexString", - &VideotexString_ber_, NULL, NULL, &VideotexString_xer_, NULL, TTCN_Typedescriptor_t::VIDEOTEXSTRING}; + &VideotexString_ber_, NULL, NULL, &VideotexString_xer_, NULL, NULL, TTCN_Typedescriptor_t::VIDEOTEXSTRING}; const TTCN_Typedescriptor_t IA5String_descr_={"IA5String", &IA5String_ber_, - NULL, NULL, &IA5String_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE}; + NULL, NULL, &IA5String_xer_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t ASN_GeneralizedTime_descr_={"GeneralizedTime", - &ASN_GeneralizedTime_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; + &ASN_GeneralizedTime_ber_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t ASN_UTCTime_descr_={"UTCTime", &ASN_UTCTime_ber_, - NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; + NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t GraphicString_descr_={"GraphicString", - &GraphicString_ber_, NULL, NULL, &GraphicString_xer_, NULL, TTCN_Typedescriptor_t::GRAPHICSTRING}; + &GraphicString_ber_, NULL, NULL, &GraphicString_xer_, NULL, NULL, TTCN_Typedescriptor_t::GRAPHICSTRING}; const TTCN_Typedescriptor_t VisibleString_descr_={"VisibleString", - &VisibleString_ber_, NULL, NULL, &VisibleString_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE}; + &VisibleString_ber_, NULL, NULL, &VisibleString_xer_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; const TTCN_Typedescriptor_t& ISO646String_descr_=VisibleString_descr_; const TTCN_Typedescriptor_t GeneralString_descr_={"GeneralString", - &GeneralString_ber_, NULL, NULL, &GeneralString_xer_, NULL, TTCN_Typedescriptor_t::GENERALSTRING}; + &GeneralString_ber_, NULL, NULL, &GeneralString_xer_, NULL, NULL, TTCN_Typedescriptor_t::GENERALSTRING}; const TTCN_Typedescriptor_t UniversalString_descr_={"UniversalString", - &UniversalString_ber_, NULL, NULL, &UniversalString_xer_, NULL, TTCN_Typedescriptor_t::UNIVERSALSTRING}; + &UniversalString_ber_, NULL, NULL, &UniversalString_xer_, NULL, NULL, TTCN_Typedescriptor_t::UNIVERSALSTRING}; const TTCN_Typedescriptor_t BMPString_descr_={"BMPString", &BMPString_ber_, - NULL, NULL, &BMPString_xer_, NULL, TTCN_Typedescriptor_t::BMPSTRING}; + NULL, NULL, &BMPString_xer_, NULL, NULL, TTCN_Typedescriptor_t::BMPSTRING}; diff --git a/core/Basetype.hh b/core/Basetype.hh index 2e4937555..76323a4e0 100644 --- a/core/Basetype.hh +++ b/core/Basetype.hh @@ -12,10 +12,11 @@ #include "Encdec.hh" #include "RInt.hh" #include "JSON_Tokenizer.hh" -#include "Vector.hh" #ifdef TITAN_RUNTIME_2 #include "Struct_of.hh" #include "XER.hh" +#include "Vector.hh" +#include "RefdIndex.hh" #endif struct ASN_BERdescriptor_t; @@ -43,6 +44,7 @@ struct TTCN_Typedescriptor_t { const TTCN_TEXTdescriptor_t * const text; /**< Information for TEXT coding */ const XERdescriptor_t * const xer; /**< Information for XER */ const TTCN_JSONdescriptor_t * const json; /**< Information for JSON coding */ + const TTCN_Typedescriptor_t * const oftype_descr; /**< Record-of element's type descriptor */ /** ASN subtype * * Used by classes implementing more than one ASN.1 type @@ -642,7 +644,7 @@ class INTEGER; * */ // Record_Of_Template can be found in Template.hh -class Record_Of_Type : public Base_Type +class Record_Of_Type : public Base_Type, public RefdIndexInterface { friend class Set_Of_Template; friend class Record_Of_Template; @@ -776,7 +778,7 @@ public: virtual int XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, unsigned flavor, int indent, embed_values_enc_struct_t*) const; /// Helper for XER_encode_negtest - int encode_element(int i, const Erroneous_values_t* err_vals, + int encode_element(int i, const XERdescriptor_t& p_td, const Erroneous_values_t* err_vals, const Erroneous_descriptor_t* emb_descr, TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t* emb_val) const; virtual int XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*); @@ -794,8 +796,6 @@ public: /** @returns \c true if this is a set-of type, * \c false if this is a record-of type */ virtual boolean is_set() const = 0; - /** return the type descriptor of the element */ - virtual const TTCN_Typedescriptor_t* get_elem_descr() const = 0; /** creates an instance of the record's element class, using the default constructor */ virtual Base_Type* create_elem() const = 0; @@ -812,12 +812,12 @@ public: /** Indicates that the element at the given index is referenced by an 'out' or * 'inout' parameter and must not be deleted. * Used just before the actual function call that references the element. */ - void add_refd_index(int index); + virtual void add_refd_index(int index); /** Indicates that the element at the given index is no longer referenced by * an 'out' or 'inout' parameter. * Used immediately after the actual function call that referenced the element. */ - void remove_refd_index(int index); + virtual void remove_refd_index(int index); }; extern boolean operator==(null_type null_value, diff --git a/core/Component.cc b/core/Component.cc index 7d57b546e..66f3604ed 100644 --- a/core/Component.cc +++ b/core/Component.cc @@ -124,21 +124,31 @@ void COMPONENT::kill() const void COMPONENT::set_param(Module_Param& param) { param.basic_check(Module_Param::BC_VALUE, "component reference (integer or null) value"); - switch (param.get_type()) { - case Module_Param::MP_Integer: - component_value = (component)param.get_integer()->get_val(); - break; - case Module_Param::MP_Ttcn_Null: + if (Ttcn_String_Parsing::happening()) { + // accept all component values in case it's a string2ttcn operation + switch (param.get_type()) { + case Module_Param::MP_Integer: + component_value = (component)param.get_integer()->get_val(); + break; + case Module_Param::MP_Ttcn_Null: + component_value = NULL_COMPREF; + break; + case Module_Param::MP_Ttcn_mtc: + component_value = MTC_COMPREF; + break; + case Module_Param::MP_Ttcn_system: + component_value = SYSTEM_COMPREF; + break; + default: + param.type_error("component reference (integer or null) value"); + } + } + else { + // only accept the null value if it's a module parameter + if (Module_Param::MP_Ttcn_Null != param.get_type()) { + param.error("Only the 'null' value is allowed for module parameters of type 'component'."); + } component_value = NULL_COMPREF; - break; - case Module_Param::MP_Ttcn_mtc: - component_value = MTC_COMPREF; - break; - case Module_Param::MP_Ttcn_system: - component_value = SYSTEM_COMPREF; - break; - default: - param.type_error("component reference (integer or null) value"); } } diff --git a/core/Float.cc b/core/Float.cc index 50c1c919e..59d6a43cf 100644 --- a/core/Float.cc +++ b/core/Float.cc @@ -793,9 +793,66 @@ int FLOAT::XER_encode(const XERdescriptor_t& p_td, return (int)p_buf.get_len() - encoded_length; } +boolean FLOAT::is_float(const char* p_str) +{ + bool first_digit = false; // first digit reached + bool decimal_point = false; // decimal point (.) reached + bool exponent_mark = false; // exponential mark (e or E) reached + bool exponent_sign = false; // sign of the exponential (- or +) reached + + if ('-' == *p_str || '+' == *p_str) { + ++p_str; + } + + while (0 != *p_str) { + switch(*p_str) { + case '.': + if (decimal_point || exponent_mark || !first_digit) { + return false; + } + decimal_point = true; + first_digit = false; + break; + case 'e': + case 'E': + if (exponent_mark || !first_digit) { + return false; + } + exponent_mark = true; + first_digit = false; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + first_digit = true; + break; + case '-': + case '+': + if (exponent_sign || !exponent_mark || first_digit) { + return false; + } + exponent_sign = true; + break; + default: + return false; + } + + ++p_str; + } + return first_digit; +} + int FLOAT::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, unsigned int flavor, embed_values_dec_struct_t*) { + bound_flag = false; int exer = is_exer(flavor); int success = reader.Ok(), depth = -1; if (success <= 0) return 0; @@ -807,8 +864,10 @@ int FLOAT::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, tagless: const char * value = (const char *)reader.Value(); - if (value && sscanf(value, "%lf", &float_value)) + if (value && is_float(value)) { bound_flag = true; + sscanf(value, "%lf", &float_value); + } // Let the caller do reader.AdvanceAttribute(); } @@ -828,8 +887,10 @@ tagless: } else if (XML_READER_TYPE_TEXT == type && depth != -1) { const char * value = (const char*)reader.Value(); - if (value && sscanf(value, "%lf", &float_value) == 1) + if (value && is_float(value)) { bound_flag = true; + sscanf(value, "%lf", &float_value); + } } else if (XML_READER_TYPE_END_ELEMENT == type) { verify_end(reader, p_td, depth, exer); diff --git a/core/Float.hh b/core/Float.hh index 013d39de7..18e6faa35 100644 --- a/core/Float.hh +++ b/core/Float.hh @@ -41,6 +41,10 @@ class FLOAT : public Base_Type { boolean bound_flag; ttcn3float float_value; + + /** Returns true if the string parameter contains the string representation + * of a real number, otherwise returns false. */ + boolean is_float(const char* p_str); public: diff --git a/core/Makefile b/core/Makefile index ff35320ae..ce0f040b6 100644 --- a/core/Makefile +++ b/core/Makefile @@ -12,9 +12,13 @@ include $(TOP)/Makefile.cfg SCHEMAS := TitanLoggerApi.xsd # Generated from `TitanLoggerApi.xsd'. GENERATED_MODULES := TitanLoggerApi.ttcn + +PREGENERATOR_MODULES := PreGenRecordOf.ttcn GENERATED_LOGGERAPI_SOURCES := $(GENERATED_MODULES:.ttcn=.cc) GENERATED_LOGGERCONTROL_SOURCES := TitanLoggerControl.cc + +PREGENERATED_SOURCES := $(PREGENERATOR_MODULES:.ttcn=.cc) ORIGINATORS := TitanLoggerApi.xsd TitanLoggerApi.ttcn TitanLoggerControl.ttcn gccversion.c \ config_process.l config_process.y @@ -33,12 +37,14 @@ endif # These directories (RT1/RT2) are replicated inside $(INCDIR) GENERATED_LOGGERAPI_SOURCES := $(addprefix $(APIDIR)/,$(GENERATED_LOGGERAPI_SOURCES)) GENERATED_LOGGERCONTROL_SOURCES := $(addprefix $(APIDIR)/,$(GENERATED_LOGGERCONTROL_SOURCES)) +PREGENERATED_SOURCES := $(addprefix $(APIDIR)/,$(PREGENERATED_SOURCES)) GENERATED_SOURCES := $(GENERATED_LOGGERAPI_SOURCES) $(GENERATED_LOGGERCONTROL_SOURCES) config_process.lex.cc config_process.tab.cc +GENERATED_SOURCES += $(PREGENERATED_SOURCES) GENERATED_HEADERS := $(GENERATED_LOGGERAPI_SOURCES:.cc=.hh) $(GENERATED_LOGGERCONTROL_SOURCES:.cc=.hh) config_process.tab.hh config_process.lex.hh -GENERATED_HEADERS += $(GENERATED_LOGGERAPI_SOURCES:.cc=Simple.hh) +GENERATED_HEADERS += $(GENERATED_LOGGERAPI_SOURCES:.cc=Simple.hh) $(PREGENERATED_SOURCES:.cc=.hh) GENERATED_OTHERS := $(GENERATED_LOGGERAPI_SOURCES).compiled $(GENERATED_LOGGERCONTROL_SOURCES).compiled -GENERATED_OTHERS += config_process.output lex.backup +GENERATED_OTHERS += $(PREGENERATED_SOURCES).compiled config_process.output lex.backup TTCN_COMPILER_FLAGS := ifeq ($(FUNCTION_TEST_RUNTIME), yes) @@ -157,7 +163,7 @@ Port.hh Event_Handler.hh Struct_of.hh Array.hh Optional.hh Textbuf.hh Encdec.hh Module_list.hh Parameters.h Addfunc.hh RAW.hh BER.hh TEXT.hh ASN_Null.hh \ ASN_Any.hh ASN_External.hh ASN_EmbeddedPDV.hh ASN_CharacterString.hh XER.hh \ XmlReader.hh cversion.h TitanLoggerControl.ttcn TitanLoggerApi.xsd Vector.hh \ -JSON.hh Profiler.hh +JSON.hh Profiler.hh RefdIndex.hh # Copied during "make install" ifdef REGEX_DIR @@ -257,6 +263,7 @@ endif endif mkdir -p $(INCDIR)/$(APIDIR) cp $(APIDIR)/TitanLoggerApi*.hh $(INCDIR)/$(APIDIR) + cp $(APIDIR)/PreGenRecordOf.hh $(INCDIR)/$(APIDIR) # # # # executables single$(RT2_SUFFIX)$(EXESUFFIX): $(LIBRARY) @@ -350,6 +357,17 @@ $(GENERATED_LOGGERCONTROL_SOURCES).compiled:: TitanLoggerControl.ttcn mkdir -p $(APIDIR) ../compiler2/compiler$(EXESUFFIX) $(TTCN_COMPILER_FLAGS) $^ - $? touch $@ + +$(PREGENERATED_SOURCES): $(PREGENERATED_SOURCES).compiled + @if [ ! -f $@ ]; then $(RM) $<; $(MAKE) $<; fi + +$(PREGENERATED_SOURCES).compiled:: ../compiler2/compiler$(EXESUFFIX) + @if [ -f $@ ]; then $(RM) $@; $(MAKE) $@; fi + +$(PREGENERATED_SOURCES).compiled:: $(PREGENERATOR_MODULES) + mkdir -p $(APIDIR) + ../compiler2/compiler$(EXESUFFIX) -F $(TTCN_COMPILER_FLAGS) $^ - $? + touch $@ include ../Makefile.genrules diff --git a/core/Module_list.cc b/core/Module_list.cc index a382c4d70..e6f19ba6c 100644 --- a/core/Module_list.cc +++ b/core/Module_list.cc @@ -95,8 +95,6 @@ void Module_List::pre_init_modules() { for (TTCN_Module *list_iter = list_head; list_iter != NULL; list_iter = list_iter->list_next) list_iter->pre_init_module(); - - send_versions(); } void Module_List::post_init_modules() diff --git a/core/Optional.hh b/core/Optional.hh index 85e14757f..3ac4d32fa 100644 --- a/core/Optional.hh +++ b/core/Optional.hh @@ -25,7 +25,11 @@ enum optional_sel { OPTIONAL_UNBOUND, OPTIONAL_OMIT, OPTIONAL_PRESENT }; template <typename T_type> -class OPTIONAL : public Base_Type { +class OPTIONAL : public Base_Type +#ifdef TITAN_RUNTIME_2 + , public RefdIndexInterface +#endif +{ /** The value, if present (owned by OPTIONAL) * In Runtime2 the pointer is null, when the value is not present. * In Runtime1 its presence is indicated by the optional_selection member. */ @@ -319,19 +323,13 @@ public: * 'inout' or 'out' parameter to a function (only in Runtime2). * Sets the optional value to present (this would be done by the indexing operation * anyway) and redirects the call to the optional value. */ - void add_refd_index(int index); + virtual void add_refd_index(int index); /** Called after an element of an optional record of/set of is passed as an * 'inout' or 'out' parameter to a function (only in Runtime2). * Redirects the call to the optional value. */ - void remove_refd_index(int index); + virtual void remove_refd_index(int index); #endif - - /** Called before an element of an optional record of/set of is passed as an - * 'inout' or 'out' parameter to a function. Returns the size of the record of/ - * set of. - * Redirects the call to the optional value. */ - int size_of(); }; #if HAVE_GCC(4,6) @@ -827,14 +825,20 @@ void OPTIONAL<T_type>::add_refd_index(int index) { ++param_refs; set_to_present(); - optional_value->add_refd_index(index); + RefdIndexInterface* refd_opt_val = dynamic_cast<RefdIndexInterface*>(optional_value); + if (0 != refd_opt_val) { + refd_opt_val->add_refd_index(index); + } } template<typename T_type> void OPTIONAL<T_type>::remove_refd_index(int index) { --param_refs; - optional_value->remove_refd_index(index); + RefdIndexInterface* refd_opt_val = dynamic_cast<RefdIndexInterface*>(optional_value); + if (0 != refd_opt_val) { + refd_opt_val->remove_refd_index(index); + } } #endif @@ -1005,6 +1009,12 @@ OPTIONAL<T_type>::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader, // we already checked for exer==1 if (!check_namespace((const char*)reader.NamespaceUri(), p_td)) break; + // set to omit if the attribute is empty + const char * value = (const char *)reader.Value(); + if (strlen(value) == 0) { + break; + } + set_to_present(); optional_value->XER_decode(p_td, reader, flavor, emb_val); goto finished; diff --git a/core/Parallel_main.cc b/core/Parallel_main.cc index ddd0242c8..2f6bdd22e 100644 --- a/core/Parallel_main.cc +++ b/core/Parallel_main.cc @@ -24,6 +24,9 @@ #include "Error.hh" #include "Encdec.hh" #include "TCov.hh" +#ifdef LINUX +#include <execinfo.h> +#endif #ifdef LICENSE #include "../common/license.h" @@ -35,7 +38,7 @@ const char * stored_argv = "Unidentified program"; //static const char segfault[] = " : Segmentation fault occurred\n"; -void signal_handler(int) +void signal_handler(int signum) { int retval; time_t now=time(0); @@ -44,7 +47,7 @@ void signal_handler(int) struct tm *tmp; tmp=localtime(&now); if(tmp==NULL){ - fprintf(stderr,"<Unknown> %s: Segmentation fault occurred\n",stored_argv); + fprintf(stderr,"<Unknown> %s: %s\n",stored_argv, signum==SIGABRT?"Abort was called":"Segmentation fault occurred"); } else { /* retval = write(STDERR_FILENO, stored_argv, strlen(stored_argv)); retval = write(STDERR_FILENO, segfault , sizeof(segfault)-1); // sizeof includes \0 @@ -52,10 +55,18 @@ void signal_handler(int) (void)retval; */ retval=strftime(ts,60,"%F %T",tmp); - fprintf(stderr,"%s %s: Segmentation fault occurred\n",ts,stored_argv); + fprintf(stderr,"%s %s: %s\n",ts,stored_argv,signum==SIGABRT?"Abort was called":"Segmentation fault occurred"); } fflush(stderr); +#ifdef LINUX + int nptrs; + void *buffer[100]; + nptrs = backtrace(buffer, 100); + backtrace_symbols_fd(buffer, nptrs, STDERR_FILENO); + fflush(stderr); +#endif + signal(SIGABRT, SIG_DFL); abort(); } @@ -185,6 +196,7 @@ int main(int argc, char *argv[]) sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGSEGV, &act, 0); + sigaction(SIGABRT, &act, 0); #ifdef MEMORY_DEBUG debug_new_counter.set_program_name(argv[0]); diff --git a/core/PreGenRecordOf.ttcn b/core/PreGenRecordOf.ttcn new file mode 100644 index 000000000..da2b0d54f --- /dev/null +++ b/core/PreGenRecordOf.ttcn @@ -0,0 +1,83 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2000-2015 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 +/////////////////////////////////////////////////////////////////////////////// + +// This module contains 'record of' and 'set of' type declarations for certain base types. +// It is used for pre-generating the C++ classes that represent these types, +// so they are not re-generated every time they are declared in TTCN-3 or ASN.1 +// modules. +module PreGenRecordOf { + +// 'record of' declarations (regular): +type record of boolean PREGEN_RECORD_OF_BOOLEAN; + +type record of integer PREGEN_RECORD_OF_INTEGER; + +type record of float PREGEN_RECORD_OF_FLOAT; + +type record of bitstring PREGEN_RECORD_OF_BITSTRING; + +type record of hexstring PREGEN_RECORD_OF_HEXSTRING; + +type record of octetstring PREGEN_RECORD_OF_OCTETSTRING; + +type record of charstring PREGEN_RECORD_OF_CHARSTRING; + +type record of universal charstring PREGEN_RECORD_OF_UNIVERSAL_CHARSTRING; + +// 'record of' declarations (with optimized memory allocation): +type record of boolean PREGEN_RECORD_OF_BOOLEAN_OPTIMIZED with { extension "optimize:memalloc" }; + +type record of integer PREGEN_RECORD_OF_INTEGER_OPTIMIZED with { extension "optimize:memalloc" }; + +type record of float PREGEN_RECORD_OF_FLOAT_OPTIMIZED with { extension "optimize:memalloc" }; + +type record of bitstring PREGEN_RECORD_OF_BITSTRING_OPTIMIZED with { extension "optimize:memalloc" }; + +type record of hexstring PREGEN_RECORD_OF_HEXSTRING_OPTIMIZED with { extension "optimize:memalloc" }; + +type record of octetstring PREGEN_RECORD_OF_OCTETSTRING_OPTIMIZED with { extension "optimize:memalloc" }; + +type record of charstring PREGEN_RECORD_OF_CHARSTRING_OPTIMIZED with { extension "optimize:memalloc" }; + +type record of universal charstring PREGEN_RECORD_OF_UNIVERSAL_CHARSTRING_OPTIMIZED with { extension "optimize:memalloc" }; + +// 'set of' declarations (regular): +type set of boolean PREGEN_SET_OF_BOOLEAN; + +type set of integer PREGEN_SET_OF_INTEGER; + +type set of float PREGEN_SET_OF_FLOAT; + +type set of bitstring PREGEN_SET_OF_BITSTRING; + +type set of hexstring PREGEN_SET_OF_HEXSTRING; + +type set of octetstring PREGEN_SET_OF_OCTETSTRING; + +type set of charstring PREGEN_SET_OF_CHARSTRING; + +type set of universal charstring PREGEN_SET_OF_UNIVERSAL_CHARSTRING; + +// 'set of' declarations (with optimized memory allocation): +type set of boolean PREGEN_SET_OF_BOOLEAN_OPTIMIZED with { extension "optimize:memalloc" }; + +type set of integer PREGEN_SET_OF_INTEGER_OPTIMIZED with { extension "optimize:memalloc" }; + +type set of float PREGEN_SET_OF_FLOAT_OPTIMIZED with { extension "optimize:memalloc" }; + +type set of bitstring PREGEN_SET_OF_BITSTRING_OPTIMIZED with { extension "optimize:memalloc" }; + +type set of hexstring PREGEN_SET_OF_HEXSTRING_OPTIMIZED with { extension "optimize:memalloc" }; + +type set of octetstring PREGEN_SET_OF_OCTETSTRING_OPTIMIZED with { extension "optimize:memalloc" }; + +type set of charstring PREGEN_SET_OF_CHARSTRING_OPTIMIZED with { extension "optimize:memalloc" }; + +type set of universal charstring PREGEN_SET_OF_UNIVERSAL_CHARSTRING_OPTIMIZED with { extension "optimize:memalloc" }; + +} diff --git a/core/Profiler.cc b/core/Profiler.cc index 860e5c8a0..e9d3b9f8d 100644 --- a/core/Profiler.cc +++ b/core/Profiler.cc @@ -7,13 +7,83 @@ /////////////////////////////////////////////////////////////////////////////// #include "Profiler.hh" -#include <sys/time.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "JSON_Tokenizer.hh" #include "memory.h" #include "Runtime.hh" +#include <unistd.h> +#include "Component.hh" + +//////////////////////////////////// +//////// timeval operations //////// +//////////////////////////////////// + +/** Reads a timeval value from the given string. The parameter must contain the + * string representation of a real number with 6 digits after the decimal dot. */ +static timeval string2timeval(const char* str) +{ + // read and store the first part (atoi will read until the decimal dot) + long int sec = atoi(str); + timeval tv; + tv.tv_sec = sec; + + do { + // step over each digit + sec /= 10; + ++str; + } + while (sec > 9); + + // step over the decimal dot and read the second part of the number + tv.tv_usec = atoi(str + 1); + return tv; +} + +/** Returns the string representation of a real number (with 6 digits after the + * decimal dot) equivalent to the timeval parameter. + * The returned character pointer needs to be freed. */ +static char* timeval2string(timeval tv) +{ + // convert the first part and set the second part to all zeros + char* str = mprintf("%ld.000000", tv.tv_sec); + + // go through each digit of the second part and add them to the zeros in the string + size_t pos = mstrlen(str) - 1; + while (tv.tv_usec > 0) { + str[pos] += tv.tv_usec % 10; + tv.tv_usec /= 10; + --pos; + } + return str; +} + +/** Adds the two timeval parameters together and returns the result. */ +static timeval add_timeval(const timeval operand1, const timeval operand2) +{ + timeval tv; + tv.tv_usec = operand1.tv_usec + operand2.tv_usec; + tv.tv_sec = operand1.tv_sec + operand2.tv_sec; + if (tv.tv_usec >= 1000000) { + ++tv.tv_sec; + tv.tv_usec -= 1000000; + } + return tv; +} + +/** Subtracts the second timeval parameter from the first one and returns the result. */ +static timeval subtract_timeval(const timeval operand1, const timeval operand2) +{ + timeval tv; + tv.tv_usec = operand1.tv_usec - operand2.tv_usec; + tv.tv_sec = operand1.tv_sec - operand2.tv_sec; + if (tv.tv_usec < 0) { + --tv.tv_sec; + tv.tv_usec += 1000000; + } + return tv; +} //////////////////////////////////// ////////// TTCN3_Profiler ////////// @@ -22,8 +92,8 @@ TTCN3_Profiler ttcn3_prof; TTCN3_Profiler::TTCN3_Profiler() -: disable_profiler(FALSE), disable_coverage(FALSE), aggregate_data(FALSE) -, disable_stats(FALSE) +: stopped(FALSE), disable_profiler(FALSE), disable_coverage(FALSE) +, aggregate_data(FALSE), disable_stats(FALSE), stats_flags(STATS_ALL) { database_filename = mcopystr("profiler.db"); stats_filename = mcopystr("profiler.stats"); @@ -32,8 +102,19 @@ TTCN3_Profiler::TTCN3_Profiler() TTCN3_Profiler::~TTCN3_Profiler() { - if (!disable_profiler || !disable_coverage) { - import_data(); + if (!profiler_db.empty() && (!disable_profiler || !disable_coverage)) { + if (aggregate_data && (TTCN_Runtime::is_single() || TTCN_Runtime::is_hc())) { + // import the data from the previous run + import_data(); + } + if (TTCN_Runtime::is_hc()) { + // import the data gathered by the other processes (the import function + // waits for them to finish exporting) + import_data(MTC_COMPREF); + for (size_t i = 0; i < ptc_list.size(); ++i) { + import_data(ptc_list[i]); + } + } export_data(); if (!disable_stats && (TTCN_Runtime::is_single() || TTCN_Runtime::is_hc())) { print_stats(); @@ -49,6 +130,27 @@ TTCN3_Profiler::~TTCN3_Profiler() Free(stats_filename); } +void TTCN3_Profiler::start() +{ + if (stopped) { + set_prev(disable_profiler ? -1 : TTCN3_Stack_Depth::depth(), NULL, -1); + stopped = FALSE; + } +} + +void TTCN3_Profiler::stop() +{ + if (!stopped) { + if (NULL != prev_file) { + // update the previous line's time + timeval elapsed = subtract_timeval(get_time(), prev_time); + add_line_time(elapsed, get_element(prev_file), prev_line); + TTCN3_Stack_Depth::update_stack_elapsed(elapsed); + } + stopped = TRUE; + } +} + void TTCN3_Profiler::set_disable_profiler(boolean p_disable_profiler) { disable_profiler = p_disable_profiler; @@ -81,41 +183,94 @@ void TTCN3_Profiler::set_disable_stats(boolean p_disable_stats) disable_stats = p_disable_stats; } +void TTCN3_Profiler::reset_stats_flags() +{ + stats_flags = 0; +} + +void TTCN3_Profiler::add_stats_flags(unsigned int p_flags) +{ + stats_flags |= p_flags; +} + boolean TTCN3_Profiler::is_profiler_disabled() const { return disable_profiler; } +boolean TTCN3_Profiler::is_running() const +{ + return !stopped; +} + +void TTCN3_Profiler::add_ptc(component p_comp_ref) +{ + ptc_list.push_back(p_comp_ref); +} + #define IMPORT_FORMAT_ERROR(cond) \ if (cond) { \ TTCN_warning("Database format is invalid. Profiler and/or code coverage data will not be loaded."); \ return; \ } -void TTCN3_Profiler::init_data_file() +void TTCN3_Profiler::import_data(component p_comp_ref /* = NULL_COMPREF */) { - // delete the database file (from the previous run) if data aggregation is not set - if (!aggregate_data && (!disable_profiler || !disable_coverage)) { - remove(database_filename); + char* file_name = NULL; + if (NULL_COMPREF == p_comp_ref) { + // this is the main database file (from the previous run), no suffix needed + file_name = database_filename; } -} - -void TTCN3_Profiler::import_data() -{ + else if (MTC_COMPREF == p_comp_ref) { + // this is the database for the MTC, suffix the file name with "mtc" + file_name = mprintf("%s.mtc", database_filename); + } + else { + // this is the database for one of the PTCs, suffix the file name with the + // component reference + file_name = mprintf("%s.%d", database_filename, p_comp_ref); + } + // open the file, if it exists - FILE* file = fopen(database_filename, "r"); - if (NULL == file) { - return; + int file_size = 0; + FILE* file = fopen(file_name, "r"); + if (NULL != file) { + // get the file size + fseek(file, 0, SEEK_END); + file_size = ftell(file); + } + while (0 == file_size) { + if (NULL_COMPREF == p_comp_ref) { + // no data from the previous run + return; + } + // as for the process-specific database files: keep reading until it appears + if (NULL != file) { + fclose(file); + } + usleep(1000); + file = fopen(file_name, "r"); + if (NULL != file) { + // refresh the file size + fseek(file, 0, SEEK_END); + file_size = ftell(file); + } } - // get the file size - fseek(file, 0, SEEK_END); - int file_size = ftell(file); + // rewind the file (the file pointer has been moved to the end of the file to + // calculate its size) rewind(file); // read the entire file into a character buffer char* buffer = (char*)Malloc(file_size); fread(buffer, 1, file_size, file); + fclose(file); + + if (NULL_COMPREF != p_comp_ref) { + // the process-specific database file is no longer needed + remove(file_name); + Free(file_name); + } // initialize a JSON tokenizer with the buffer JSON_Tokenizer json(buffer, file_size); @@ -202,33 +357,32 @@ void TTCN3_Profiler::import_data() func_data.name = function_name; func_data.lineno = start_line; func_data.exec_count = 0; - func_data.total_time = 0.0; + func_data.total_time.tv_sec = 0; + func_data.total_time.tv_usec = 0; profiler_db[file_index].functions.push_back(func_data); } - if (!disable_coverage) { - // function execution count: - json.get_next_token(&token, &value, &value_len); - IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 15 || - 0 != strncmp(value, "execution count", value_len)); + // function execution count: + json.get_next_token(&token, &value, &value_len); + IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 15 || + 0 != strncmp(value, "execution count", value_len)); - // read the execution count and add it to the current data - json.get_next_token(&token, &value, &value_len); - IMPORT_FORMAT_ERROR(JSON_TOKEN_NUMBER != token); - profiler_db[file_index].functions[function_index].exec_count += atoi(value); - } - - if (!disable_profiler) { - // total function execution time: - json.get_next_token(&token, &value, &value_len); - IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 10 || - 0 != strncmp(value, "total time", value_len)); + // read the execution count and add it to the current data + json.get_next_token(&token, &value, &value_len); + IMPORT_FORMAT_ERROR(JSON_TOKEN_NUMBER != token); + profiler_db[file_index].functions[function_index].exec_count += atoi(value); - // read the total time and add it to the current data - json.get_next_token(&token, &value, &value_len); - IMPORT_FORMAT_ERROR(JSON_TOKEN_NUMBER != token); - profiler_db[file_index].functions[function_index].total_time += atof(value); - } + // total function execution time: + json.get_next_token(&token, &value, &value_len); + IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 10 || + 0 != strncmp(value, "total time", value_len)); + + // read the total time and add it to the current data + // note: the database contains a real number, this needs to be split into 2 integers + json.get_next_token(&token, &value, &value_len); + IMPORT_FORMAT_ERROR(JSON_TOKEN_NUMBER != token); + profiler_db[file_index].functions[function_index].total_time = add_timeval( + profiler_db[file_index].functions[function_index].total_time, string2timeval(value)); // end of the function's object json.get_next_token(&token, NULL, NULL); @@ -251,6 +405,7 @@ void TTCN3_Profiler::import_data() IMPORT_FORMAT_ERROR(JSON_TOKEN_ARRAY_START != token); json.get_next_token(&token, NULL, NULL); while (JSON_TOKEN_OBJECT_START == token) { + int line_index = 0; // line number: json.get_next_token(&token, &value, &value_len); @@ -262,39 +417,32 @@ void TTCN3_Profiler::import_data() IMPORT_FORMAT_ERROR(JSON_TOKEN_NUMBER != token); int lineno = atoi(value); IMPORT_FORMAT_ERROR(lineno < 0); - size_t line_no = lineno; - if (line_no >= profiler_db[file_index].lines.size()) { - for (size_t i = profiler_db[file_index].lines.size(); i <= line_no; ++i) { - profiler_db_item_t::profiler_line_data_t line_data; - line_data.total_time = 0.0; - line_data.exec_count = 0; - profiler_db[file_index].lines.push_back(line_data); - } + line_index = get_line(file_index, lineno); + if (-1 == line_index) { + create_line(file_index, lineno); + line_index = profiler_db[file_index].lines.size() - 1; } - if (!disable_coverage) { - // line execution count: - json.get_next_token(&token, &value, &value_len); - IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 15 || - 0 != strncmp(value, "execution count", value_len)); + // line execution count: + json.get_next_token(&token, &value, &value_len); + IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 15 || + 0 != strncmp(value, "execution count", value_len)); - // read the execution count and add it to the current data - json.get_next_token(&token, &value, &value_len); - IMPORT_FORMAT_ERROR(JSON_TOKEN_NUMBER != token); - profiler_db[file_index].lines[line_no].exec_count += atoi(value); - } + // read the execution count and add it to the current data + json.get_next_token(&token, &value, &value_len); + IMPORT_FORMAT_ERROR(JSON_TOKEN_NUMBER != token); + profiler_db[file_index].lines[line_index].exec_count += atoi(value); - if (!disable_profiler) { - // total line execution time: - json.get_next_token(&token, &value, &value_len); - IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 10 || - 0 != strncmp(value, "total time", value_len)); + // total line execution time: + json.get_next_token(&token, &value, &value_len); + IMPORT_FORMAT_ERROR(JSON_TOKEN_NAME != token || value_len != 10 || + 0 != strncmp(value, "total time", value_len)); - // read the total time and add it to the current data - json.get_next_token(&token, &value, &value_len); - IMPORT_FORMAT_ERROR(JSON_TOKEN_NUMBER != token); - profiler_db[file_index].lines[line_no].total_time += atof(value); - } + // read the total time and add it to the current data + json.get_next_token(&token, &value, &value_len); + IMPORT_FORMAT_ERROR(JSON_TOKEN_NUMBER != token); + profiler_db[file_index].lines[line_index].total_time = add_timeval( + profiler_db[file_index].lines[line_index].total_time, string2timeval(value)); // end of the line's object json.get_next_token(&token, NULL, NULL); @@ -321,19 +469,36 @@ void TTCN3_Profiler::import_data() void TTCN3_Profiler::export_data() { - // nothing to export if the database is empty - if (profiler_db.empty()) { - return; + char* file_name = NULL; + if (TTCN_Runtime::is_single() || TTCN_Runtime::is_hc()) { + // this is the main database file, no suffix needed + file_name = database_filename; + } + else if (TTCN_Runtime::is_mtc()) { + // this is the database for the MTC, suffix the file name with "mtc" + file_name = mprintf("%s.mtc", database_filename); + } + else { + // this is the database for one of the PTCs, suffix the file name with the + // component reference + file_name = mprintf("%s.%d", database_filename, (component)self); } // check whether the file can be opened for writing - FILE* file = fopen(database_filename, "w"); + FILE* file = fopen(file_name, "w"); if (NULL == file) { TTCN_warning("Could not open file '%s' for writing. Profiler and/or code coverage " - "data will not be saved.", database_filename); + "data will not be saved.", file_name); + if (file_name != database_filename) { + Free(file_name); + } return; } + if (file_name != database_filename) { + Free(file_name); + } + // use the JSON tokenizer to create a JSON document from the database JSON_Tokenizer json(true); @@ -354,40 +519,47 @@ void TTCN3_Profiler::export_data() json.put_next_token(JSON_TOKEN_NAME, "functions"); json.put_next_token(JSON_TOKEN_ARRAY_START, NULL); for (size_t j = 0; j < profiler_db[i].functions.size(); ++j) { + // only store functions with actual data + if ((0 != profiler_db[i].functions[j].total_time.tv_sec && + 0 != profiler_db[i].functions[j].total_time.tv_usec) || + 0 != profiler_db[i].functions[j].exec_count) { - // the data is stored in an object for each function - json.put_next_token(JSON_TOKEN_OBJECT_START, NULL); - - // store the function name - json.put_next_token(JSON_TOKEN_NAME, "name"); - char* func_name_str = mprintf("\"%s\"", profiler_db[i].functions[j].name); - json.put_next_token(JSON_TOKEN_STRING, func_name_str); - Free(func_name_str); - - // store the function start line - json.put_next_token(JSON_TOKEN_NAME, "start line"); - char* start_line_str = mprintf("%d", profiler_db[i].functions[j].lineno); - json.put_next_token(JSON_TOKEN_NUMBER, start_line_str); - Free(start_line_str); - - if (!disable_coverage) { + // the data is stored in an object for each function + json.put_next_token(JSON_TOKEN_OBJECT_START, NULL); + + // store the function name + json.put_next_token(JSON_TOKEN_NAME, "name"); + char* func_name_str = mprintf("\"%s\"", profiler_db[i].functions[j].name); + json.put_next_token(JSON_TOKEN_STRING, func_name_str); + Free(func_name_str); + + // store the function start line + json.put_next_token(JSON_TOKEN_NAME, "start line"); + char* start_line_str = mprintf("%d", profiler_db[i].functions[j].lineno); + json.put_next_token(JSON_TOKEN_NUMBER, start_line_str); + Free(start_line_str); + // store the function execution count json.put_next_token(JSON_TOKEN_NAME, "execution count"); - char* exec_count_str = mprintf("%d", profiler_db[i].functions[j].exec_count); + char* exec_count_str = mprintf("%d", disable_coverage ? 0 : + profiler_db[i].functions[j].exec_count); json.put_next_token(JSON_TOKEN_NUMBER, exec_count_str); Free(exec_count_str); - } - - if (!disable_profiler) { + // store the function's total execution time json.put_next_token(JSON_TOKEN_NAME, "total time"); - char* exec_count_str = mprintf("%.6lf", profiler_db[i].functions[j].total_time); - json.put_next_token(JSON_TOKEN_NUMBER, exec_count_str); - Free(exec_count_str); + if (disable_profiler) { + json.put_next_token(JSON_TOKEN_NUMBER, "0.000000"); + } + else { + char* total_time_str = timeval2string(profiler_db[i].functions[j].total_time); + json.put_next_token(JSON_TOKEN_NUMBER, total_time_str); + Free(total_time_str); + } + + // end of function object + json.put_next_token(JSON_TOKEN_OBJECT_END, NULL); } - - // end of function object - json.put_next_token(JSON_TOKEN_OBJECT_END, NULL); } // end of function data array @@ -397,34 +569,38 @@ void TTCN3_Profiler::export_data() json.put_next_token(JSON_TOKEN_NAME, "lines"); json.put_next_token(JSON_TOKEN_ARRAY_START, NULL); for (size_t j = 0; j < profiler_db[i].lines.size(); ++j) { - if (0.0 != profiler_db[i].lines[j].total_time || + // only store lines with actual data + if ((0 != profiler_db[i].lines[j].total_time.tv_sec && + 0 != profiler_db[i].lines[j].total_time.tv_usec) || 0 != profiler_db[i].lines[j].exec_count) { - + // store line data in an object json.put_next_token(JSON_TOKEN_OBJECT_START, NULL); - + // store the line number json.put_next_token(JSON_TOKEN_NAME, "number"); - char* line_number_str = mprintf("%lu", j); + char* line_number_str = mprintf("%d", profiler_db[i].lines[j].lineno); json.put_next_token(JSON_TOKEN_NUMBER, line_number_str); Free(line_number_str); - - if (!disable_coverage) { - // store the line execution count - json.put_next_token(JSON_TOKEN_NAME, "execution count"); - char* exec_count_str = mprintf("%d", profiler_db[i].lines[j].exec_count); - json.put_next_token(JSON_TOKEN_NUMBER, exec_count_str); - Free(exec_count_str); - } - if (!disable_profiler) { - // store the line's total execution time - json.put_next_token(JSON_TOKEN_NAME, "total time"); - char* exec_count_str = mprintf("%.6lf", profiler_db[i].lines[j].total_time); - json.put_next_token(JSON_TOKEN_NUMBER, exec_count_str); - Free(exec_count_str); + // store the line execution count + json.put_next_token(JSON_TOKEN_NAME, "execution count"); + char* exec_count_str = mprintf("%d", disable_coverage ? 0 : + profiler_db[i].lines[j].exec_count); + json.put_next_token(JSON_TOKEN_NUMBER, exec_count_str); + Free(exec_count_str); + + // store the line's total execution time + json.put_next_token(JSON_TOKEN_NAME, "total time"); + if (disable_profiler) { + json.put_next_token(JSON_TOKEN_NUMBER, "0.000000"); } - + else { + char* total_time_str = timeval2string(profiler_db[i].lines[j].total_time); + json.put_next_token(JSON_TOKEN_NUMBER, total_time_str); + Free(total_time_str); + } + // end of this line's object json.put_next_token(JSON_TOKEN_OBJECT_END, NULL); } @@ -445,6 +621,43 @@ void TTCN3_Profiler::export_data() fclose(file); } +// Structure for one code line or function, used by print_stats for sorting +struct stats_data_t { + const char* filename; // not owned + const char* funcname; // not owned, NULL for code lines that don't start a function + int lineno; + timeval total_time; + int exec_count; +}; + +// Compare function for sorting stats data based on total execution time (descending) +int stats_data_cmp_time(const void* p_left, const void* p_right) { + const stats_data_t* p_left_data = (stats_data_t*)p_left; + const stats_data_t* p_right_data = (stats_data_t*)p_right; + if (p_left_data->total_time.tv_sec > p_right_data->total_time.tv_sec) return -1; + if (p_left_data->total_time.tv_sec < p_right_data->total_time.tv_sec) return 1; + if (p_left_data->total_time.tv_usec > p_right_data->total_time.tv_usec) return -1; + if (p_left_data->total_time.tv_usec < p_right_data->total_time.tv_usec) return 1; + return 0; +} + +// Compare function for sorting stats data based on execution count (descending) +int stats_data_cmp_count(const void* p_left, const void* p_right) { + return ((stats_data_t*)p_right)->exec_count - ((stats_data_t*)p_left)->exec_count; +} + +// Compare function for sorting stats data based on total time per execution count (descending) +int stats_data_cmp_avg(const void* p_left, const void* p_right) { + const stats_data_t* p_left_data = (stats_data_t*)p_left; + const stats_data_t* p_right_data = (stats_data_t*)p_right; + double left_time = p_left_data->total_time.tv_sec + p_left_data->total_time.tv_usec / 1000000.0; + double right_time = p_right_data->total_time.tv_sec + p_right_data->total_time.tv_usec / 1000000.0; + double diff = (right_time / p_right_data->exec_count) - (left_time / p_left_data->exec_count); + if (diff < 0) return -1; + if (diff > 0) return 1; + return 0; +} + void TTCN3_Profiler::print_stats() { if (profiler_db.empty()) { @@ -462,122 +675,804 @@ void TTCN3_Profiler::print_stats() , disable_coverage ? "" : "code coverage " , disable_profiler ? "######" : (disable_coverage ? "#########" : "")); + char* line_func_count_str = NULL; + if (stats_flags & STATS_NUMBER_OF_LINES) { + line_func_count_str = mcopystr( + "--------------------------------------\n" + "- Number of code lines and functions -\n" + "--------------------------------------\n"); + } + // line data - char* line_data_str = mprintf( - "-------------------------------------------------\n" - "%s- Code line data (%s%s%s) -%s\n" - "-------------------------------------------------\n" - , disable_profiler ? "-------" : (disable_coverage ? "---------" : "") - , disable_profiler ? "" : "total time" - , (disable_profiler || disable_coverage) ? "" : " / " - , disable_coverage ? "" : "execution count" - , disable_profiler ? "------" : (disable_coverage ? "---------" : "")); + char* line_data_str = NULL; + if (stats_flags & STATS_LINE_DATA_RAW) { + line_data_str = mprintf( + "-------------------------------------------------\n" + "%s- Code line data (%s%s%s) -%s\n" + "-------------------------------------------------\n" + , disable_profiler ? "-------" : (disable_coverage ? "---------" : "") + , disable_profiler ? "" : "total time" + , (disable_profiler || disable_coverage) ? "" : " / " + , disable_coverage ? "" : "execution count" + , disable_profiler ? "------" : (disable_coverage ? "---------" : "")); + } // average time / exec count for lines char* line_avg_str = NULL; - if (!disable_coverage && !disable_profiler) { + if (!disable_coverage && !disable_profiler && (stats_flags & STATS_LINE_AVG_RAW)) { line_avg_str = mcopystr( - "-------------------------------------------------\n" - "- Average time / execution count for code lines -\n" - "-------------------------------------------------\n"); + "-------------------------------------------\n" + "- Average time / execution for code lines -\n" + "-------------------------------------------\n"); } // function data - char* func_data_str = mprintf( - "------------------------------------------------\n" - "%s- Function data (%s%s%s) -%s\n" - "------------------------------------------------\n" - , disable_profiler ? "-------" : (disable_coverage ? "---------" : "") - , disable_profiler ? "" : "total time" - , (disable_profiler || disable_coverage) ? "" : " / " - , disable_coverage ? "" : "execution count" - , disable_profiler ? "------" : (disable_coverage ? "---------" : "")); + char* func_data_str = NULL; + if (stats_flags & STATS_FUNC_DATA_RAW) { + func_data_str = mprintf( + "------------------------------------------------\n" + "%s- Function data (%s%s%s) -%s\n" + "------------------------------------------------\n" + , disable_profiler ? "-------" : (disable_coverage ? "---------" : "") + , disable_profiler ? "" : "total time" + , (disable_profiler || disable_coverage) ? "" : " / " + , disable_coverage ? "" : "execution count" + , disable_profiler ? "------" : (disable_coverage ? "---------" : "")); + } // average time / exec count for functions char* func_avg_str = NULL; - if (!disable_coverage && !disable_profiler) { + if (!disable_coverage && !disable_profiler && (stats_flags & STATS_FUNC_AVG_RAW)) { func_avg_str = mcopystr( + "------------------------------------------\n" + "- Average time / execution for functions -\n" + "------------------------------------------\n"); + } + + char* line_time_sorted_mod_str = NULL; + if (!disable_profiler && (stats_flags & STATS_LINE_TIMES_SORTED_BY_MOD)) { + line_time_sorted_mod_str = mcopystr( + "------------------------------------------------\n" + "- Total time of code lines, sorted, per module -\n" + "------------------------------------------------\n"); + } + + char* line_count_sorted_mod_str = NULL; + if (!disable_coverage && (stats_flags & STATS_LINE_COUNT_SORTED_BY_MOD)) { + line_count_sorted_mod_str = mcopystr( + "-----------------------------------------------------\n" + "- Execution count of code lines, sorted, per module -\n" + "-----------------------------------------------------\n"); + } + + char* line_avg_sorted_mod_str = NULL; + if (!disable_profiler && !disable_coverage && (stats_flags & STATS_LINE_AVG_SORTED_BY_MOD)) { + line_avg_sorted_mod_str = mcopystr( + "--------------------------------------------------------------\n" + "- Average time / execution of code lines, sorted, per module -\n" + "--------------------------------------------------------------\n"); + } + + char* line_time_sorted_tot_str = NULL; + if (!disable_profiler && (stats_flags & STATS_LINE_TIMES_SORTED_TOTAL)) { + line_time_sorted_tot_str = mcopystr( + "-------------------------------------------\n" + "- Total time of code lines, sorted, total -\n" + "-------------------------------------------\n"); + } + + char* line_count_sorted_tot_str = NULL; + if (!disable_coverage && (stats_flags & STATS_LINE_COUNT_SORTED_TOTAL)) { + line_count_sorted_tot_str = mcopystr( "------------------------------------------------\n" - "- Average time / execution count for functions -\n" + "- Execution count of code lines, sorted, total -\n" "------------------------------------------------\n"); } + char* line_avg_sorted_tot_str = NULL; + if (!disable_profiler && !disable_coverage && (stats_flags & STATS_LINE_AVG_SORTED_TOTAL)) { + line_avg_sorted_tot_str = mcopystr( + "---------------------------------------------------------\n" + "- Average time / execution of code lines, sorted, total -\n" + "---------------------------------------------------------\n"); + } + + char* func_time_sorted_mod_str = NULL; + if (!disable_profiler && (stats_flags & STATS_FUNC_TIMES_SORTED_BY_MOD)) { + func_time_sorted_mod_str = mcopystr( + "-----------------------------------------------\n" + "- Total time of functions, sorted, per module -\n" + "-----------------------------------------------\n"); + } + + char* func_count_sorted_mod_str = NULL; + if (!disable_coverage && (stats_flags & STATS_FUNC_COUNT_SORTED_BY_MOD)) { + func_count_sorted_mod_str = mcopystr( + "----------------------------------------------------\n" + "- Execution count of functions, sorted, per module -\n" + "----------------------------------------------------\n"); + } + + char* func_avg_sorted_mod_str = NULL; + if (!disable_profiler && !disable_coverage && (stats_flags & STATS_FUNC_AVG_SORTED_BY_MOD)) { + func_avg_sorted_mod_str = mcopystr( + "-------------------------------------------------------------\n" + "- Average time / execution of functions, sorted, per module -\n" + "-------------------------------------------------------------\n"); + } + + char* func_time_sorted_tot_str = NULL; + if (!disable_profiler && (stats_flags & STATS_FUNC_TIMES_SORTED_TOTAL)) { + func_time_sorted_tot_str = mcopystr( + "------------------------------------------\n" + "- Total time of functions, sorted, total -\n" + "------------------------------------------\n"); + } + + char* func_count_sorted_tot_str = NULL; + if (!disable_coverage && (stats_flags & STATS_FUNC_COUNT_SORTED_TOTAL)) { + func_count_sorted_tot_str = mcopystr( + "-----------------------------------------------\n" + "- Execution count of functions, sorted, total -\n" + "-----------------------------------------------\n"); + } + + char* func_avg_sorted_tot_str = NULL; + if (!disable_profiler && !disable_coverage && (stats_flags & STATS_FUNC_AVG_SORTED_TOTAL)) { + func_avg_sorted_tot_str = mcopystr( + "--------------------------------------------------------\n" + "- Average time / execution of functions, sorted, total -\n" + "--------------------------------------------------------\n"); + } + + char* line_time_sorted_top10_str = NULL; + if (!disable_profiler && (stats_flags & STATS_TOP10_LINE_TIMES)) { + line_time_sorted_top10_str = mcopystr( + "------------------------------------\n" + "- Total time of code lines, top 10 -\n" + "------------------------------------\n"); + } + + char* line_count_sorted_top10_str = NULL; + if (!disable_coverage && (stats_flags & STATS_TOP10_LINE_COUNT)) { + line_count_sorted_top10_str = mcopystr( + "-----------------------------------------\n" + "- Execution count of code lines, top 10 -\n" + "-----------------------------------------\n"); + } + + char* line_avg_sorted_top10_str = NULL; + if (!disable_profiler && !disable_coverage && (stats_flags & STATS_TOP10_LINE_AVG)) { + line_avg_sorted_top10_str = mcopystr( + "--------------------------------------------------\n" + "- Average time / execution of code lines, top 10 -\n" + "--------------------------------------------------\n"); + } + + char* func_time_sorted_top10_str = NULL; + if (!disable_profiler && (stats_flags & STATS_TOP10_FUNC_TIMES)) { + func_time_sorted_top10_str = mcopystr( + "-----------------------------------\n" + "- Total time of functions, top 10 -\n" + "-----------------------------------\n"); + } + + char* func_count_sorted_top10_str = NULL; + if (!disable_coverage && (stats_flags & STATS_TOP10_FUNC_COUNT)) { + func_count_sorted_top10_str = mcopystr( + "----------------------------------------\n" + "- Execution count of functions, top 10 -\n" + "----------------------------------------\n"); + } + + char* func_avg_sorted_top10_str = NULL; + if (!disable_profiler && !disable_coverage && (stats_flags & STATS_TOP10_FUNC_AVG)) { + func_avg_sorted_top10_str = mcopystr( + "-------------------------------------------------\n" + "- Average time / execution of functions, top 10 -\n" + "-------------------------------------------------\n"); + } + + char* unused_lines_str = NULL; + char* unused_func_str = NULL; + if (!disable_coverage && (stats_flags & STATS_UNUSED_LINES)) { + unused_lines_str = mcopystr( + "---------------------\n" + "- Unused code lines -\n" + "---------------------\n"); + } + if (!disable_coverage && (stats_flags & STATS_UNUSED_FUNC)) { + unused_func_str = mcopystr( + "--------------------\n" + "- Unused functions -\n" + "--------------------\n"); + } + + // variables for counting totals, and for determining the amount of unused lines/functions + size_t total_code_lines = 0; + size_t total_functions = 0; + size_t used_code_lines = 0; + size_t used_functions = 0; + + // cached sizes of statistics data segments, needed to determine whether a separator + // is needed or not + size_t line_data_str_len = mstrlen(line_data_str); + size_t func_data_str_len = mstrlen(func_data_str); + size_t unused_lines_str_len = mstrlen(unused_lines_str); + size_t unused_func_str_len = mstrlen(unused_func_str); + size_t line_avg_str_len = mstrlen(line_avg_str); + size_t func_avg_str_len = mstrlen(func_avg_str); + // cycle through the database and gather the necessary data for (size_t i = 0; i < profiler_db.size(); ++i) { if (i > 0) { - // add separators between files - line_data_str = mputstr(line_data_str, "-------------------------------------------------\n"); - func_data_str = mputstr(func_data_str, "------------------------------------------------\n"); - if (!disable_profiler && !disable_coverage) { - line_avg_str = mputstr(line_avg_str, "-------------------------------------------------\n"); - func_avg_str = mputstr(func_avg_str, "------------------------------------------------\n"); + // add separators between files (only add them if the previous file actually added something) + if ((stats_flags & STATS_LINE_DATA_RAW) && line_data_str_len != mstrlen(line_data_str)) { + line_data_str = mputstr(line_data_str, "-------------------------------------------------\n"); + line_data_str_len = mstrlen(line_data_str); + } + if ((stats_flags & STATS_FUNC_DATA_RAW) && func_data_str_len != mstrlen(func_data_str)) { + func_data_str = mputstr(func_data_str, "------------------------------------------------\n"); + func_data_str_len = mstrlen(func_data_str); + } + if (!disable_coverage) { + if ((stats_flags & STATS_UNUSED_LINES) && unused_lines_str_len != mstrlen(unused_lines_str)) { + unused_lines_str = mputstr(unused_lines_str, "---------------------\n"); + unused_lines_str_len = mstrlen(unused_lines_str); + } + if ((stats_flags & STATS_UNUSED_FUNC) && unused_func_str_len != mstrlen(unused_func_str)) { + unused_func_str = mputstr(unused_func_str, "--------------------\n"); + unused_func_str_len = mstrlen(unused_func_str); + } + if (!disable_profiler) { + if ((stats_flags & STATS_LINE_AVG_RAW) && line_avg_str_len != mstrlen(line_avg_str)) { + line_avg_str = mputstr(line_avg_str, "-------------------------------------------\n"); + line_avg_str_len = mstrlen(line_avg_str); + } + if ((stats_flags & STATS_FUNC_AVG_RAW) && func_avg_str_len != mstrlen(func_avg_str)) { + func_avg_str = mputstr(func_avg_str, "------------------------------------------\n"); + func_avg_str_len = mstrlen(func_avg_str); + } + } } } // lines for (size_t j = 0; j < profiler_db[i].lines.size(); ++j) { - if (0.0 != profiler_db[i].lines[j].total_time || - 0 != profiler_db[i].lines[j].exec_count) { + // line specification (including function name for the function's start line) + char* line_spec_str = mprintf("%s:%d", profiler_db[i].filename, + profiler_db[i].lines[j].lineno); + int func = get_function(i, profiler_db[i].lines[j].lineno); + if (-1 != func) { + line_spec_str = mputprintf(line_spec_str, " [%s]", profiler_db[i].functions[func].name); + } + line_spec_str = mputstrn(line_spec_str, "\n", 1); + + if (disable_coverage || 0 != profiler_db[i].lines[j].exec_count) { if (!disable_profiler) { - line_data_str = mputprintf(line_data_str, "%.6lfs", profiler_db[i].lines[j].total_time); + if (stats_flags & STATS_LINE_DATA_RAW) { + char* total_time_str = timeval2string(profiler_db[i].lines[j].total_time); + line_data_str = mputprintf(line_data_str, "%ss", total_time_str); + Free(total_time_str); + } if (!disable_coverage) { - line_data_str = mputstrn(line_data_str, "\t/\t", 3); - line_avg_str = mputprintf(line_avg_str, "%.6lfs", - profiler_db[i].lines[j].total_time / profiler_db[i].lines[j].exec_count); + if (stats_flags & STATS_LINE_DATA_RAW) { + line_data_str = mputstrn(line_data_str, "\t/\t", 3); + } + if (stats_flags & STATS_LINE_AVG_RAW) { + double avg = (profiler_db[i].lines[j].total_time.tv_sec + + profiler_db[i].lines[j].total_time.tv_usec / 1000000.0) / + profiler_db[i].lines[j].exec_count; + char* total_time_str = timeval2string(profiler_db[i].lines[j].total_time); + line_avg_str = mputprintf(line_avg_str, "%.6lfs\t(%ss / %d)", + avg, total_time_str, profiler_db[i].lines[j].exec_count); + Free(total_time_str); + } } } - if (!disable_coverage) { + if (!disable_coverage && (stats_flags & STATS_LINE_DATA_RAW)) { line_data_str = mputprintf(line_data_str, "%d", profiler_db[i].lines[j].exec_count); } - - // line specification (including function name for the function's start line) - char* line_spec_str = mprintf("\t%s:%lu", profiler_db[i].filename, j); - int func = get_function(i, j); - if (-1 != func) { - line_spec_str = mputprintf(line_spec_str, " [%s]", profiler_db[i].functions[func].name); - } - line_spec_str = mputstrn(line_spec_str, "\n", 1); - + // add the line spec string to the other strings - line_data_str = mputstr(line_data_str, line_spec_str); - if (!disable_profiler && !disable_coverage) { - line_avg_str = mputstr(line_avg_str, line_spec_str); + if (stats_flags & STATS_LINE_DATA_RAW) { + line_data_str = mputprintf(line_data_str, "\t%s", line_spec_str); + } + if (!disable_profiler && !disable_coverage && (stats_flags & STATS_LINE_AVG_RAW)) { + line_avg_str = mputprintf(line_avg_str, "\t%s", line_spec_str); } + ++used_code_lines; } + else if (stats_flags & STATS_UNUSED_LINES) { + // unused line + unused_lines_str = mputstr(unused_lines_str, line_spec_str); + } + Free(line_spec_str); } // functions for (size_t j = 0; j < profiler_db[i].functions.size(); ++j) { - if (!disable_profiler) { - func_data_str = mputprintf(func_data_str, "%.6lfs", profiler_db[i].functions[j].total_time); - if (!disable_coverage) { - func_data_str = mputstrn(func_data_str, "\t/\t", 3); - func_avg_str = mputprintf(func_avg_str, "%.6lfs", - profiler_db[i].functions[j].total_time / profiler_db[i].functions[j].exec_count); + // functions specification + char* func_spec_str = mprintf("%s:%d [%s]\n", profiler_db[i].filename, + profiler_db[i].functions[j].lineno, profiler_db[i].functions[j].name); + + if (disable_coverage || 0 != profiler_db[i].functions[j].exec_count) { + if (!disable_profiler) { + if (stats_flags & STATS_FUNC_DATA_RAW) { + char* total_time_str = timeval2string(profiler_db[i].functions[j].total_time); + func_data_str = mputprintf(func_data_str, "%ss", total_time_str); + Free(total_time_str); + } + if (!disable_coverage) { + if (stats_flags & STATS_FUNC_DATA_RAW) { + func_data_str = mputstrn(func_data_str, "\t/\t", 3); + } + if (stats_flags & STATS_FUNC_AVG_RAW) { + double avg = (profiler_db[i].functions[j].total_time.tv_sec + + profiler_db[i].functions[j].total_time.tv_usec / 1000000.0) / + profiler_db[i].functions[j].exec_count; + char* total_time_str = timeval2string(profiler_db[i].functions[j].total_time); + func_avg_str = mputprintf(func_avg_str, "%.6lfs\t(%ss / %d)", + avg, total_time_str, profiler_db[i].functions[j].exec_count); + Free(total_time_str); + } + } + } + if (!disable_coverage && (stats_flags & STATS_FUNC_DATA_RAW)) { + func_data_str = mputprintf(func_data_str, "%d", profiler_db[i].functions[j].exec_count); + } + + // add the line spec string to the other strings + if (stats_flags & STATS_FUNC_DATA_RAW) { + func_data_str = mputprintf(func_data_str, "\t%s", func_spec_str); } + if (!disable_profiler && !disable_coverage && (stats_flags & STATS_FUNC_AVG_RAW)) { + func_avg_str = mputprintf(func_avg_str, "\t%s", func_spec_str); + } + + ++used_functions; } - if (!disable_coverage) { - func_data_str = mputprintf(func_data_str, "%d", profiler_db[i].functions[j].exec_count); + else if (stats_flags & STATS_UNUSED_FUNC) { + // unused function + unused_func_str = mputprintf(unused_func_str, func_spec_str); + } + Free(func_spec_str); + } + + // number of lines and functions + if (stats_flags & STATS_NUMBER_OF_LINES) { + line_func_count_str = mputprintf(line_func_count_str, "%s:\t%lu lines,\t%lu functions\n", + profiler_db[i].filename, profiler_db[i].lines.size(), profiler_db[i].functions.size()); + } + total_code_lines += profiler_db[i].lines.size(); + total_functions += profiler_db[i].functions.size(); + } + if (stats_flags & STATS_NUMBER_OF_LINES) { + line_func_count_str = mputprintf(line_func_count_str, + "--------------------------------------\n" + "Total:\t%lu lines,\t%lu functions\n", total_code_lines, total_functions); + } + + if (stats_flags & (STATS_TOP10_ALL_DATA | STATS_ALL_DATA_SORTED)) { + // copy code line and function info into stats_data_t containers for sorting + stats_data_t* code_line_stats = (stats_data_t*)Malloc(used_code_lines * sizeof(stats_data_t)); + stats_data_t* function_stats = (stats_data_t*)Malloc(used_functions * sizeof(stats_data_t)); + int line_index = 0; + int func_index = 0; + + for (size_t i = 0; i < profiler_db.size(); ++i) { + for (size_t j = 0; j < profiler_db[i].lines.size(); ++j) { + if (disable_coverage || 0 != profiler_db[i].lines[j].exec_count) { + code_line_stats[line_index].filename = profiler_db[i].filename; + code_line_stats[line_index].funcname = NULL; + code_line_stats[line_index].lineno = profiler_db[i].lines[j].lineno; + code_line_stats[line_index].total_time = profiler_db[i].lines[j].total_time; + code_line_stats[line_index].exec_count = profiler_db[i].lines[j].exec_count; + int func = get_function(i, profiler_db[i].lines[j].lineno); + if (-1 != func) { + code_line_stats[line_index].funcname = profiler_db[i].functions[func].name; + } + ++line_index; + } + } + for (size_t j = 0; j < profiler_db[i].functions.size(); ++j) { + if (disable_coverage || 0 != profiler_db[i].functions[j].exec_count) { + function_stats[func_index].filename = profiler_db[i].filename; + function_stats[func_index].funcname = profiler_db[i].functions[j].name; + function_stats[func_index].lineno = profiler_db[i].functions[j].lineno; + function_stats[func_index].total_time = profiler_db[i].functions[j].total_time; + function_stats[func_index].exec_count = profiler_db[i].functions[j].exec_count; + ++func_index; + } } + } - // functions specification - char* func_spec_str = mprintf("\t%s:%d [%s]\n", profiler_db[i].filename, - profiler_db[i].functions[j].lineno, profiler_db[i].functions[j].name); + if (!disable_profiler) { + // sort the code lines and functions by total time + qsort(code_line_stats, used_code_lines, sizeof(stats_data_t), &stats_data_cmp_time); + qsort(function_stats, used_functions, sizeof(stats_data_t), &stats_data_cmp_time); + + if (stats_flags & (STATS_LINE_TIMES_SORTED_TOTAL | STATS_TOP10_LINE_TIMES)) { + // cycle through the sorted code lines and gather the necessary data + for (size_t i = 0; i < used_code_lines; ++i) { + char* total_time_str = timeval2string(code_line_stats[i].total_time); + char* the_data = mprintf("%ss\t%s:%d", total_time_str, + code_line_stats[i].filename, code_line_stats[i].lineno); + Free(total_time_str); + if (NULL != code_line_stats[i].funcname) { + the_data = mputprintf(the_data, " [%s]", code_line_stats[i].funcname); + } + the_data = mputstrn(the_data, "\n", 1); + if (stats_flags & STATS_LINE_TIMES_SORTED_TOTAL) { + line_time_sorted_tot_str = mputstr(line_time_sorted_tot_str, the_data); + } + if (i < 10 && (stats_flags & STATS_TOP10_LINE_TIMES)) { + line_time_sorted_top10_str = mputprintf(line_time_sorted_top10_str, + "%2lu.\t%s", i + 1, the_data); + } + Free(the_data); + } + } + + if (stats_flags & (STATS_FUNC_TIMES_SORTED_TOTAL | STATS_TOP10_FUNC_TIMES)) { + // cycle through the sorted functions and gather the necessary data + for (size_t i = 0; i < used_functions; ++i) { + char* total_time_str = timeval2string(function_stats[i].total_time); + char* the_data = mprintf("%ss\t%s:%d [%s]\n", total_time_str, + function_stats[i].filename, function_stats[i].lineno, function_stats[i].funcname); + Free(total_time_str); + if (stats_flags & STATS_FUNC_TIMES_SORTED_TOTAL) { + func_time_sorted_tot_str = mputstr(func_time_sorted_tot_str, the_data); + } + if (i < 10 && (stats_flags & STATS_TOP10_FUNC_TIMES)) { + func_time_sorted_top10_str = mputprintf(func_time_sorted_top10_str, + "%2lu.\t%s", i + 1, the_data); + } + Free(the_data); + } + } + + if (stats_flags & (STATS_LINE_TIMES_SORTED_BY_MOD | STATS_FUNC_TIMES_SORTED_BY_MOD)) { + // cached string lengths, to avoid multiple separators after each other + size_t line_time_sorted_mod_str_len = mstrlen(line_time_sorted_mod_str); + size_t func_time_sorted_mod_str_len = mstrlen(func_time_sorted_mod_str); + + // cycle through the sorted statistics and gather the necessary data per module + for (size_t i = 0; i < profiler_db.size(); ++i) { + if (i > 0) { + if ((stats_flags & STATS_LINE_TIMES_SORTED_BY_MOD) && + line_time_sorted_mod_str_len != mstrlen(line_time_sorted_mod_str)) { + line_time_sorted_mod_str = mputstr(line_time_sorted_mod_str, + "------------------------------------------------\n"); + line_time_sorted_mod_str_len = mstrlen(line_time_sorted_mod_str); + } + if ((stats_flags & STATS_FUNC_TIMES_SORTED_BY_MOD) && + func_time_sorted_mod_str_len != mstrlen(func_time_sorted_mod_str)) { + func_time_sorted_mod_str = mputstr(func_time_sorted_mod_str, + "-----------------------------------------------\n"); + func_time_sorted_mod_str_len = mstrlen(func_time_sorted_mod_str); + } + } + if (stats_flags & STATS_LINE_TIMES_SORTED_BY_MOD) { + for (size_t j = 0; j < used_code_lines; ++j) { + if (0 == strcmp(code_line_stats[j].filename, profiler_db[i].filename)) { + char* total_time_str = timeval2string(code_line_stats[j].total_time); + line_time_sorted_mod_str = mputprintf(line_time_sorted_mod_str, + "%ss\t%s:%d", total_time_str, code_line_stats[j].filename, + code_line_stats[j].lineno); + Free(total_time_str); + if (NULL != code_line_stats[j].funcname) { + line_time_sorted_mod_str = mputprintf(line_time_sorted_mod_str, + " [%s]", code_line_stats[j].funcname); + } + line_time_sorted_mod_str = mputstrn(line_time_sorted_mod_str, "\n", 1); + } + } + } + if (stats_flags & STATS_FUNC_TIMES_SORTED_BY_MOD) { + for (size_t j = 0; j < used_functions; ++j) { + if (0 == strcmp(function_stats[j].filename, profiler_db[i].filename)) { + char* total_time_str = timeval2string(function_stats[j].total_time); + func_time_sorted_mod_str = mputprintf(func_time_sorted_mod_str, + "%ss\t%s:%d [%s]\n", total_time_str, function_stats[j].filename, + function_stats[j].lineno, function_stats[j].funcname); + Free(total_time_str); + } + } + } + } + } + } + + if (!disable_coverage) { + // sort the code lines and functions by execution count + qsort(code_line_stats, used_code_lines, sizeof(stats_data_t), &stats_data_cmp_count); + qsort(function_stats, used_functions, sizeof(stats_data_t), &stats_data_cmp_count); + + if (stats_flags & (STATS_LINE_COUNT_SORTED_TOTAL | STATS_TOP10_LINE_COUNT)) { + // cycle through the sorted code lines and gather the necessary data + for (size_t i = 0; i < used_code_lines; ++i) { + char* the_data = mprintf("%d\t%s:%d", code_line_stats[i].exec_count, + code_line_stats[i].filename, code_line_stats[i].lineno); + if (NULL != code_line_stats[i].funcname) { + the_data = mputprintf(the_data, " [%s]", code_line_stats[i].funcname); + } + the_data = mputstrn(the_data, "\n", 1); + if (stats_flags & STATS_LINE_COUNT_SORTED_TOTAL) { + line_count_sorted_tot_str = mputstr(line_count_sorted_tot_str, the_data); + } + if (i < 10 && (stats_flags & STATS_TOP10_LINE_COUNT)) { + line_count_sorted_top10_str = mputprintf(line_count_sorted_top10_str, + "%2lu.\t%s", i + 1, the_data); + } + Free(the_data); + } + } + + if (stats_flags & (STATS_FUNC_COUNT_SORTED_TOTAL | STATS_TOP10_FUNC_COUNT)) { + // cycle through the sorted functions and gather the necessary data + for (size_t i = 0; i < used_functions; ++i) { + char* the_data = mprintf("%d\t%s:%d [%s]\n", + function_stats[i].exec_count, function_stats[i].filename, + function_stats[i].lineno, function_stats[i].funcname); + if (stats_flags & STATS_FUNC_COUNT_SORTED_TOTAL) { + func_count_sorted_tot_str = mputstr(func_count_sorted_tot_str, the_data); + } + if (i < 10 && (stats_flags & STATS_TOP10_FUNC_COUNT)) { + func_count_sorted_top10_str = mputprintf(func_count_sorted_top10_str, + "%2lu.\t%s", i + 1, the_data); + } + Free(the_data); + } + } + + if (stats_flags & (STATS_LINE_COUNT_SORTED_BY_MOD | STATS_FUNC_COUNT_SORTED_BY_MOD)) { + // cached string lengths, to avoid multiple separators after each other + size_t line_count_sorted_mod_str_len = mstrlen(line_count_sorted_mod_str); + size_t func_count_sorted_mod_str_len = mstrlen(func_count_sorted_mod_str); + + // cycle through the sorted statistics and gather the necessary data per module + for (size_t i = 0; i < profiler_db.size(); ++i) { + if (i > 0) { + if ((stats_flags & STATS_LINE_COUNT_SORTED_BY_MOD) && + line_count_sorted_mod_str_len != mstrlen(line_count_sorted_mod_str)) { + line_count_sorted_mod_str = mputstr(line_count_sorted_mod_str, + "-----------------------------------------------------\n"); + line_count_sorted_mod_str_len = mstrlen(line_count_sorted_mod_str); + } + if ((stats_flags & STATS_FUNC_COUNT_SORTED_BY_MOD) && + func_count_sorted_mod_str_len != mstrlen(func_count_sorted_mod_str)) { + func_count_sorted_mod_str = mputstr(func_count_sorted_mod_str, + "----------------------------------------------------\n"); + func_count_sorted_mod_str_len = mstrlen(func_count_sorted_mod_str); + } + } + if (stats_flags & STATS_LINE_COUNT_SORTED_BY_MOD) { + for (size_t j = 0; j < used_code_lines; ++j) { + if (0 == strcmp(code_line_stats[j].filename, profiler_db[i].filename)) { + line_count_sorted_mod_str = mputprintf(line_count_sorted_mod_str, + "%d\t%s:%d", code_line_stats[j].exec_count, code_line_stats[j].filename, + code_line_stats[j].lineno); + if (NULL != code_line_stats[j].funcname) { + line_count_sorted_mod_str = mputprintf(line_count_sorted_mod_str, + " [%s]", code_line_stats[j].funcname); + } + line_count_sorted_mod_str = mputstrn(line_count_sorted_mod_str, "\n", 1); + } + } + } + if (stats_flags & STATS_FUNC_COUNT_SORTED_BY_MOD) { + for (size_t j = 0; j < used_functions; ++j) { + if (0 == strcmp(function_stats[j].filename, profiler_db[i].filename)) { + func_count_sorted_mod_str = mputprintf(func_count_sorted_mod_str, + "%d\t%s:%d [%s]\n", function_stats[j].exec_count, function_stats[j].filename, + function_stats[j].lineno, function_stats[j].funcname); + } + } + } + } + } + } + + if (!disable_profiler && !disable_coverage) { + // sort the code lines and functions by average time / execution + qsort(code_line_stats, used_code_lines, sizeof(stats_data_t), &stats_data_cmp_avg); + qsort(function_stats, used_functions, sizeof(stats_data_t), &stats_data_cmp_avg); + + if (stats_flags & (STATS_LINE_AVG_SORTED_TOTAL | STATS_TOP10_LINE_AVG)) { + // cycle through the sorted code lines and gather the necessary data + for (size_t i = 0; i < used_code_lines; ++i) { + double avg = (code_line_stats[i].total_time.tv_sec + + code_line_stats[i].total_time.tv_usec / 1000000.0) / + code_line_stats[i].exec_count; + char* total_time_str = timeval2string(code_line_stats[i].total_time); + char* the_data = mprintf("%.6lfs\t(%ss / %d)\t%s:%d", + avg, total_time_str, code_line_stats[i].exec_count, + code_line_stats[i].filename, code_line_stats[i].lineno); + Free(total_time_str); + if (NULL != code_line_stats[i].funcname) { + the_data = mputprintf(the_data, " [%s]", code_line_stats[i].funcname); + } + the_data = mputstrn(the_data, "\n", 1); + if (stats_flags & STATS_LINE_AVG_SORTED_TOTAL) { + line_avg_sorted_tot_str = mputstr(line_avg_sorted_tot_str, the_data); + } + if (i < 10 && (stats_flags & STATS_TOP10_LINE_AVG)) { + line_avg_sorted_top10_str = mputprintf(line_avg_sorted_top10_str, + "%2lu.\t%s", i + 1, the_data); + } + Free(the_data); + } + } + + if (stats_flags & (STATS_FUNC_AVG_SORTED_TOTAL | STATS_TOP10_FUNC_AVG)) { + // cycle through the sorted functions and gather the necessary data + for (size_t i = 0; i < used_functions; ++i) { + double avg = (function_stats[i].total_time.tv_sec + + function_stats[i].total_time.tv_usec / 1000000.0) / + function_stats[i].exec_count; + char* total_time_str = timeval2string(function_stats[i].total_time); + char* the_data = mprintf("%.6lfs\t(%ss / %d)\t%s:%d [%s]\n", + avg, total_time_str, function_stats[i].exec_count, + function_stats[i].filename, function_stats[i].lineno, function_stats[i].funcname); + Free(total_time_str); + if (stats_flags & STATS_FUNC_AVG_SORTED_TOTAL) { + func_avg_sorted_tot_str = mputstr(func_avg_sorted_tot_str, the_data); + } + if (i < 10 && (stats_flags & STATS_TOP10_FUNC_AVG)) { + func_avg_sorted_top10_str = mputprintf(func_avg_sorted_top10_str, + "%2lu.\t%s", i + 1, the_data); + } + Free(the_data); + } + } + + if (stats_flags & (STATS_LINE_AVG_SORTED_BY_MOD | STATS_FUNC_AVG_SORTED_BY_MOD)) { + // cached string lengths, to avoid multiple separators after each other + size_t line_avg_sorted_mod_str_len = mstrlen(line_avg_sorted_mod_str); + size_t func_avg_sorted_mod_str_len = mstrlen(func_avg_sorted_mod_str); - // add the line spec string to the other strings - func_data_str = mputstr(func_data_str, func_spec_str); - if (!disable_profiler && !disable_coverage) { - func_avg_str = mputstr(func_avg_str, func_spec_str); + // cycle through the sorted statistics and gather the necessary data per module + for (size_t i = 0; i < profiler_db.size(); ++i) { + if (i > 0) { + if ((stats_flags & STATS_LINE_AVG_SORTED_BY_MOD) && + line_avg_sorted_mod_str_len != mstrlen(line_avg_sorted_mod_str)) { + line_avg_sorted_mod_str = mputstr(line_avg_sorted_mod_str, + "--------------------------------------------------------------\n"); + line_avg_sorted_mod_str_len = mstrlen(line_avg_sorted_mod_str); + } + if ((stats_flags & STATS_FUNC_AVG_SORTED_BY_MOD) && + func_avg_sorted_mod_str_len != mstrlen(func_avg_sorted_mod_str)) { + func_avg_sorted_mod_str = mputstr(func_avg_sorted_mod_str, + "-------------------------------------------------------------\n"); + func_avg_sorted_mod_str_len = mstrlen(func_avg_sorted_mod_str); + } + } + if (stats_flags & STATS_LINE_AVG_SORTED_BY_MOD) { + for (size_t j = 0; j < used_code_lines; ++j) { + if (0 == strcmp(code_line_stats[j].filename, profiler_db[i].filename)) { + double avg = (code_line_stats[j].total_time.tv_sec + + code_line_stats[j].total_time.tv_usec / 1000000.0) / + code_line_stats[j].exec_count; + char* total_time_str = timeval2string(code_line_stats[j].total_time); + line_avg_sorted_mod_str = mputprintf(line_avg_sorted_mod_str, + "%.6lfs\t(%ss / %d)\t%s:%d", + avg, total_time_str, code_line_stats[j].exec_count, + code_line_stats[j].filename, code_line_stats[j].lineno); + Free(total_time_str); + if (NULL != code_line_stats[j].funcname) { + line_avg_sorted_mod_str = mputprintf(line_avg_sorted_mod_str, + " [%s]", code_line_stats[j].funcname); + } + line_avg_sorted_mod_str = mputstrn(line_avg_sorted_mod_str, "\n", 1); + } + } + } + if (stats_flags & STATS_FUNC_AVG_SORTED_BY_MOD) { + for (size_t j = 0; j < used_functions; ++j) { + if (0 == strcmp(function_stats[j].filename, profiler_db[i].filename)) { + double avg = (function_stats[j].total_time.tv_sec + + function_stats[j].total_time.tv_usec / 1000000.0) / + function_stats[j].exec_count; + char* total_time_str = timeval2string(function_stats[j].total_time); + func_avg_sorted_mod_str = mputprintf(func_avg_sorted_mod_str, + "%.6lfs\t(%ss / %d)\t%s:%d [%s]\n", + avg, total_time_str, function_stats[j].exec_count, + function_stats[j].filename, function_stats[j].lineno, function_stats[j].funcname); + Free(total_time_str); + } + } + } + } } } + + // free the stats data + Free(code_line_stats); + Free(function_stats); } // add new lines at the end of each segment - line_data_str = mputstrn(line_data_str, "\n", 1); - func_data_str = mputstrn(func_data_str, "\n", 1); - if (!disable_profiler && !disable_coverage) { - line_avg_str = mputstrn(line_avg_str, "\n", 1); - func_avg_str = mputstrn(func_avg_str, "\n", 1); + if (stats_flags & STATS_NUMBER_OF_LINES) { + line_func_count_str = mputstrn(line_func_count_str, "\n", 1); + } + if (stats_flags & STATS_LINE_DATA_RAW) { + line_data_str = mputstrn(line_data_str, "\n", 1); + } + if (stats_flags & STATS_FUNC_DATA_RAW) { + func_data_str = mputstrn(func_data_str, "\n", 1); + } + if (!disable_profiler) { + if (stats_flags & STATS_LINE_TIMES_SORTED_BY_MOD) { + line_time_sorted_mod_str = mputstrn(line_time_sorted_mod_str, "\n", 1); + } + if (stats_flags & STATS_LINE_TIMES_SORTED_TOTAL) { + line_time_sorted_tot_str = mputstrn(line_time_sorted_tot_str, "\n", 1); + } + if (stats_flags & STATS_FUNC_TIMES_SORTED_BY_MOD) { + func_time_sorted_mod_str = mputstrn(func_time_sorted_mod_str, "\n", 1); + } + if (stats_flags & STATS_FUNC_TIMES_SORTED_TOTAL) { + func_time_sorted_tot_str = mputstrn(func_time_sorted_tot_str, "\n", 1); + } + if (stats_flags & STATS_TOP10_LINE_TIMES) { + line_time_sorted_top10_str = mputstrn(line_time_sorted_top10_str, "\n", 1); + } + if (stats_flags & STATS_TOP10_FUNC_TIMES) { + func_time_sorted_top10_str = mputstrn(func_time_sorted_top10_str, "\n", 1); + } + if (!disable_coverage) { + if (stats_flags & STATS_LINE_AVG_RAW) { + line_avg_str = mputstrn(line_avg_str, "\n", 1); + } + if (stats_flags & STATS_LINE_AVG_RAW) { + func_avg_str = mputstrn(func_avg_str, "\n", 1); + } + if (stats_flags & STATS_LINE_AVG_SORTED_BY_MOD) { + line_avg_sorted_mod_str = mputstrn(line_avg_sorted_mod_str, "\n", 1); + } + if (stats_flags & STATS_LINE_AVG_SORTED_TOTAL) { + line_avg_sorted_tot_str = mputstrn(line_avg_sorted_tot_str, "\n", 1); + } + if (stats_flags & STATS_FUNC_AVG_SORTED_BY_MOD) { + func_avg_sorted_mod_str = mputstrn(func_avg_sorted_mod_str, "\n", 1); + } + if (stats_flags & STATS_FUNC_AVG_SORTED_TOTAL) { + func_avg_sorted_tot_str = mputstrn(func_avg_sorted_tot_str, "\n", 1); + } + if (stats_flags & STATS_TOP10_LINE_AVG) { + line_avg_sorted_top10_str = mputstrn(line_avg_sorted_top10_str, "\n", 1); + } + if (stats_flags & STATS_TOP10_FUNC_AVG) { + func_avg_sorted_top10_str = mputstrn(func_avg_sorted_top10_str, "\n", 1); + } + } + } + if (!disable_coverage) { + if (stats_flags & STATS_LINE_COUNT_SORTED_BY_MOD) { + line_count_sorted_mod_str = mputstrn(line_count_sorted_mod_str, "\n", 1); + } + if (stats_flags & STATS_LINE_COUNT_SORTED_TOTAL) { + line_count_sorted_tot_str = mputstrn(line_count_sorted_tot_str, "\n", 1); + } + if (stats_flags & STATS_FUNC_COUNT_SORTED_BY_MOD) { + func_count_sorted_mod_str = mputstrn(func_count_sorted_mod_str, "\n", 1); + } + if (stats_flags & STATS_FUNC_COUNT_SORTED_TOTAL) { + func_count_sorted_tot_str = mputstrn(func_count_sorted_tot_str, "\n", 1); + } + if (stats_flags & STATS_TOP10_LINE_COUNT) { + line_count_sorted_top10_str = mputstrn(line_count_sorted_top10_str, "\n", 1); + } + if (stats_flags & STATS_TOP10_FUNC_COUNT) { + func_count_sorted_top10_str = mputstrn(func_count_sorted_top10_str, "\n", 1); + } + if (stats_flags & STATS_UNUSED_LINES) { + unused_lines_str = mputstrn(unused_lines_str, "\n", 1); + } + if (stats_flags & STATS_UNUSED_FUNC) { + unused_func_str = mputstrn(unused_func_str, "\n", 1); + } } // write the statistics to the specified file @@ -587,29 +1482,83 @@ void TTCN3_Profiler::print_stats() "statistics will not be saved.", stats_filename); return; } - fprintf(file, "%s%s%s%s%s" - , title_str, line_data_str - , (disable_profiler || disable_coverage) ? "" : line_avg_str - , func_data_str, (disable_profiler || disable_coverage) ? "" : func_avg_str); + // by now the strings for all disabled statistics entries should be null + fprintf(file, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s" + , title_str + , (NULL != line_func_count_str) ? line_func_count_str : "" + , (NULL != line_data_str) ? line_data_str : "" + , (NULL != line_avg_str) ? line_avg_str : "" + , (NULL != func_data_str) ? func_data_str : "" + , (NULL != func_avg_str) ? func_avg_str : "" + , (NULL != line_time_sorted_mod_str) ? line_time_sorted_mod_str : "" + , (NULL != line_time_sorted_tot_str) ? line_time_sorted_tot_str : "" + , (NULL != func_time_sorted_mod_str) ? func_time_sorted_mod_str : "" + , (NULL != func_time_sorted_tot_str) ? func_time_sorted_tot_str : "" + , (NULL != line_count_sorted_mod_str) ? line_count_sorted_mod_str : "" + , (NULL != line_count_sorted_tot_str) ? line_count_sorted_tot_str : "" + , (NULL != func_count_sorted_mod_str) ? func_count_sorted_mod_str : "" + , (NULL != func_count_sorted_tot_str) ? func_count_sorted_tot_str : "" + , (NULL != line_avg_sorted_mod_str) ? line_avg_sorted_mod_str : "" + , (NULL != line_avg_sorted_tot_str) ? line_avg_sorted_tot_str : "" + , (NULL != func_avg_sorted_mod_str) ? func_avg_sorted_mod_str : "" + , (NULL != func_avg_sorted_tot_str) ? func_avg_sorted_tot_str : "" + , (NULL != line_time_sorted_top10_str) ? line_time_sorted_top10_str : "" + , (NULL != func_time_sorted_top10_str) ? func_time_sorted_top10_str : "" + , (NULL != line_count_sorted_top10_str) ? line_count_sorted_top10_str : "" + , (NULL != func_count_sorted_top10_str) ? func_count_sorted_top10_str : "" + , (NULL != line_avg_sorted_top10_str) ? line_avg_sorted_top10_str : "" + , (NULL != func_avg_sorted_top10_str) ? func_avg_sorted_top10_str : "" + , (NULL != unused_lines_str) ? unused_lines_str : "" + , (NULL != unused_func_str) ? unused_func_str : ""); + fclose(file); + + // free the strings + Free(title_str); + Free(line_func_count_str); + Free(line_data_str); + Free(line_avg_str); + Free(func_data_str); + Free(func_avg_str); + Free(line_time_sorted_mod_str); + Free(line_time_sorted_tot_str); + Free(func_time_sorted_mod_str); + Free(func_time_sorted_tot_str); + Free(line_count_sorted_mod_str); + Free(line_count_sorted_tot_str); + Free(func_count_sorted_mod_str); + Free(func_count_sorted_tot_str); + Free(line_avg_sorted_mod_str); + Free(line_avg_sorted_tot_str); + Free(func_avg_sorted_mod_str); + Free(func_avg_sorted_tot_str); + Free(line_time_sorted_top10_str); + Free(func_time_sorted_top10_str); + Free(line_count_sorted_top10_str); + Free(func_count_sorted_top10_str); + Free(line_avg_sorted_top10_str); + Free(func_avg_sorted_top10_str); + Free(unused_lines_str); + Free(unused_func_str); } void TTCN3_Profiler::reset() { - prev_time = 0.0; + prev_time.tv_sec = 0; + prev_time.tv_usec = 0; prev_file = NULL; prev_line = -1; - prev_stack_len = 0; + prev_stack_len = -1; } -double TTCN3_Profiler::get_time() +timeval TTCN3_Profiler::get_time() { timeval tv; gettimeofday(&tv, NULL); - return tv.tv_sec + tv.tv_usec / 1000000.0; + return tv; } -void TTCN3_Profiler::enter_function(const char* filename, int lineno, const char* function_name) +void TTCN3_Profiler::enter_function(const char* filename, int lineno) { if (disable_profiler && disable_coverage) { return; @@ -619,17 +1568,13 @@ void TTCN3_Profiler::enter_function(const char* filename, int lineno, const char // is measured by using the stack depth. execute_line(filename, lineno); - int element = get_element(filename); - - // store function data - int func = get_function(element, lineno); - if (-1 == func) { - create_function(element, lineno, function_name); - func = profiler_db[element].functions.size() - 1; - } - - if (!disable_coverage) { - ++profiler_db[element].functions[func].exec_count; + if (!stopped) { + int element = get_element(filename); + + // store function data + if (!disable_coverage) { + ++profiler_db[element].functions[get_function(element, lineno)].exec_count; + } } } @@ -639,35 +1584,33 @@ void TTCN3_Profiler::execute_line(const char* filename, int lineno) return; } - if (!disable_profiler) { - double currentTime = get_time(); - - // prev line should not be measured, because it is still running: we are in longer stack level - if (0.0 == prev_time || TTCN3_Stack_Depth::depth() > prev_stack_len) { - // add prev timer to call stack: - TTCN3_Stack_Depth::add_stack(prev_stack_len, prev_file, filename, prev_line, lineno); - } - else { - // if stack level is the same or higher: current line should be measured: - double elapsed = currentTime - prev_time; + if (!disable_profiler && TTCN3_Stack_Depth::depth() > prev_stack_len) { + // this line is in a different function than the last one, don't measure anything + TTCN3_Stack_Depth::add_stack(prev_stack_len, prev_file, filename, prev_line, lineno); + } + + if (!stopped) { + if (!disable_profiler && NULL != prev_file) { + // this line is in the same function as the previous one, measure the time difference + timeval elapsed = subtract_timeval(get_time(), prev_time); - // add the elapsed time to the time of the previous line: + // add the elapsed time to the total time of the previous line add_line_time(elapsed, get_element(prev_file), prev_line); TTCN3_Stack_Depth::update_stack_elapsed(elapsed); } - } - - // several instructions could be in the same line, only count the line once - if (!disable_coverage && (lineno != prev_line || NULL == prev_file || - 0 != strcmp(prev_file, filename))) { - int element = get_element(filename); - - // make sure the line exists in the database - create_lines(element, lineno); - - // increase line execution count - ++profiler_db[element].lines[lineno].exec_count; + + // functions starting at line 0 are: pre_init_module and post_init_module, + // don't include them in the database (as they don't appear in the TTCN-3 code), + // but include any actual code lines they may contain + // also, several instructions could be in the same line, only count the line once + if (0 != lineno && !disable_coverage && (lineno != prev_line || NULL == prev_file || + 0 != strcmp(prev_file, filename))) { + int element = get_element(filename); + + // increase line execution count + ++profiler_db[element].lines[get_line(element, lineno)].exec_count; + } } // store the current location as previous for the next call @@ -702,65 +1645,69 @@ void TTCN3_Profiler::create_function(int element, int lineno, const char* functi { profiler_db_item_t::profiler_function_data_t func_data; func_data.lineno = lineno; - func_data.total_time = 0.0; + func_data.total_time.tv_sec = 0; + func_data.total_time.tv_usec = 0; func_data.exec_count = 0; func_data.name = mcopystr(function_name); profiler_db[element].functions.push_back(func_data); } -void TTCN3_Profiler::create_lines(int element, int lineno) +int TTCN3_Profiler::get_line(int element, int lineno) { - // set 0 for the unknown lines - size_t line_no = lineno; - if (profiler_db[element].lines.size() <= line_no) { - for (size_t i = profiler_db[element].lines.size(); i <= line_no; ++i) { - profiler_db_item_t::profiler_line_data_t line_data; - line_data.total_time = 0.0; - line_data.exec_count = 0; - profiler_db[element].lines.push_back(line_data); + for (size_t i = 0; i < profiler_db[element].lines.size(); ++i) { + if (profiler_db[element].lines[i].lineno == lineno) { + return i; } } + return -1; +} + +void TTCN3_Profiler::create_line(int element, int lineno) +{ + profiler_db_item_t::profiler_line_data_t line_data; + line_data.lineno = lineno; + line_data.total_time.tv_sec = 0; + line_data.total_time.tv_usec = 0; + line_data.exec_count = 0; + profiler_db[element].lines.push_back(line_data); } -void TTCN3_Profiler::add_line_time(double elapsed, int element, int lineno) +void TTCN3_Profiler::add_line_time(timeval elapsed, int element, int lineno) { - if (-1 == lineno) { + if (0 == lineno) { return; } - - // ensure the line data exists - create_lines(element, lineno); - - // increase the time of the line in the current file: - profiler_db[element].lines[lineno].total_time += elapsed; + profiler_db[element].lines[get_line(element, lineno)].total_time = add_timeval( + profiler_db[element].lines[get_line(element, lineno)].total_time, elapsed); } -void TTCN3_Profiler::add_function_time(double elapsed, int element, int lineno) +void TTCN3_Profiler::add_function_time(timeval elapsed, int element, int lineno) { int func = get_function(element, lineno); if (-1 == func) { return; } - profiler_db[element].functions[func].total_time += elapsed; + profiler_db[element].functions[func].total_time = add_timeval( + profiler_db[element].functions[func].total_time, elapsed); } void TTCN3_Profiler::update_last() { - if (0.0 == prev_time) { + if (stopped || (0 == prev_time.tv_sec && 0 == prev_time.tv_usec) || NULL == prev_file) { return; } - - double currentTime = get_time(); - double elapsed = currentTime - prev_time; + + timeval elapsed = subtract_timeval(get_time(), prev_time); int element = get_element(prev_file); - // add the elapsed time to the time of the previous line: + // add the elapsed time to the total time of the previous line add_line_time(elapsed, element, prev_line); TTCN3_Stack_Depth::update_stack_elapsed(elapsed); - // reset measurement: - prev_time = 0.0; + // reset measurement + prev_time.tv_sec = 0; + prev_time.tv_usec = 0; } void TTCN3_Profiler::set_prev(int stack_len, const char* filename, int lineno) @@ -779,6 +1726,8 @@ void TTCN3_Profiler::set_prev(int stack_len, const char* filename, int lineno) int TTCN3_Stack_Depth::current_depth = -1; Vector<TTCN3_Stack_Depth::call_stack_timer_item_t> TTCN3_Stack_Depth::call_stack_timer_db; +boolean TTCN3_Stack_Depth::net_line_times = FALSE; +boolean TTCN3_Stack_Depth::net_func_times = FALSE; TTCN3_Stack_Depth::TTCN3_Stack_Depth() { @@ -801,6 +1750,16 @@ TTCN3_Stack_Depth::~TTCN3_Stack_Depth() --current_depth; } +void TTCN3_Stack_Depth::set_net_line_times(boolean p_net_line_times) +{ + net_line_times = p_net_line_times; +} + +void TTCN3_Stack_Depth::set_net_func_times(boolean p_net_func_times) +{ + net_func_times = p_net_func_times; +} + void TTCN3_Stack_Depth::add_stack(int stack_len, const char* caller_file, const char* func_file, int caller_line, int start_line) { @@ -810,19 +1769,55 @@ void TTCN3_Stack_Depth::add_stack(int stack_len, const char* caller_file, const item.func_file = func_file; item.caller_line = caller_line; item.start_line = start_line; - item.elapsed = 0.0; + item.elapsed.tv_sec = 0; + item.elapsed.tv_usec = 0; + item.first_call = true; + item.recursive_call = false; + + if (!net_line_times || !net_func_times) { + // check if it's a recursive function + for (int i = current_depth - 1; i >= 0 ; --i) { + if (call_stack_timer_db[i].start_line == start_line && + 0 == strcmp(call_stack_timer_db[i].func_file, func_file)) { + item.recursive_call = true; + + // check if the caller is new + if (call_stack_timer_db[i].caller_line == caller_line && + ((NULL == call_stack_timer_db[i].caller_file && NULL == caller_file) || + (NULL != call_stack_timer_db[i].caller_file && NULL != caller_file && + 0 == strcmp(call_stack_timer_db[i].caller_file, caller_file)))) { + item.first_call = false; + break; + } + } + } + } + call_stack_timer_db.push_back(item); } void TTCN3_Stack_Depth::remove_stack() { - // if stack level is the same or higher: measure the time: - double elapsed = call_stack_timer_db[current_depth].elapsed; - - int element = ttcn3_prof.get_element(call_stack_timer_db[current_depth].func_file); - - // add elapsed time to the total execution time of the previous line: - ttcn3_prof.add_function_time(elapsed, element, call_stack_timer_db[current_depth].start_line); + // add the time gathered for this stack level to the appropriate line and function + // except for functions starting at line 0 (pre_init_module and post_init_module) + if (0 != call_stack_timer_db[current_depth].start_line) { + timeval elapsed = call_stack_timer_db[current_depth].elapsed; + if (!net_line_times && NULL != call_stack_timer_db[current_depth].caller_file && + call_stack_timer_db[current_depth].first_call) { + // add the elapsed time to the caller line, if it exists + // (only add it once for recursive functions, at the first call) + ttcn3_prof.add_line_time(elapsed, + ttcn3_prof.get_element(call_stack_timer_db[current_depth].caller_file), + call_stack_timer_db[current_depth].caller_line); + } + if (!net_func_times && !call_stack_timer_db[current_depth].recursive_call) { + // add the elapsed time to the called function, if it's not recursive + // (in case of net function times this has already been done in update_stack_elapsed) + ttcn3_prof.add_function_time(elapsed, + ttcn3_prof.get_element(call_stack_timer_db[current_depth].func_file), + call_stack_timer_db[current_depth].start_line); + } + } ttcn3_prof.set_prev(call_stack_timer_db[current_depth].stack_len, call_stack_timer_db[current_depth].caller_file, @@ -831,9 +1826,21 @@ void TTCN3_Stack_Depth::remove_stack() call_stack_timer_db.erase_at(current_depth); } -void TTCN3_Stack_Depth::update_stack_elapsed(double elapsed) +void TTCN3_Stack_Depth::update_stack_elapsed(timeval elapsed) { - for(int i = 0; i <= current_depth; i++) { - call_stack_timer_db[i].elapsed += elapsed; + // if function times are net times, only add the elapsed time to the current function + if (net_func_times) { + ttcn3_prof.add_function_time(elapsed, + ttcn3_prof.get_element(call_stack_timer_db[current_depth].func_file), + call_stack_timer_db[current_depth].start_line); } -} \ No newline at end of file + if (!net_line_times || !net_func_times) { + // cycle through the stack and add the elapsed time to the entries where + // the function/caller pair appears for the first time (marked by 'first_call') + for(int i = 0; i <= current_depth; ++i) { + if (call_stack_timer_db[i].first_call) { + call_stack_timer_db[i].elapsed = add_timeval(call_stack_timer_db[i].elapsed, elapsed); + } + } + } +} diff --git a/core/Profiler.hh b/core/Profiler.hh index c84bb97a9..67b4081a1 100644 --- a/core/Profiler.hh +++ b/core/Profiler.hh @@ -11,6 +11,7 @@ #include "Vector.hh" #include "Types.h" +#include <sys/time.h> /** This class performs profiling and code coverage on lines and functions in * TTCN-3 code (requires the -z compiler option). @@ -22,8 +23,10 @@ public: struct profiler_db_item_t { /** Database entry for one line */ struct profiler_line_data_t { + /** Line number */ + int lineno; /** The line's total execution time */ - double total_time; + timeval total_time; /** The number of times this line was executed */ int exec_count; }; @@ -34,26 +37,78 @@ public: /** Function starting line */ int lineno; /** The function's total execution time */ - double total_time; + timeval total_time; /** The number of times this function was executed */ int exec_count; }; /** TTCN-3 File name (relative path, owned) */ char* filename; - /** Contains database entries for all the lines in this file (its index is - * the line number, so there may be empty elements) */ + /** Contains database entries for all the lines in this file */ Vector<profiler_line_data_t> lines; - /** Contains database entries for all the functions in this file (one entry - * for each function) */ + /** Contains database entries for all the functions in this file */ Vector<profiler_function_data_t> functions; }; + enum profiler_stats_flag_t { + // flags for each statistics entry + STATS_NUMBER_OF_LINES = 0x0000001, + STATS_LINE_DATA_RAW = 0x0000002, + STATS_FUNC_DATA_RAW = 0x0000004, + STATS_LINE_AVG_RAW = 0x0000008, + STATS_FUNC_AVG_RAW = 0x0000010, + STATS_LINE_TIMES_SORTED_BY_MOD = 0x0000020, + STATS_FUNC_TIMES_SORTED_BY_MOD = 0x0000040, + STATS_LINE_TIMES_SORTED_TOTAL = 0x0000080, + STATS_FUNC_TIMES_SORTED_TOTAL = 0x0000100, + STATS_LINE_COUNT_SORTED_BY_MOD = 0x0000200, + STATS_FUNC_COUNT_SORTED_BY_MOD = 0x0000400, + STATS_LINE_COUNT_SORTED_TOTAL = 0x0000800, + STATS_FUNC_COUNT_SORTED_TOTAL = 0x0001000, + STATS_LINE_AVG_SORTED_BY_MOD = 0x0002000, + STATS_FUNC_AVG_SORTED_BY_MOD = 0x0004000, + STATS_LINE_AVG_SORTED_TOTAL = 0x0008000, + STATS_FUNC_AVG_SORTED_TOTAL = 0x0010000, + STATS_TOP10_LINE_TIMES = 0x0020000, + STATS_TOP10_FUNC_TIMES = 0x0040000, + STATS_TOP10_LINE_COUNT = 0x0080000, + STATS_TOP10_FUNC_COUNT = 0x0100000, + STATS_TOP10_LINE_AVG = 0x0200000, + STATS_TOP10_FUNC_AVG = 0x0400000, + STATS_UNUSED_LINES = 0x0800000, + STATS_UNUSED_FUNC = 0x1000000, + // grouped entries + STATS_ALL_RAW_DATA = 0x000001E, + STATS_LINE_DATA_SORTED_BY_MOD = 0x0002220, + STATS_FUNC_DATA_SORTED_BY_MOD = 0x0004440, + STATS_LINE_DATA_SORTED_TOTAL = 0x0008880, + STATS_FUNC_DATA_SORTED_TOTAL = 0x0011100, + STATS_LINE_DATA_SORTED = 0x000AAA0, + STATS_FUNC_DATA_SORTED = 0x0015540, + STATS_ALL_DATA_SORTED = 0x001FFE0, + STATS_TOP10_LINE_DATA = 0x02A0000, + STATS_TOP10_FUNC_DATA = 0x0540000, + STATS_TOP10_ALL_DATA = 0x07E0000, + STATS_UNUSED_DATA = 0x1800000, + STATS_ALL = 0x1FFFFFF + }; + /** Constructor */ TTCN3_Profiler(); - /** Destructor - adds all gathered data to the database file and prints - * statistics if necessary */ + /** Destructor + * In single mode and in the Host Controller's process in parallel mode: + * - imports data gathered on the previous run (if data aggregation is set) + * - imports data gathered by all other processes (only in parallel mode) + * - prints statistics (if necessary) + * Afterwards, in all cases: + * - exports data gathered in this process (including any imported data) + * - frees allocated memory */ ~TTCN3_Profiler(); + /** Reactivates the profiler if it was stopped before, data gathering will resume */ + void start(); + /** Deactivates the profiler, no more data will be gathered until it is reactivated */ + void stop(); + /** Enables or disables profiling - called by the config file parser */ void set_disable_profiler(boolean p_disable_profiler); /** Enables or disables code coverage - called by the config file parser */ @@ -66,14 +121,21 @@ public: void set_stats_filename(const char* p_stats_filename); /** Enables or disables the printing of statistics - called by the config file parser */ void set_disable_stats(boolean p_disable_stats); + /** Disables all statistics entry flags - called by the config file parser */ + void reset_stats_flags(); + /** Enables the specified statistics entry flags - called by the config file parser */ + void add_stats_flags(unsigned int p_flags); /** Returns true if profiling is disabled */ boolean is_profiler_disabled() const; + /** Returns true if the profiler is currently running (not stopped) */ + boolean is_running() const; - /** Deletes the database file if data aggregation is not set */ - void init_data_file(); + /** Stores the component reference of a newly created PTC (in parallel mode only) */ + void add_ptc(component p_comp_ref); + /** Adds the data from the database file to the local database */ - void import_data(); + void import_data(component p_comp_ref = NULL_COMPREF); /** Writes the local database to the database file (overwrites the file) */ void export_data(); @@ -83,9 +145,9 @@ public: /** Resets data related to the previous location and time (the local database is not changed) */ void reset(); /** Returns the current time (in seconds) */ - static double get_time(); + static timeval get_time(); /** Called when a TTCN-3 function starts execution - stores data */ - void enter_function(const char* filename, int lineno, const char* function_name); + void enter_function(const char* filename, int lineno); /** Called when a TTCN-3 code line starts execution - stores data */ void execute_line(const char* filename, int lineno); /** Returns the index of a TTCN-3 file's entry in the local database */ @@ -99,18 +161,22 @@ public: * @param lineno function start line * @param function_name name of the function */ void create_function(int element, int lineno, const char* function_name); - /** Creates TTCN-3 code line entries up to the given line number */ - void create_lines(int element, int lineno); + /** Returns the index of a TTCN-3 code line's entry in the database */ + int get_line(int element, int lineno); + /** Creates a new TTCN-3 code line entry and inserts it into the database */ + void create_line(int element, int lineno); /** Adds elapsed time to the specified TTCN-3 code line's total time */ - void add_line_time(double elapsed, int element, int lineno); + void add_line_time(timeval elapsed, int element, int lineno); /** Adds elapsed time to the specified TTCN-3 function's total time*/ - void add_function_time(double elapsed, int element, int lineno); + void add_function_time(timeval elapsed, int element, int lineno); /** Called when a TTCN-3 function's execution ends - stores data */ void update_last(); /** Stores data related to the previous location */ void set_prev(int stack_len, const char* filename, int lineno); private: + /** If true, the profiler ignores execute_line, enter_function and update_last calls */ + boolean stopped; /** Profiling is disabled if true */ boolean disable_profiler; /** Code coverage is disabled if true */ @@ -124,9 +190,10 @@ private: char* stats_filename; /** Statistics will not be calculated and printed if true */ boolean disable_stats; - + /** Flags that determine which statistics entries are displayed */ + unsigned int stats_flags; /** The time measured at the previous TTCN-3 code line */ - double prev_time; + timeval prev_time; /** Name of the TTCN-3 file, where the last executed line is (not owned) */ const char* prev_file; /** The number of the previously executed line */ @@ -135,6 +202,9 @@ private: Vector<profiler_db_item_t> profiler_db; /** The stack length at the previously executed line */ int prev_stack_len; + /** Contains the component references of all PTCs (only relevant in the Host + * Controller's process, in parallel mode) */ + Vector<component> ptc_list; }; /** The global TTCN3_Profiler object @@ -151,21 +221,27 @@ extern TTCN3_Profiler ttcn3_prof; * Its instances depict the current call stack. One instance is created at the start * of each TTCN-3 function execution, and it's destroyed at the function's end. */ class TTCN3_Stack_Depth { -public: +public: /** Entry for one function call in the call stack */ struct call_stack_timer_item_t { /** Stack length before the function call */ int stack_len; /** File name, where the calling function is declared (not owned) */ const char* caller_file; - /** File name, where the called function is declared (not owned)*/ + /** File name, where the called function is declared (not owned) */ const char* func_file; /** Calling function's start line */ int caller_line; /** Called function's start line */ int start_line; /** Time elapsed in this function call */ - double elapsed; + timeval elapsed; + /** If true, then this is the first entry of this function and caller pair + * (only used in case of gross line times) */ + boolean first_call; + /** If true, then this function has appeared before in the call stack + * (only used in case of gross function times)*/ + boolean recursive_call; }; /** Constructor - increases the stack depth */ @@ -173,6 +249,11 @@ public: /** Destructor - decreases the stack depth, updates call times in the profiler */ ~TTCN3_Stack_Depth(); + /** Sets whether line times should include function call times - called by the config file parser */ + static void set_net_line_times(boolean p_net_line_times); + /** Sets whether function times should include embedded function times - called by the config file parser */ + static void set_net_func_times(boolean p_net_func_times); + /** Returns the current stack depth */ static int depth() { return current_depth; } /** Inserts a new function call entry into the call stack database */ @@ -181,12 +262,18 @@ public: /** Removes the last entry from the call stack database */ static void remove_stack(); /** Adds the elapsed time to all entries in the call stack database */ - static void update_stack_elapsed(double elapsed); + static void update_stack_elapsed(timeval elapsed); private: /** The current stack depth (starts from 0)*/ static int current_depth; /** The call stack database */ static Vector<call_stack_timer_item_t> call_stack_timer_db; + /** If true, line times will not include the execution times of functions called + * in that line */ + static boolean net_line_times; + /** If true, function times will not include the execution times of functions + * called in that function */ + static boolean net_func_times; }; #endif /* PROFILER_HH */ diff --git a/core/RAW.cc b/core/RAW.cc index b31638671..72947e8b8 100644 --- a/core/RAW.cc +++ b/core/RAW.cc @@ -340,7 +340,7 @@ int RAW_encode_enum_type(const TTCN_Typedescriptor_t& p_td, my_raw.ptroffset = p_td.raw->ptroffset; my_raw.unit = p_td.raw->unit; TTCN_Typedescriptor_t my_descr = { p_td.name, 0, &my_raw, NULL, NULL, NULL, - TTCN_Typedescriptor_t::DONTCARE }; + NULL, TTCN_Typedescriptor_t::DONTCARE }; INTEGER i(integer_value); i.RAW_encode(my_descr, myleaf); // myleaf.align=0;//p_td.raw->endianness==ORDER_MSB?min_bits_enum-fl:fl-min_bits_enum; @@ -369,7 +369,7 @@ int RAW_decode_enum_type(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& buff, my_raw.ptroffset = p_td.raw->ptroffset; my_raw.unit = p_td.raw->unit; TTCN_Typedescriptor_t my_descr = { p_td.name, 0, &my_raw, NULL, NULL, NULL, - TTCN_Typedescriptor_t::DONTCARE }; + NULL, TTCN_Typedescriptor_t::DONTCARE }; INTEGER i; /* if(p_td.raw->endianness==ORDER_MSB) buff.increase_pos_bit(fl-min_bits_enum);*/ diff --git a/core/RefdIndex.hh b/core/RefdIndex.hh new file mode 100644 index 000000000..2b2f4a6e8 --- /dev/null +++ b/core/RefdIndex.hh @@ -0,0 +1,55 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2000-2015 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 +/////////////////////////////////////////////////////////////////////////////// + +#ifndef REFDINDEX_HH +#define REFDINDEX_HH + +#ifdef TITAN_RUNTIME_2 + +/** This class contains the functions needed for adding and removing referenced + * indexes to record of/set of types and the optional type (only in RT2). + * By default the functions are empty.*/ +class RefdIndexInterface +{ +public: + virtual ~RefdIndexInterface() {} + virtual void add_refd_index(int) {} + virtual void remove_refd_index(int) {} +}; + +/** References to record of/set of elements through 'out' and 'inout' function + * parameters are handled by this class. + * Usage: create instances of this class before the function call (one instance + * for each referenced index), and place the instances and the function call in + * a block (so the destructor is called immediately after the function call). + * This way the referenced indexes are cleaned up even if the function call ends + * with an exception (DTE) */ +class RefdIndexHandler +{ +public: + RefdIndexHandler(RefdIndexInterface* p_container, int p_index) + { + container = p_container; + index = p_index; + container->add_refd_index(index); + } + + ~RefdIndexHandler() + { + container->remove_refd_index(index); + } + +private: + RefdIndexInterface* container; + int index; +}; + +#endif /* TITAN_RUNTIME_2 */ + +#endif /* REFDINDEX_HH */ + diff --git a/core/Runtime.cc b/core/Runtime.cc index 24a8a9cc4..25e07bb9d 100644 --- a/core/Runtime.cc +++ b/core/Runtime.cc @@ -41,6 +41,7 @@ #include "Charstring.hh" #include "Fd_And_Timeout_User.hh" #include <TitanLoggerApi.hh> +#include "Profiler.hh" namespace API = TitanLoggerApi; @@ -403,6 +404,7 @@ int TTCN_Runtime::hc_main(const char *local_addr, const char *MC_addr, TTCN_Communication::set_local_address(local_addr); TTCN_Communication::set_mc_address(MC_addr, MC_port); TTCN_Communication::connect_mc(); + Module_List::send_versions(); executor_state = HC_IDLE; TTCN_Communication::send_version(); initialize_component_process_tables(); @@ -2303,6 +2305,9 @@ void TTCN_Runtime::process_create_ptc(component component_reference, "state."); return; } + + // let the HC's TTCN-3 Profiler know of this new PTC + ttcn3_prof.add_ptc(component_reference); // clean Emergency log buffer before fork, to avoid duplication TTCN_Logger::ring_buffer_dump(false); diff --git a/core/Single_main.cc b/core/Single_main.cc index e4d7375a5..0c2430675 100644 --- a/core/Single_main.cc +++ b/core/Single_main.cc @@ -22,6 +22,9 @@ #include "Encdec.hh" #include "TitanLoggerApi.hh" #include "TCov.hh" +#ifdef LINUX +#include <execinfo.h> +#endif #ifdef LICENSE #include "../common/license.h" @@ -32,15 +35,29 @@ const char * stored_argv = "Unidentified program"; static const char segfault[] = ": Segmentation fault occurred\n"; +static const char abortcall[] = ": Abort was called\n"; -void signal_handler(int) +void signal_handler(int signum) { int retval; retval = write(STDERR_FILENO, stored_argv, strlen(stored_argv)); + if(signum==SIGSEGV){ retval = write(STDERR_FILENO, segfault , sizeof(segfault)-1); // sizeof includes \0 + } else { + retval = write(STDERR_FILENO, abortcall , sizeof(abortcall)-1); // sizeof includes \0 + } +#ifdef LINUX + int nptrs; + void *buffer[100]; + nptrs = backtrace(buffer, 100); + backtrace_symbols_fd(buffer, nptrs, STDERR_FILENO); + + fflush(stderr); +#endif (void)retval; TTCN_Logger::close_file(); + signal(SIGABRT, SIG_DFL); abort(); } @@ -65,6 +82,7 @@ int main(int argc, char *argv[]) sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGSEGV, &act, 0); + sigaction(SIGABRT, &act, 0); #ifdef MEMORY_DEBUG debug_new_counter.set_program_name(argv[0]); diff --git a/core/Snapshot.cc b/core/Snapshot.cc index 4877d9533..42e32a7d6 100644 --- a/core/Snapshot.cc +++ b/core/Snapshot.cc @@ -14,6 +14,7 @@ #include <fcntl.h> #include <errno.h> +#include <sys/select.h> #include <sys/types.h> #include <poll.h> #ifdef USE_EPOLL diff --git a/core/TEXT.cc b/core/TEXT.cc index 91ddd7204..d0b57c4a4 100644 --- a/core/TEXT.cc +++ b/core/TEXT.cc @@ -268,6 +268,9 @@ const TTCN_TEXTdescriptor_t BOOLEAN_text_ = { NULL, NULL, NULL, NULL, const TTCN_TEXTdescriptor_t CHARSTRING_text_ = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, { NULL } }; +const TTCN_TEXTdescriptor_t UNIVERSAL_CHARSTRING_text_ = { NULL, NULL, NULL, NULL, + NULL, NULL, NULL, { NULL } }; + const TTCN_TEXTdescriptor_t BITSTRING_text_ = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, { NULL } }; diff --git a/core/TEXT.hh b/core/TEXT.hh index 4d3962d92..7a2483310 100644 --- a/core/TEXT.hh +++ b/core/TEXT.hh @@ -121,6 +121,7 @@ extern const TTCN_TEXTdescriptor_t CHARSTRING_text_; extern const TTCN_TEXTdescriptor_t BITSTRING_text_; extern const TTCN_TEXTdescriptor_t HEXSTRING_text_; extern const TTCN_TEXTdescriptor_t OCTETSTRING_text_; +extern const TTCN_TEXTdescriptor_t UNIVERSAL_CHARSTRING_text_; /** @} end of TEXT group */ diff --git a/core/TTCN3.hh b/core/TTCN3.hh index 405a340e6..6fb4305eb 100644 --- a/core/TTCN3.hh +++ b/core/TTCN3.hh @@ -53,8 +53,10 @@ #ifdef TITAN_RUNTIME_2 #include "RT2/TitanLoggerApiSimple.hh" +#include "RT2/PreGenRecordOf.hh" #else #include "RT1/TitanLoggerApiSimple.hh" +#include "RT1/PreGenRecordOf.hh" #endif #include "Module_list.hh" @@ -70,5 +72,6 @@ #include "JSON.hh" #include "Error.hh" #include "XmlReader.hh" +#include "Profiler.hh" #endif diff --git a/core/Template.hh b/core/Template.hh index 44ccdc483..9b3a0d192 100644 --- a/core/Template.hh +++ b/core/Template.hh @@ -12,6 +12,7 @@ #ifdef TITAN_RUNTIME_2 #include "Struct_of.hh" +#include "RefdIndex.hh" struct TTCN_Typedescriptor_t; struct Erroneous_descriptor_t; #endif @@ -113,7 +114,11 @@ public: #endif }; -class Restricted_Length_Template : public Base_Template { +class Restricted_Length_Template : public Base_Template +#ifdef TITAN_RUNTIME_2 + , public RefdIndexInterface +#endif +{ protected: enum length_restriction_type_t { NO_LENGTH_RESTRICTION = 0, @@ -160,12 +165,6 @@ public: boolean is_omit() const; boolean is_any_or_omit() const; - -#ifdef TITAN_RUNTIME_2 - // Dummy functions, only used in record of/set of value in RT2 - void add_refd_index(int) {} - void remove_refd_index(int) {} -#endif }; #ifndef TITAN_RUNTIME_2 diff --git a/core/Universal_charstring.cc b/core/Universal_charstring.cc index 330f4f27b..9b7f53444 100644 --- a/core/Universal_charstring.cc +++ b/core/Universal_charstring.cc @@ -19,6 +19,7 @@ #include "Logger.hh" #include "Encdec.hh" #include "Addfunc.hh" // for unichar2int +#include "TEXT.hh" #include <string> #include <iostream> #include <stdint.h> @@ -200,7 +201,7 @@ UNIVERSAL_CHARSTRING::UNIVERSAL_CHARSTRING other_value.must_bound("Initialization of a universal charstring with an " "unbound universal charstring element."); if (charstring) { - cstr = CHARSTRING(other_value.get_uchar().uc_cell); + cstr = CHARSTRING((const char)(other_value.get_uchar().uc_cell)); val_ptr = NULL; } else { init_struct(1); @@ -1068,6 +1069,13 @@ void UNIVERSAL_CHARSTRING::encode(const TTCN_Typedescriptor_t& p_td, TTCN_EncDec_ErrorContext::error_internal ("No RAW descriptor available for type '%s'.", p_td.name); break;} + case TTCN_EncDec::CT_TEXT: { + TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name); + if(!p_td.text) + TTCN_EncDec_ErrorContext::error_internal + ("No TEXT descriptor available for type '%s'.", p_td.name); + TEXT_encode(p_td,p_buf); + break;} case TTCN_EncDec::CT_XER: { TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name); unsigned XER_coding=va_arg(pvar, unsigned); @@ -1117,6 +1125,24 @@ void UNIVERSAL_CHARSTRING::decode(const TTCN_Typedescriptor_t& p_td, TTCN_EncDec_ErrorContext::error_internal ("No RAW descriptor available for type '%s'.", p_td.name); break;} + case TTCN_EncDec::CT_TEXT: { + Limit_Token_List limit; + TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name); + if(!p_td.text) + TTCN_EncDec_ErrorContext::error_internal + ("No TEXT descriptor available for type '%s'.", p_td.name); + const unsigned char *b=p_buf.get_data(); + if(b[p_buf.get_len()-1]!='\0'){ + p_buf.set_pos(p_buf.get_len()); + p_buf.put_zero(8,ORDER_LSB); + p_buf.rewind(); + } + if(TEXT_decode(p_td,p_buf,limit)<0) + ec.error(TTCN_EncDec::ET_INCOMPL_MSG, + "Can not decode type '%s', because invalid or incomplete" + " message was received" + , p_td.name); + break;} case TTCN_EncDec::CT_XER : { unsigned XER_coding=va_arg(pvar, unsigned); XmlReaderWrap reader(p_buf); @@ -1200,6 +1226,198 @@ UNIVERSAL_CHARSTRING::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding); return new_tlv; } +int UNIVERSAL_CHARSTRING::TEXT_decode(const TTCN_Typedescriptor_t& p_td, + TTCN_Buffer& buff, Limit_Token_List& limit, boolean no_err, boolean /*first_call*/) +{ + int decoded_length = 0; + int str_len = 0; + clean_up(); + if (p_td.text->begin_decode) { + int tl; + if ((tl = p_td.text->begin_decode->match_begin(buff)) < 0) { + if (no_err) return -1; + TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR, + "The specified token '%s' not found for '%s': ", + (const char*) *(p_td.text->begin_decode), p_td.name); + return 0; + } + decoded_length += tl; + buff.increase_pos(tl); + } + // never return "not enough bits" + // if(buff.get_read_len()<=1 && no_err) return -TTCN_EncDec::ET_LEN_ERR; + + if (p_td.text->select_token) { + int tl; + if ((tl = p_td.text->select_token->match_begin(buff)) < 0) { + if (no_err) return -1; + else tl = 0; + } + str_len = tl; + } + // The length restriction needs some more work +/* else if ( p_td.text->val.parameters + && p_td.text->val.parameters->decoding_params.min_length != -1) { + str_len = p_td.text->val.parameters->decoding_params.min_length; + }*/ + else if (p_td.text->end_decode) { + int tl; + if ((tl = p_td.text->end_decode->match_first(buff)) < 0) { + if (no_err) return -1; + else tl = 0; + } + str_len = tl; + } + else if (limit.has_token()) { + int tl; + if ((tl = limit.match(buff)) < 0) tl = buff.get_read_len() - 1; + str_len = tl; + } + else { + str_len = buff.get_read_len() - 1; + } + +// only utf8 is supported now. + decode_utf8(str_len,buff.get_read_data()); + + decoded_length += str_len; + buff.increase_pos(str_len); + +// Case conversion is an another study +// and it is locale dependent +/* if ( p_td.text->val.parameters + && p_td.text->val.parameters->decoding_params.convert != 0) { + if (p_td.text->val.parameters->decoding_params.convert == 1) { + for (int a = 0; a < str_len; a++) { + val_ptr->chars_ptr[a] = toupper(val_ptr->chars_ptr[a]); + } + } + else { + for (int a = 0; a < str_len; a++) { + val_ptr->chars_ptr[a] = tolower(val_ptr->chars_ptr[a]); + } + } + }*/ + if (p_td.text->end_decode) { + int tl; + if ((tl = p_td.text->end_decode->match_begin(buff)) < 0) { + if (no_err) return -1; + TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR, + "The specified token '%s' not found for '%s': ", + (const char*) *(p_td.text->end_decode), p_td.name); + return 0; + } + decoded_length += tl; + buff.increase_pos(tl); + } + return decoded_length; +} + +int UNIVERSAL_CHARSTRING::TEXT_encode(const TTCN_Typedescriptor_t& p_td, + TTCN_Buffer& buff) const{ + int encoded_length=0; + if(p_td.text->begin_encode){ + buff.put_cs(*p_td.text->begin_encode); + encoded_length+=p_td.text->begin_encode->lengthof(); + } + if(!is_bound()) { + TTCN_EncDec_ErrorContext::error + (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value."); + if(p_td.text->end_encode){ + buff.put_cs(*p_td.text->end_encode); + encoded_length+=p_td.text->end_encode->lengthof(); + } + return encoded_length; + } + +// The length restriction and case conversion will be added later +// if(p_td.text->val.parameters==NULL){ + + int base_size=buff.get_len(); // strore the current length of the data + // in the buffer + + encode_utf8(buff); + + encoded_length+=buff.get_len()-base_size; // calculate the number of the + // stored octets + +/* } else { + int chars_before=0; + int chars_after=0; + if(val_ptr->n_chars<p_td.text->val.parameters->coding_params.min_length){ + switch(p_td.text->val.parameters->coding_params.just){ + case -1: //left + chars_after=p_td.text-> + val.parameters->coding_params.min_length-val_ptr->n_chars; + break; + case 0:{ // center + int pad=p_td.text-> + val.parameters->coding_params.min_length-val_ptr->n_chars; + chars_after=pad/2; + chars_before=pad-chars_after; + break; + } + case 1: // right + default: + chars_before=p_td.text-> + val.parameters->coding_params.min_length-val_ptr->n_chars; + break; + } + } + if(chars_before){ + unsigned char* p=NULL; + size_t len=chars_before; + buff.get_end(p,len); + for(int a=0;a<chars_before;a++) p[a]=(unsigned char)' '; + buff.increase_length(chars_before); + encoded_length+=chars_before; + } + + switch(p_td.text->val.parameters->coding_params.convert){ + case -1:{ //lower_case + unsigned char* p=NULL; + size_t len=val_ptr->n_chars; + buff.get_end(p,len); + for(int a=0;a<val_ptr->n_chars;a++) + p[a]=(unsigned char)tolower(val_ptr->chars_ptr[a]); + buff.increase_length(val_ptr->n_chars); + break; + } + case 0:{ // no conversion + buff.put_cs(*this); + break; + } + case 1: // upper_case + default: + { + unsigned char* p=NULL; + size_t len=val_ptr->n_chars; + buff.get_end(p,len); + for(int a=0;a<val_ptr->n_chars;a++) + p[a]=(unsigned char)toupper(val_ptr->chars_ptr[a]); + buff.increase_length(val_ptr->n_chars); + break; + } + } + encoded_length+=val_ptr->n_chars; + + if(chars_after){ + unsigned char* p=NULL; + size_t len=chars_after; + buff.get_end(p,len); + for(int a=0;a<chars_after;a++) p[a]=(unsigned char)' '; + buff.increase_length(chars_after); + encoded_length+=chars_after; + } + } +*/ + + if(p_td.text->end_encode){ + buff.put_cs(*p_td.text->end_encode); + encoded_length+=p_td.text->end_encode->lengthof(); + } + return encoded_length; +} void UNIVERSAL_CHARSTRING::encode_utf8(TTCN_Buffer& buf, bool addBOM /*= false*/) const { @@ -2214,7 +2432,9 @@ void UNIVERSAL_CHARSTRING::decode_utf8(int n_octets, // count all octets except the continuing octets (10xxxxxx) if ((octets_ptr[i] & 0xC0) != 0x80) n_uchars++; } - // allocate enough memory + // allocate enough memory, start from clean state + clean_up(); + charstring=false; init_struct(n_uchars); n_uchars = 0; @@ -2676,22 +2896,13 @@ UNIVERSAL_CHARSTRING_ELEMENT& UNIVERSAL_CHARSTRING_ELEMENT::operator= { other_value.must_bound("Assignment of an unbound universal charstring value " "to a universal charstring element."); - if (other_value.val_ptr->n_uchars != 1) + int other_value_size = other_value.charstring ? other_value.cstr.val_ptr->n_chars : + other_value.val_ptr->n_uchars; + if (other_value_size != 1) TTCN_error("Assignment of a universal charstring value with length other " "than 1 to a universal charstring element."); bound_flag = TRUE; - const universal_char& uchar = other_value.val_ptr->uchars_ptr[0]; - if (str_val.charstring) { - if (uchar.is_char()) - str_val.cstr.val_ptr->chars_ptr[uchar_pos] = uchar.uc_cell; - else { - str_val.convert_cstr_to_uni(); - str_val.val_ptr->uchars_ptr[uchar_pos] = uchar; - } - } else { - str_val.copy_value(); - str_val.val_ptr->uchars_ptr[uchar_pos] = uchar; - } + *this = other_value[0]; return *this; } diff --git a/core/Universal_charstring.hh b/core/Universal_charstring.hh index 62ea9fbf9..5d2e66a61 100644 --- a/core/Universal_charstring.hh +++ b/core/Universal_charstring.hh @@ -318,6 +318,10 @@ public: boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, unsigned L_form); + int TEXT_encode(const TTCN_Typedescriptor_t&, + TTCN_Buffer&) const; + int TEXT_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, Limit_Token_List&, + boolean no_err=FALSE, boolean first_call=TRUE); int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const; int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*); /** Decodes UTF-8 into the internal representation (UCS4-BE) diff --git a/core/XER.hh b/core/XER.hh index 604ca048f..78262afc4 100644 --- a/core/XER.hh +++ b/core/XER.hh @@ -19,6 +19,11 @@ class Base_Type; #ifdef TITAN_RUNTIME_2 class Record_Of_Type; class Erroneous_descriptor_t; +#else +namespace PreGenRecordOf { + class PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING; + class PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING__OPTIMIZED; +} #endif class TTCN_Module; @@ -255,6 +260,9 @@ struct XERdescriptor_t * or invalid ("anyElement except ...") namespace URIs. * The unqualified namespace is marked by an empty string ("").*/ const char** ns_uris; + + /** Points to the element type's XER descriptor in case of 'record of' and 'set of' types */ + const XERdescriptor_t* oftype_descr; }; /** Information related to the embedded values in XML encoding @@ -273,11 +281,10 @@ struct embed_values_enc_struct_t /** Erroneous descriptor index for the embedded values (for negative tests) */ int embval_err_descr_idx; #else - /** Stores the array of embedded values as a Base_Type (use get_embedded_value - * to retrieve values - temporarily disabled) */ - const Base_Type* embval_array; - /** Stores the size of the embedded value array */ - int embval_size; + /** Stores the array of embedded values (regular record-of) */ + const PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING* embval_array_reg; + /** Stores the array of embedded values (optimized record-of) */ + const PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING__OPTIMIZED* embval_array_opt; #endif /** Stores the index of the next embedded value to be read */ int embval_index; @@ -293,9 +300,10 @@ struct embed_values_dec_struct_t /** Stores the array of embedded values */ Record_Of_Type* embval_array; #else - /** Stores the array of embedded values as a Base_type (use set_embedded_value - * to insert new values - temporarily disabled) */ - Base_Type* embval_array; + /** Stores the array of embedded values (regular record-of) */ + PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING* embval_array_reg; + /** Stores the array of embedded values (optimized record-of) */ + PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING__OPTIMIZED* embval_array_opt; #endif /** Stores the number of embedded values that are currently in the array, * and the index where the next one should be inserted */ @@ -414,7 +422,7 @@ void check_namespace_restrictions(const XERdescriptor_t& p_td, const char* p_xml extern const XERdescriptor_t type_name##_xer_ = { \ { xmlname ">\n", xmlname ">\n" }, \ { 2+sizeof(xmlname)-1, 2+sizeof(xmlname)-1 }, \ - 0UL, WHITESPACE_PRESERVE, NULL, NULL, 0, 0, NULL } + 0UL, WHITESPACE_PRESERVE, NULL, NULL, 0, 0, NULL, NULL } // The compiler should fold the two identical strings into one # define XER_STRUCT_COPY(cpy,original) \ diff --git a/core/config_process.l b/core/config_process.l index 4d96260b1..dafbf2d1d 100644 --- a/core/config_process.l +++ b/core/config_process.l @@ -35,6 +35,8 @@ #include "../common/dbgnew.hh" +#include "Profiler.hh" + extern string_map_t *config_defines; #define yylval config_process_lval @@ -276,6 +278,25 @@ TTCNSTRINGPARSING_COMPONENT "$#&&&(#TTCNSTRINGPARSING_COMPONENT$#&&^#% " . /* eat unnecessary chars */ +} + +<SC_PROFILER>{HEX}+ { + /* numeric statistics filter (check this before checking for NUMBERs) */ + yylval.uint_val = 0; + while(0 != *yytext) { + yylval.uint_val *= 16; + if ('0' <= *yytext && '9' >= *yytext) { + yylval.uint_val += *yytext - '0'; + } + else if ('a' <= *yytext && 'f' >= *yytext) { + yylval.uint_val += *yytext - 'a' + 10; + } + else { + yylval.uint_val += *yytext - 'A' + 10; + } + ++yytext; + } + return ProfilerStatsFlag; } /* Values */ @@ -966,12 +987,170 @@ LOG_ALL { <SC_PROFILER> { - [Dd]isable[Pp]rofiler return DisableProfilerKeyword; - [Dd]isable[Cc]overage return DisableCoverageKeyword; - [Dd]ata[Bb]ase[Ff]ile return DatabaseFileKeyword; - [Aa]ggregate[Dd]ata return AggregateDataKeyword; - [Ss]tatistics[Ff]ile return StatisticsFileKeyword; - [Dd]isable[Ss]tatistics return DisableStatisticsKeyword; + [Dd]isable[Pp]rofiler return DisableProfilerKeyword; + [Dd]isable[Cc]overage return DisableCoverageKeyword; + [Dd]ata[Bb]ase[Ff]ile return DatabaseFileKeyword; + [Aa]ggregate[Dd]ata return AggregateDataKeyword; + [Ss]tatistics[Ff]ile return StatisticsFileKeyword; + [Dd]isable[Ss]tatistics return DisableStatisticsKeyword; + [Ss]tatistics[Ff]ilter return StatisticsFilterKeyword; + [Ss]tart[Aa]utomatically return StartAutomaticallyKeyword; + [Nn]et[Ll]ine[Tt]imes return NetLineTimesKeyword; + [Nn]et[Ff]unction[Tt]imes return NetFunctionTimesKeyword; + + /* statistics filters */ + [Nn]umber[Oo]f[Ll]ines { + yylval.uint_val = TTCN3_Profiler::STATS_NUMBER_OF_LINES; + return ProfilerStatsFlag; + } + [Ll]ine[Dd]ata[Rr]aw { + yylval.uint_val = TTCN3_Profiler::STATS_LINE_DATA_RAW; + return ProfilerStatsFlag; + } + [Ff]unc[Dd]ata[Rr]aw { + yylval.uint_val = TTCN3_Profiler::STATS_FUNC_DATA_RAW; + return ProfilerStatsFlag; + } + [Ll]ine[Aa]vg[Rr]aw { + yylval.uint_val = TTCN3_Profiler::STATS_LINE_AVG_RAW; + return ProfilerStatsFlag; + } + [Ff]unc[Aa]vg[Rr]aw { + yylval.uint_val = TTCN3_Profiler::STATS_FUNC_AVG_RAW; + return ProfilerStatsFlag; + } + [Ll]ine[Tt]imes[Ss]orted[Bb]y[Mm]od { + yylval.uint_val = TTCN3_Profiler::STATS_LINE_TIMES_SORTED_BY_MOD; + return ProfilerStatsFlag; + } + [Ff]unc[Tt]imes[Ss]orted[Bb]y[Mm]od { + yylval.uint_val = TTCN3_Profiler::STATS_FUNC_TIMES_SORTED_BY_MOD; + return ProfilerStatsFlag; + } + [Ll]ine[Tt]imes[Ss]orted[Tt]otal { + yylval.uint_val = TTCN3_Profiler::STATS_LINE_TIMES_SORTED_TOTAL; + return ProfilerStatsFlag; + } + [Ff]unc[Tt]imes[Ss]orted[Tt]otal { + yylval.uint_val = TTCN3_Profiler::STATS_FUNC_TIMES_SORTED_TOTAL; + return ProfilerStatsFlag; + } + [Ll]ine[Cc]ount[Ss]orted[Bb]y[Mm]od { + yylval.uint_val = TTCN3_Profiler::STATS_LINE_COUNT_SORTED_BY_MOD; + return ProfilerStatsFlag; + } + [Ff]unc[Cc]ount[Ss]orted[Bb]y[Mm]od { + yylval.uint_val = TTCN3_Profiler::STATS_FUNC_COUNT_SORTED_BY_MOD; + return ProfilerStatsFlag; + } + [Ll]ine[Cc]ount[Ss]orted[Tt]otal { + yylval.uint_val = TTCN3_Profiler::STATS_LINE_COUNT_SORTED_TOTAL; + return ProfilerStatsFlag; + } + [Ff]unc[Cc]ount[Ss]orted[Tt]otal { + yylval.uint_val = TTCN3_Profiler::STATS_FUNC_COUNT_SORTED_TOTAL; + return ProfilerStatsFlag; + } + [Ll]ine[Aa]vg[Ss]orted[Bb]y[Mm]od { + yylval.uint_val = TTCN3_Profiler::STATS_LINE_AVG_SORTED_BY_MOD; + return ProfilerStatsFlag; + } + [Ff]unc[Aa]vg[Ss]orted[Bb]y[Mm]od { + yylval.uint_val = TTCN3_Profiler::STATS_FUNC_AVG_SORTED_BY_MOD; + return ProfilerStatsFlag; + } + [Ll]ine[Aa]vg[Ss]orted[Tt]otal { + yylval.uint_val = TTCN3_Profiler::STATS_LINE_AVG_SORTED_TOTAL; + return ProfilerStatsFlag; + } + [Ff]unc[Aa]vg[Ss]orted[Tt]otal { + yylval.uint_val = TTCN3_Profiler::STATS_FUNC_AVG_SORTED_TOTAL; + return ProfilerStatsFlag; + } + [Tt]op10[Ll]ine[Tt]imes { + yylval.uint_val = TTCN3_Profiler::STATS_TOP10_LINE_TIMES; + return ProfilerStatsFlag; + } + [Tt]op10[Ff]unc[Tt]imes { + yylval.uint_val = TTCN3_Profiler::STATS_TOP10_FUNC_TIMES; + return ProfilerStatsFlag; + } + [Tt]op10[Ll]ine[Cc]ount { + yylval.uint_val = TTCN3_Profiler::STATS_TOP10_LINE_COUNT; + return ProfilerStatsFlag; + } + [Tt]op10[Ff]unc[Cc]ount { + yylval.uint_val = TTCN3_Profiler::STATS_TOP10_FUNC_COUNT; + return ProfilerStatsFlag; + } + [Tt]op10[Ll]ine[Aa]vg { + yylval.uint_val = TTCN3_Profiler::STATS_TOP10_LINE_AVG; + return ProfilerStatsFlag; + } + [Tt]op10[Ff]unc[Aa]vg { + yylval.uint_val = TTCN3_Profiler::STATS_TOP10_FUNC_AVG; + return ProfilerStatsFlag; + } + [Uu]nused[Ll]ines { + yylval.uint_val = TTCN3_Profiler::STATS_UNUSED_LINES; + return ProfilerStatsFlag; + } + [Uu]nused[Ff]unc { + yylval.uint_val = TTCN3_Profiler::STATS_UNUSED_FUNC; + return ProfilerStatsFlag; + } + [Aa]ll[Rr]aw[Dd]ata { + yylval.uint_val = TTCN3_Profiler::STATS_ALL_RAW_DATA; + return ProfilerStatsFlag; + } + [Ll]ine[Dd]ata[Ss]orted[Bb]y[Mm]od { + yylval.uint_val = TTCN3_Profiler::STATS_LINE_DATA_SORTED_BY_MOD; + return ProfilerStatsFlag; + } + [Ff]unc[Dd]ata[Ss]orted[Bb]y[Mm]od { + yylval.uint_val = TTCN3_Profiler::STATS_FUNC_DATA_SORTED_BY_MOD; + return ProfilerStatsFlag; + } + [Ll]ine[Dd]ata[Ss]orted[Tt]otal { + yylval.uint_val = TTCN3_Profiler::STATS_LINE_DATA_SORTED_TOTAL; + return ProfilerStatsFlag; + } + [Ff]unc[Dd]ata[Ss]orted[Tt]otal { + yylval.uint_val = TTCN3_Profiler::STATS_FUNC_DATA_SORTED_TOTAL; + return ProfilerStatsFlag; + } + [Ll]ine[Dd]ata[Ss]orted { + yylval.uint_val = TTCN3_Profiler::STATS_LINE_DATA_SORTED; + return ProfilerStatsFlag; + } + [Ff]unc[Dd]ata[Ss]orted { + yylval.uint_val = TTCN3_Profiler::STATS_FUNC_DATA_SORTED; + return ProfilerStatsFlag; + } + [Aa]ll[Dd]ata[Ss]orted { + yylval.uint_val = TTCN3_Profiler::STATS_ALL_DATA_SORTED; + return ProfilerStatsFlag; + } + [Tt]op10[Ll]ine[Dd]ata { + yylval.uint_val = TTCN3_Profiler::STATS_TOP10_LINE_DATA; + return ProfilerStatsFlag; + } + [Tt]op10[Ff]unc[Dd]ata { + yylval.uint_val = TTCN3_Profiler::STATS_TOP10_FUNC_DATA; + return ProfilerStatsFlag; + } + [Tt]op10[Aa]ll[Dd]ata { + yylval.uint_val = TTCN3_Profiler::STATS_TOP10_ALL_DATA; + return ProfilerStatsFlag; + } + [Uu]nused[Dd]ata { + yylval.uint_val = TTCN3_Profiler::STATS_UNUSED_DATA; + return ProfilerStatsFlag; + } + [Aa]ll { + yylval.uint_val = TTCN3_Profiler::STATS_ALL; + return ProfilerStatsFlag; + } } <SC_EXECUTE>control return ControlKeyword; diff --git a/core/config_process.y b/core/config_process.y index 92c209798..28dce692f 100644 --- a/core/config_process.y +++ b/core/config_process.y @@ -219,12 +219,17 @@ string_map_t *config_defines; %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 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 <uint_val> ProfilerStatsFlag "profiler statistics filter" %type <int_val> IntegerValue %type <float_val> FloatValue @@ -269,6 +274,7 @@ string_map_t *config_defines; %type <module_param_length_restriction> LengthMatch %type <str_val> PatternChunk PatternChunkList %type <int_native> IndexItemIndex LengthBound +%type <uint_val> ProfilerStatsFlags %destructor { Free($$); } ArrayRef @@ -1688,6 +1694,10 @@ ProfilerSetting: | AggregateDataSetting | StatisticsFileSetting | DisableStatisticsSetting +| StatisticsFilterSetting +| StartAutomaticallySetting +| NetLineTimesSetting +| NetFunctionTimesSetting ; DisableProfilerSetting: @@ -1726,6 +1736,46 @@ DisableStatisticsSetting: } ; +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: @@ -2207,8 +2257,6 @@ boolean process_config_file(const char *file_name) string_map_free(config_defines); config_defines = NULL; - ttcn3_prof.init_data_file(); - return !error_flag; } diff --git a/core2/Basetype2.cc b/core2/Basetype2.cc index c3389472e..189fa743f 100644 --- a/core2/Basetype2.cc +++ b/core2/Basetype2.cc @@ -856,7 +856,7 @@ int Record_Of_Type::TEXT_encode(const TTCN_Typedescriptor_t& p_td, } return encoded_length; } - const TTCN_Typedescriptor_t* elem_descr = get_elem_descr(); + const TTCN_Typedescriptor_t* elem_descr = p_td.oftype_descr; for(int a=0;a<get_nof_elements();a++) { if(a!=0 && p_td.text->separator_encode) { buff.put_cs(*p_td.text->separator_encode); @@ -942,9 +942,9 @@ int Record_Of_Type::TEXT_encode_negtest(const Erroneous_descriptor_t* p_err_desc } if (emb_descr) { encoded_length += get_at(a)->TEXT_encode_negtest( - emb_descr,*get_elem_descr(),buff); + emb_descr,*p_td.oftype_descr,buff); } else { - encoded_length += get_at(a)->TEXT_encode(*get_elem_descr(),buff); + encoded_length += get_at(a)->TEXT_encode(*p_td.oftype_descr,buff); } need_separator=true; } @@ -1012,7 +1012,7 @@ int Record_Of_Type::TEXT_decode(const TTCN_Typedescriptor_t& p_td, while(TRUE){ Base_Type* val = create_elem(); pos=buff.get_pos(); - int len = val->TEXT_decode(*get_elem_descr(),buff,limit,TRUE); + int len = val->TEXT_decode(*p_td.oftype_descr,buff,limit,TRUE); if(len==-1 || (len==0 && !limit.has_token())){ buff.set_pos(pos); delete val; @@ -1103,7 +1103,7 @@ ASN_BER_TLV_t* Record_Of_Type::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, TTCN_EncDec_ErrorContext ec; for(int elem_i=0; elem_i<get_nof_elements(); elem_i++) { ec.set_msg("Component #%d: ", elem_i); - new_tlv->add_TLV(get_at(elem_i)->BER_encode_TLV(*get_elem_descr(), p_coding)); + new_tlv->add_TLV(get_at(elem_i)->BER_encode_TLV(*p_td.oftype_descr, p_coding)); } if (is_set()) new_tlv->sort_tlvs(); } @@ -1156,10 +1156,10 @@ ASN_BER_TLV_t* Record_Of_Type::BER_encode_TLV_negtest(const Erroneous_descriptor ec.set_msg("Component #%d: ", elem_i); if (emb_descr) { new_tlv->add_TLV(get_at(elem_i)->BER_encode_TLV_negtest( - emb_descr, *get_elem_descr(), p_coding)); + emb_descr, *p_td.oftype_descr, p_coding)); } else { new_tlv->add_TLV(get_at(elem_i)->BER_encode_TLV( - *get_elem_descr(), p_coding)); + *p_td.oftype_descr, p_coding)); } } @@ -1199,7 +1199,7 @@ boolean Record_Of_Type::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, TTCN_EncDec_ErrorContext ec_1("Component #"); TTCN_EncDec_ErrorContext ec_2("0: "); while(BER_decode_constdTLV_next(stripped_tlv, V_pos, L_form, tmp_tlv)) { - get_at(get_nof_elements())->BER_decode_TLV(*get_elem_descr(), tmp_tlv, L_form); + get_at(get_nof_elements())->BER_decode_TLV(*p_td.oftype_descr, tmp_tlv, L_form); ec_2.set_msg("%d: ", val_ptr->n_elements); } return TRUE; @@ -1232,7 +1232,7 @@ int Record_Of_Type::RAW_decode(const TTCN_Typedescriptor_t& p_td, set_size(0); } int start_field = get_nof_elements(); // append at the end - TTCN_Typedescriptor_t const& elem_descr = *get_elem_descr(); + TTCN_Typedescriptor_t const& elem_descr = *p_td.oftype_descr; if (p_td.raw->fieldlength || sel_field != -1) { if (sel_field == -1) sel_field = p_td.raw->fieldlength; for (int a = 0; a < sel_field; a++) { @@ -1250,7 +1250,6 @@ int Record_Of_Type::RAW_decode(const TTCN_Typedescriptor_t& p_td, if (!first_call) return -1; goto finished; } - int ext_bit = rawdec_ebv(); while (limit > 0) { start_of_field = buff.get_pos_bit(); Base_Type* field_bt = get_at(a); // non-const, extend the record-of @@ -1267,12 +1266,11 @@ int Record_Of_Type::RAW_decode(const TTCN_Typedescriptor_t& p_td, decoded_length += decoded_field_length; limit -= decoded_field_length; a++; - if (ext_bit != 1/*XDEFNO*/&& ext_bit != -1/*XDEFDEFAULT*/) { - // ext_bit here may be 2 (XDEFYES) or 3 (XDEFREVERSE). - // (ext_bit != 2) is 0 or 1 + if (EXT_BIT_NO != p_td.raw->extension_bit) { + // (EXT_BIT_YES != p_td.raw->extension_bit) is 0 or 1 // This is the opposite value of what the bit needs to be to signal // the end of decoding, because x-or is the equivalent of != - if ((ext_bit != 2/*XDEFYES*/) ^ buff.get_last_bit()) { + if ((EXT_BIT_YES != p_td.raw->extension_bit) ^ buff.get_last_bit()) { goto finished; } } @@ -1294,7 +1292,7 @@ int Record_Of_Type::RAW_encode(const TTCN_Typedescriptor_t& p_td, RAW_enc_tree& myleaf.rec_of = TRUE; myleaf.body.node.num_of_nodes = encoded_num_of_records; myleaf.body.node.nodes = init_nodes_of_enc_tree(encoded_num_of_records); - TTCN_Typedescriptor_t const& elem_descr = *get_elem_descr(); + TTCN_Typedescriptor_t const& elem_descr = *p_td.oftype_descr; for (int a = 0; a < encoded_num_of_records; a++) { const Base_Type *field_bt = get_at(a); myleaf.body.node.nodes[a] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), a, elem_descr.raw); @@ -1345,7 +1343,7 @@ int Record_Of_Type::RAW_encode_negtest(const Erroneous_descriptor_t *p_err_descr continue; const Erroneous_values_t *err_vals = p_err_descr->next_field_err_values(i, values_idx); const Erroneous_descriptor_t *emb_descr = p_err_descr->next_field_emb_descr(i, edescr_idx); - TTCN_Typedescriptor_t const& elem_descr = *get_elem_descr(); + TTCN_Typedescriptor_t const& elem_descr = *p_td.oftype_descr; if (err_vals && err_vals->before) { if (err_vals->before->errval == NULL) TTCN_error("internal error: erroneous before value missing"); @@ -1388,11 +1386,11 @@ int Record_Of_Type::RAW_encode_negtest(const Erroneous_descriptor_t *p_err_descr myleaf.body.node.nodes[node_pos] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), node_pos, elem_descr.raw); encoded_length += get_at(i)->RAW_encode_negtest(emb_descr, - *get_elem_descr(), *myleaf.body.node.nodes[node_pos++]); + *p_td.oftype_descr, *myleaf.body.node.nodes[node_pos++]); } else { myleaf.body.node.nodes[node_pos] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), node_pos, elem_descr.raw); - encoded_length += get_at(i)->RAW_encode(*get_elem_descr(), + encoded_length += get_at(i)->RAW_encode(*p_td.oftype_descr, *myleaf.body.node.nodes[node_pos++]); } } @@ -1421,7 +1419,7 @@ int Record_Of_Type::RAW_encode_negtest(const Erroneous_descriptor_t *p_err_descr return myleaf.length = encoded_length; } -int Record_Of_Type::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const +int Record_Of_Type::JSON_encode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok) const { if (!is_bound()) { TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, @@ -1432,7 +1430,7 @@ int Record_Of_Type::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_ int enc_len = p_tok.put_next_token(JSON_TOKEN_ARRAY_START, NULL); for(int i = 0; i < get_nof_elements(); ++i) { - int ret_val = get_at(i)->JSON_encode(*get_elem_descr(), p_tok); + int ret_val = get_at(i)->JSON_encode(*p_td.oftype_descr, p_tok); if (0 > ret_val) break; enc_len += ret_val; } @@ -1458,7 +1456,7 @@ int Record_Of_Type::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenize // Read value tokens until we reach some other token size_t buf_pos = p_tok.get_buf_pos(); Base_Type* val = create_elem(); - int ret_val = val->JSON_decode(*get_elem_descr(), p_tok, p_silent); + int ret_val = val->JSON_decode(*p_td.oftype_descr, p_tok, p_silent); if (JSON_ERROR_INVALID_TOKEN == ret_val) { // undo the last action on the buffer p_tok.set_buf_pos(buf_pos); @@ -1634,7 +1632,7 @@ char **Record_Of_Type::collect_ns(const XERdescriptor_t& p_td, size_t& num, bool if (val_ptr) for (int i = 0; i < get_nof_elements(); ++i) { size_t num_new = 0; char **new_namespaces = get_at(i)->collect_ns( - *get_elem_descr()->xer, num_new, def_ns_1); + *p_td.oftype_descr, num_new, def_ns_1); merge_ns(collected_ns, num_collected, new_namespaces, num_new); def_ns = def_ns || def_ns_1; // alas, no ||= } @@ -1786,6 +1784,8 @@ int Record_Of_Type::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, } else { // not ANY-ATTRIBUTES unsigned int sub_flavor = flavor | XER_RECOF | (p_td.xer_bits & (XER_LIST)); + TTCN_EncDec_ErrorContext ec_0("Index "); + TTCN_EncDec_ErrorContext ec_1; for (int i = 0; i < nof_elements; ++i) { if (i > 0 && !own_tag && 0 != emb_val && @@ -1794,8 +1794,9 @@ int Record_Of_Type::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, UNIVERSAL_CHARSTRING_xer_, p_buf, flavor | EMBED_VALUES, indent+1, 0); ++emb_val->embval_index; } + ec_1.set_msg("%d: ", i); if (exer && (p_td.xer_bits & XER_LIST) && i>0) p_buf.put_c(' '); - get_at(i)->XER_encode(*get_elem_descr()->xer, p_buf, + get_at(i)->XER_encode(*p_td.oftype_descr, p_buf, sub_flavor, indent+own_tag, emb_val); } @@ -1824,7 +1825,7 @@ int Record_Of_Type::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, * @param indent indentation level * @return number of bytes generated */ -int Record_Of_Type::encode_element(int i, +int Record_Of_Type::encode_element(int i, const XERdescriptor_t& p_td, const Erroneous_values_t* ev, const Erroneous_descriptor_t* ed, TTCN_Buffer& p_buf, unsigned int sub_flavor, int indent, embed_values_enc_struct_t* emb_val) const { @@ -1869,10 +1870,10 @@ int Record_Of_Type::encode_element(int i, } else { ec.set_msg("Component #%d: ", i); if (ed) { - get_at(i)->XER_encode_negtest(ed, *get_elem_descr()->xer, p_buf, sub_flavor, indent, emb_val); + get_at(i)->XER_encode_negtest(ed, p_td, p_buf, sub_flavor, indent, emb_val); } else { // the "real" encoder - get_at(i)->XER_encode(*get_elem_descr()->xer, p_buf, sub_flavor, indent, emb_val); + get_at(i)->XER_encode(p_td, p_buf, sub_flavor, indent, emb_val); } } @@ -2069,8 +2070,8 @@ int Record_Of_Type::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr ev0_i = emb_val->embval_err->next_field_err_values(emb_val->embval_index, emb_val->embval_err_val_idx); ed0_i = emb_val->embval_err->next_field_emb_descr (emb_val->embval_index, emb_val->embval_err_descr_idx); } - emb_val->embval_array->encode_element(emb_val->embval_index, ev0_i, ed0_i, - p_buf, flavor | EMBED_VALUES, indent + own_tag, 0); + emb_val->embval_array->encode_element(emb_val->embval_index, UNIVERSAL_CHARSTRING_xer_, + ev0_i, ed0_i, p_buf, flavor | EMBED_VALUES, indent + own_tag, 0); ++emb_val->embval_index; } @@ -2079,7 +2080,7 @@ int Record_Of_Type::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr const Erroneous_descriptor_t* emb_descr = p_err_descr->next_field_emb_descr (i, edescr_idx); - encode_element(i, err_vals, emb_descr, p_buf, sub_flavor, indent+own_tag, emb_val); + encode_element(i, *p_td.oftype_descr, err_vals, emb_descr, p_buf, sub_flavor, indent+own_tag, emb_val); // omit_after value -1 becomes "very big" if ((unsigned int)i >= (unsigned int)p_err_descr->omit_after) break; @@ -2146,7 +2147,7 @@ int Record_Of_Type::XER_decode(const XERdescriptor_t& p_td, pos += strlen(str) + 1; // Construct a new XML Reader with the current token. TTCN_Buffer buf2; - const XERdescriptor_t& sub_xer = *get_elem_descr()->xer; + const XERdescriptor_t& sub_xer = *p_td.oftype_descr; buf2.put_c('<'); write_ns_prefix(sub_xer, buf2); @@ -2233,7 +2234,7 @@ int Record_Of_Type::XER_decode(const XERdescriptor_t& p_td, * belong to the embedded type, the record-of has already ended. */ if (!own_tag && !can_start_v( (const char*)reader.LocalName(), (const char*)reader.NamespaceUri(), - *get_elem_descr()->xer, flavor | UNTAGGED)) + p_td, flavor | UNTAGGED)) { for (; success == 1 && reader.Depth() > depth; success = reader.Read()) ; // We should now be back at the same depth as we started. @@ -2241,7 +2242,7 @@ int Record_Of_Type::XER_decode(const XERdescriptor_t& p_td, } ec_1.set_msg("%d: ", get_nof_elements()); /* The call to the non-const get_at() creates the element */ - get_at(get_nof_elements())->XER_decode(*get_elem_descr()->xer, reader, flavor, emb_val); + get_at(get_nof_elements())->XER_decode(*p_td.oftype_descr, reader, flavor, emb_val); if (0 != emb_val && !own_tag && get_nof_elements() > 1) { ++emb_val->embval_index; } @@ -4690,8 +4691,8 @@ int Record_Type::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, ev0_0 = ed0->next_field_err_values(0, embed_values_val_idx); ed0_0 = ed0->next_field_emb_descr (0, embed_values_descr_idx); } - sub_len += embed_values->encode_element(0, ev0_0, ed0_0, - p_buf, flavor | EMBED_VALUES, indent+!omit_tag, 0); + sub_len += embed_values->encode_element(0, UNIVERSAL_CHARSTRING_xer_, + ev0_0, ed0_0, p_buf, flavor | EMBED_VALUES, indent+!omit_tag, 0); } } @@ -4844,8 +4845,8 @@ int Record_Type::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, ev0_i = ed0->next_field_err_values(emb_val->embval_index, emb_val->embval_err_val_idx); ed0_i = ed0->next_field_emb_descr (emb_val->embval_index, emb_val->embval_err_descr_idx); } - embed_values->encode_element(emb_val->embval_index, ev0_i, ed0_i, - p_buf, flavor | EMBED_VALUES, indent + !omit_tag, 0); + embed_values->encode_element(emb_val->embval_index, UNIVERSAL_CHARSTRING_xer_, + ev0_i, ed0_i, p_buf, flavor | EMBED_VALUES, indent + !omit_tag, 0); ++emb_val->embval_index; } } //for diff --git a/etc/xsd/TXD.xsd b/etc/xsd/TXD.xsd deleted file mode 100644 index e2730e9fc..000000000 --- a/etc/xsd/TXD.xsd +++ /dev/null @@ -1,174 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- -XML Schema for JunitLogger plugin - - Copyright (c) 2000-2014 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 ---> -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" - targetNamespace="http://schemas.ericsson.com/TXD" - xmlns:txd= "http://schemas.ericsson.com/TXD" - elementFormDefault="qualified"> - - <xs:import schemaLocation="TPD.xsd"/> - - <xs:element name="Titan_Execution_Descriptor" type="txd:TXD_Type"/> - - <xs:complexType name="TXD_Type"> - <xs:sequence> - <xs:choice> - <xs:annotation> - <xs:documentation> - A choice between describing how to build the project <build> - or providing the location of a pre-built <executable> - These two are mutually exclusive. - </xs:documentation> - </xs:annotation> - - <xs:element name="Build"> - <xs:annotation> - <xs:documentation> - Describes the way to build the product from source, - using TPDs. - </xs:documentation> - </xs:annotation> - <xs:complexType> - <xs:sequence> - <xs:element name="Projects"> - <xs:complexType> - <xs:sequence> - <xs:element name="Project" minOccurs="1" maxOccurs="unbounded" type="txd:ProjectType" /> - <!-- see below --> - </xs:sequence> - </xs:complexType> - </xs:element> - <xs:element name="MasterConfiguration" type="ConfigurationType" minOccurs="0"> - <xs:annotation> - <xs:documentation> - Override configuration settings in TPDs - </xs:documentation> - </xs:annotation> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - - <xs:element name="Executable"> - <xs:annotation> - <xs:documentation> - Specifies the location of an already built executable - </xs:documentation> - </xs:annotation> - <xs:complexType> - <xs:attribute name="location" /> - </xs:complexType> - </xs:element> - </xs:choice> - - <!-- - Runners - --> - <xs:element name="Run" minOccurs="0" maxOccurs="1"> - <xs:annotation> - <xs:documentation> - Describes how to run the test. - There can be at most one "Run" which may contain various runners - </xs:documentation> - </xs:annotation> - <xs:complexType> - <xs:choice minOccurs="1" maxOccurs="unbounded"> - <xs:element name="SingleModeRun"> - <xs:complexType> - <xs:sequence> - <xs:element name="WorkingDirectory" type="xs:string"/> - <xs:element name="ETS_Name" type="xs:string" minOccurs="0"/> - <!-- ETS_Name may be deduced from the build information --> - <xs:element name="ConfigurationFile" type="xs:string"/> - </xs:sequence> - </xs:complexType> - </xs:element> - <xs:element name="ParallelRun"> - <xs:complexType> - <xs:sequence> - <xs:element name="WorkingDirectory" type="xs:string"/> - <xs:element name="ETS_Name" type="xs:string" minOccurs="0"/> - <!-- ETS_Name may be deduced from the build information --> - <xs:element name="ConfigurationFile" type="xs:string"/> - <xs:element name="HostControllers" minOccurs="0" maxOccurs="1"> - <xs:complexType> - <xs:sequence> - <xs:element name="HostController" minOccurs="1" maxOccurs="unbounded"> - <!-- - Empty <HostControllers> with no <HostController> is not allowed. - Omit the entire <HostControllers> instead. - --> - <xs:complexType> - <xs:sequence> - <xs:element type="xs:string" name="Name"/> - <xs:element type="xs:string" name="HostId" minOccurs="0"/> - <xs:element type="xs:string" name="WorkingDirectory" minOccurs="0"/> - <xs:element type="xs:string" name="Executable" minOccurs="0"/> - <!-- - HostId, WorkingDir and Executable may be omitted, if not referenced by <Command> - --> - <xs:element type="xs:string" name="Command"/> - </xs:sequence> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - <xs:element name="CustomRun" type="xs:string"> - <!-- TODO: is a simple string enough? --> - </xs:element> - </xs:choice> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - - <xs:complexType name="ProjectType"> - <xs:annotation> - <xs:documentation> - Describes a referenced project - </xs:documentation> - </xs:annotation> - <xs:sequence> - <xs:element name="Configurations"> - <xs:complexType> - <xs:sequence> - <xs:element name="Configuration" minOccurs="0" maxOccurs="unbounded" > - <xs:complexType> - <!-- Optional: put in a <sequence> if sub-elements are needed --> - <xs:attribute name="name" use="required" /> - </xs:complexType> - </xs:element> - </xs:sequence> - </xs:complexType> - </xs:element> - </xs:sequence> - <xs:attribute name="name" use="optional"> - <xs:annotation> - <xs:documentation> - Optional name of the project. Can be used as reference in the TXD itself. - The TPD is identified by the "path" attribute, below. - </xs:documentation> - </xs:annotation> - </xs:attribute> - <xs:attribute name="path" use="required"> - <xs:annotation> - <xs:documentation> - This is the filename of the TPD file. Paths are relative to the TXD - itself, or absolute. - </xs:documentation> - </xs:annotation> - </xs:attribute> - </xs:complexType> -</xs:schema> diff --git a/function_test/BER_EncDec/BER_EncDec_TD.fast_script b/function_test/BER_EncDec/BER_EncDec_TD.fast_script index 4510b010e..49b8a3e8d 100644 --- a/function_test/BER_EncDec/BER_EncDec_TD.fast_script +++ b/function_test/BER_EncDec/BER_EncDec_TD.fast_script @@ -9,9 +9,9 @@ :lang eng. .* :docname.Test Description -:docno.8/152 91-CRL 113 200/2 Uen -:rev.A -:date.2012-06-27 +:docno.8/152 91-CRL 113 200/5 Uen +:rev.C +:date.2015-04-27 .* :prep.ETH/XZR Kristof Szabados (+36 1 437 7256) :appr.ETH/XZ (Roland Gecse) diff --git a/function_test/Config_Parser/Logging_1_TD.script b/function_test/Config_Parser/Logging_1_TD.script index 285f4e098..e3a6a6c07 100755 --- a/function_test/Config_Parser/Logging_1_TD.script +++ b/function_test/Config_Parser/Logging_1_TD.script @@ -14,9 +14,9 @@ .* Document header information :docname.Test Description -:docno.24/152 91-CRL 113 200/4 Uen -:rev.PA6 -:date.2014-04-01 +:docno.24/152 91-CRL 113 200/5 Uen +:rev.C +:date.2015-04-27 :prep.ETH/RZX Norbert Bartha (ethnba) :appr.ETH/RZX (Csaba Koppany) diff --git a/function_test/Config_Parser/OrderedInclude.script b/function_test/Config_Parser/OrderedInclude.script index 6a80b4896..e22683fda 100644 --- a/function_test/Config_Parser/OrderedInclude.script +++ b/function_test/Config_Parser/OrderedInclude.script @@ -15,8 +15,8 @@ .* Document header information :docname.Test Description :docno.xx/152 91-CRL 113 200/3 Uen -:rev.A -:date.2013-13-14 +:rev.C +:date.2015-04-27 :prep.ETH/XZR Jeno Balasko :appr.ETH/XZR (Elemer Lelik) diff --git a/function_test/Config_Parser/PreprocessingCfgFiles_TD.script b/function_test/Config_Parser/PreprocessingCfgFiles_TD.script index 6a48c1af8..19926d924 100644 --- a/function_test/Config_Parser/PreprocessingCfgFiles_TD.script +++ b/function_test/Config_Parser/PreprocessingCfgFiles_TD.script @@ -14,9 +14,9 @@ .* Document header information :docname.Test Description -:docno.xx/152 91-CRL 113 200/2 Uen -:rev.A -:date.2013-01-16 +:docno.xx/152 91-CRL 113 200/5 Uen +:rev.C +:date.2015-04-27 :prep.ETH/RZX Jeno Balasko (ethbaat) :appr.ETH/RZX (Gyula Koos) diff --git a/function_test/RAW_EncDec/RAW_EncDec_TD.fast_script b/function_test/RAW_EncDec/RAW_EncDec_TD.fast_script index 02c2cdf9d..fd145b621 100644 --- a/function_test/RAW_EncDec/RAW_EncDec_TD.fast_script +++ b/function_test/RAW_EncDec/RAW_EncDec_TD.fast_script @@ -9,9 +9,9 @@ :lang eng. .* :docname.Test Description -:docno.7/152 91-CRL 113 200/2 Uen +:docno.7/152 91-CRL 113 200/5 Uen :rev.A -:date.2013-02-01 +:date.2015-04-27 .* :prep.ETH/XZR Jeno Balasko (+36 1 437 7760) :appr.ETH/XZ (Gyula Koos) diff --git a/function_test/Semantic_Analyser/ASN_SA_1_TD.script b/function_test/Semantic_Analyser/ASN_SA_1_TD.script index 4e33f50ba..d3dedc04f 100644 --- a/function_test/Semantic_Analyser/ASN_SA_1_TD.script +++ b/function_test/Semantic_Analyser/ASN_SA_1_TD.script @@ -14,9 +14,9 @@ .* Document header information :docname.Test Description -:docno. Uen -:rev.PA1 -:date.2005.02.03. +:docno. 12/15291-CRL200/5 Uen +:rev.A +:date.2015-04-27 :prep.ETH/RZD Endre Szalai (+36 1 437 7796) :appr.ETH/RZ (Zsolt Szendrei) diff --git a/function_test/Semantic_Analyser/ASN_SA_asn1adhoc_TD.script b/function_test/Semantic_Analyser/ASN_SA_asn1adhoc_TD.script index 834ce8d5c..f4436d6ac 100644 --- a/function_test/Semantic_Analyser/ASN_SA_asn1adhoc_TD.script +++ b/function_test/Semantic_Analyser/ASN_SA_asn1adhoc_TD.script @@ -14,9 +14,9 @@ .* Document header information :docname.Test Description -:docno. +:docno.20/15291-CRL200/5 Uen :rev. -:date.2005.01.31. +:date.2015-04-27 :prep.ETH/RZD Endre Szalai (+36 1 437 7796) :appr. @@ -33,7 +33,7 @@ :xmp tab=2. REV DATE PREPARED CHANGE __________________________________________________ -- 2005-01-31 ETHESI New document for TITAN R6 +- 2005-01-31 ETHESI New document for TITAN R1.6 :exmp. .*---------------------------------------------------------------------* :h2.Purpose diff --git a/function_test/Semantic_Analyser/TTCN3_SA_10_TD.script b/function_test/Semantic_Analyser/TTCN3_SA_10_TD.script index 89dea1694..3d0552ce9 100644 --- a/function_test/Semantic_Analyser/TTCN3_SA_10_TD.script +++ b/function_test/Semantic_Analyser/TTCN3_SA_10_TD.script @@ -14,11 +14,11 @@ .* Document header information :docname.Test Description -:docno.22/152 91-CRL 113 200/3 Uen +:docno.22/152 91-CRL 113 200/5 Uen :rev.A -:date.2013-01-17 +:date.2015-04-27 -:prep.ETH/XZR Krisztian Pandi +:prep.ETH/XZ Jeno Balasko :appr.ETH/XZ (Gyula Koos) :checked.ETHGRY diff --git a/function_test/Semantic_Analyser/TTCN3_SA_11_TD.script b/function_test/Semantic_Analyser/TTCN3_SA_11_TD.script index ce629bd05..03373a9c4 100644 --- a/function_test/Semantic_Analyser/TTCN3_SA_11_TD.script +++ b/function_test/Semantic_Analyser/TTCN3_SA_11_TD.script @@ -9,9 +9,9 @@ text. :lang eng. .* :docname.Test Description -:docno. -:rev.PA1 -:date.2011.11.21 +:docno. xy/152 91-CRL 113 200/5 Uen +:rev.A +:date.2015-04-27 .* :prep.ETH/XZR ETHBAAT :subresp.ETHBAAT diff --git a/function_test/Semantic_Analyser/TTCN3_SA_12_TD.script_not_running b/function_test/Semantic_Analyser/TTCN3_SA_12_TD.script_not_running index 6c66e1973..fde96ede2 100644 --- a/function_test/Semantic_Analyser/TTCN3_SA_12_TD.script_not_running +++ b/function_test/Semantic_Analyser/TTCN3_SA_12_TD.script_not_running @@ -8,8 +8,8 @@ .* Document header information :docname.Test Description :docno.xx/152 91-CRL 113 200 Uen -:rev.PA1 -:date.2011-11-16 +:rev.A +:date.2015-04-27 :prep.ETH/RZX Jeno Balasko (ethbaat) :appr.ETH/RZX (Roland Gecse) diff --git a/function_test/Semantic_Analyser/TTCN3_SA_13_TD.script b/function_test/Semantic_Analyser/TTCN3_SA_13_TD.script index 36678584a..3011ec228 100644 --- a/function_test/Semantic_Analyser/TTCN3_SA_13_TD.script +++ b/function_test/Semantic_Analyser/TTCN3_SA_13_TD.script @@ -9,9 +9,9 @@ text. :lang eng. .* :docname.Test Description -:docno. +:docno.xz/152 91-CRL 113 200 Uen :rev.PA3 -:date.2013-01-16 +:date.2015-04-27 .* :prep.ETH/XZR ETHBAAT :subresp.ETHBAAT diff --git a/function_test/Semantic_Analyser/TTCN3_SA_1_TD.script b/function_test/Semantic_Analyser/TTCN3_SA_1_TD.script index 37e1db132..f4c5b926d 100644 --- a/function_test/Semantic_Analyser/TTCN3_SA_1_TD.script +++ b/function_test/Semantic_Analyser/TTCN3_SA_1_TD.script @@ -14,11 +14,11 @@ .* Document header information :docname.Test Description -:docno.12/152 91-CRL 113 200/3 Uen +:docno.12/152 91-CRL 113 200/5 Uen :rev.A -:date.2013-01-17 +:date.2015-04-27 -:prep.ETH/XZR Krisztian Pandi +:prep.ETH/XZR Jeno Balasko :appr.ETH/XZ (Gyula Koos) :checked.ETHGRY diff --git a/function_test/Semantic_Analyser/TTCN3_SA_3_TD.script b/function_test/Semantic_Analyser/TTCN3_SA_3_TD.script index e769c1841..5ced083cd 100644 --- a/function_test/Semantic_Analyser/TTCN3_SA_3_TD.script +++ b/function_test/Semantic_Analyser/TTCN3_SA_3_TD.script @@ -14,12 +14,12 @@ .* Document header information :docname.Test Description -:docno.14/152 91-CRL 113 200/3 Uen +:docno.14/152 91-CRL 113 200/5 Uen :rev.A -:date.2013-01-17 +:date.2015-04-27 -:prep.ETH/XZR Krisztian Pandi -:appr.ETH/XZ (Gyula Koos) +:prep.ETH/XZ Jeno Balasko +:appr.ETH/XZ (Elemer Lelik) :checked.ETHGRY :title.Test description of the TTCN-3 Semantic Analyzer: Scope Rules diff --git a/function_test/Semantic_Analyser/TTCN3_SA_4_TD.script b/function_test/Semantic_Analyser/TTCN3_SA_4_TD.script index 46eef824d..bde23e488 100644 --- a/function_test/Semantic_Analyser/TTCN3_SA_4_TD.script +++ b/function_test/Semantic_Analyser/TTCN3_SA_4_TD.script @@ -16,9 +16,9 @@ :docname.Test Description :docno.15/152 91-CRL 113 200/3 Uen :rev.A -:date.2013-01-17 +:date.2015-04-27 -:prep.ETH/XZR Krisztian Pandi +:prep.ETH/XZ Jeno Balasko :appr.ETH/XZ (Gyula Koos) :checked.ETHGRY diff --git a/function_test/Semantic_Analyser/TTCN3_SA_5_TD.script b/function_test/Semantic_Analyser/TTCN3_SA_5_TD.script index 4db626a15..86e414e24 100644 --- a/function_test/Semantic_Analyser/TTCN3_SA_5_TD.script +++ b/function_test/Semantic_Analyser/TTCN3_SA_5_TD.script @@ -14,11 +14,11 @@ .* Document header information :docname.Test Description -:docno.16/152 91-CRL 113 200/3 Uen +:docno.16/152 91-CRL 113 200/5 Uen :rev.A -:date.2013-01-17 +:date.2015-04-27 -:prep.ETH/XZR Krisztian Pandi +:prep.ETH/XZ Jeno Balasko :appr.ETH/XZ (Gyula Koos) :checked.ETHGRY diff --git a/function_test/Semantic_Analyser/TTCN3_SA_6_TD.script b/function_test/Semantic_Analyser/TTCN3_SA_6_TD.script index c6402d6c9..b86039917 100644 --- a/function_test/Semantic_Analyser/TTCN3_SA_6_TD.script +++ b/function_test/Semantic_Analyser/TTCN3_SA_6_TD.script @@ -16,9 +16,9 @@ :docname.Test Description :docno.17/152 91-CRL 113 200/3 Uen :rev.A -:date.2013-01-17 +:date.2015-04-27 -:prep.ETH/XZR Krisztian Pandi +:prep.ETH/XZ Jeno Balasko :appr.ETH/XZ (Gyula Koos) :checked.EKRISZA @@ -16537,7 +16537,7 @@ ConsoleMask := WARNING | ERROR | TESTCASE | STATISTICS ModuleA <END_MODULE> <RESULT IF_PASS COUNT 1> -(?im)Dynamic test case error: Accessing an element in an unbound value of type @ModuleA.t_recof. +(?im)Dynamic test case error: Accessing an element in an unbound value of type @PreGenRecordOf.PREGEN_RECORD_OF_INTEGER. <END_RESULT> <END_TC> :exmp. @@ -16577,7 +16577,7 @@ ConsoleMask := WARNING | ERROR | TESTCASE | STATISTICS ModuleA <END_MODULE> <RESULT IF_PASS COUNT 1> -(?im)Dynamic test case error: Index overflow in a value of type @ModuleA.t_recof: The index is 10, but the value has only 2 elements. +(?im)Dynamic test case error: Index overflow in a value of type @PreGenRecordOf.PREGEN_RECORD_OF_INTEGER: The index is 10, but the value has only 2 elements. <END_RESULT> <END_TC> :exmp. @@ -16617,7 +16617,7 @@ ConsoleMask := WARNING | ERROR | TESTCASE | STATISTICS ModuleA <END_MODULE> <RESULT IF_PASS COUNT 1> -(?im)Dynamic test case error: Accessing an element in an unbound value of type @ModuleA.t_setof. +(?im)Dynamic test case error: Accessing an element in an unbound value of type @PreGenRecordOf.PREGEN_SET_OF_INTEGER. <END_RESULT> <END_TC> :exmp. @@ -16657,7 +16657,7 @@ ConsoleMask := WARNING | ERROR | TESTCASE | STATISTICS ModuleA <END_MODULE> <RESULT IF_PASS COUNT 1> -(?im)Dynamic test case error: Index overflow in a value of type @ModuleA.t_setof: The index is 10, but the value has only 2 elements. +(?im)Dynamic test case error: Index overflow in a value of type @PreGenRecordOf.PREGEN_SET_OF_INTEGER: The index is 10, but the value has only 2 elements. <END_RESULT> <END_TC> :exmp. diff --git a/function_test/Semantic_Analyser/TTCN3_SA_7_TD.script b/function_test/Semantic_Analyser/TTCN3_SA_7_TD.script index 99987ce00..10878ccfc 100644 --- a/function_test/Semantic_Analyser/TTCN3_SA_7_TD.script +++ b/function_test/Semantic_Analyser/TTCN3_SA_7_TD.script @@ -14,9 +14,9 @@ .* Document header information :docname.Test Description -:docno.18/152 91-CRL 113 200/3 Uen +:docno.18/152 91-CRL 113 200/5 Uen :rev.A -:date.2013-01-17 +:date.2015-04-27 :prep.ETH/XZR Krisztian Pandi :appr.ETH/XZ (Gyula Koos) diff --git a/function_test/Semantic_Analyser/TTCN3_SA_9_TD.script b/function_test/Semantic_Analyser/TTCN3_SA_9_TD.script index f136affdd..9076fc2ca 100644 --- a/function_test/Semantic_Analyser/TTCN3_SA_9_TD.script +++ b/function_test/Semantic_Analyser/TTCN3_SA_9_TD.script @@ -14,11 +14,11 @@ .* Document header information :docname.Test Description -:docno.20/152 91-CRL 113 200/3 Uen +:docno.xx/152 91-CRL 113 200/5 Uen :rev.A -:date.2013-01-17 +:date.2015-04-27 -:prep.ETH/XZR Krisztian Pandi +:prep.ETH/XZ Jeno Balasko :appr.ETH/XZ (Gyula Koos) :checked.ETHGRY @@ -41,9 +41,10 @@ D 2007-06-08 EJNOSZA Updates for TITAN R7B (expected error messages for E 2008-10-01 EKRISZA Updates for TITAN R7E F 2010-01-18 EKRISZA Updated for TITAN R8C K 2011-10-10 EKRISZA Updated for TITAN R8H -A 2011-12-12 EKRISZA Updated for release -A 2012-06-27 EFERKOV Updated for release -A 2013-01-17 EKRIPND Updated for release +A 2011-12-12 EKRISZA Updated for release +A 2012-06-27 EFERKOV Updated for release +A 2013-01-17 EKRIPND Updated for release +A 2015-04-27 ETHBAAT Updated for release :exmp. .*---------------------------------------------------------------------* diff --git a/function_test/Semantic_Analyser/TTCN3_SA_ttcn3adhoc_TD.script b/function_test/Semantic_Analyser/TTCN3_SA_ttcn3adhoc_TD.script index db2b40fc7..b1daa6a20 100644 --- a/function_test/Semantic_Analyser/TTCN3_SA_ttcn3adhoc_TD.script +++ b/function_test/Semantic_Analyser/TTCN3_SA_ttcn3adhoc_TD.script @@ -14,11 +14,11 @@ .* Document header information :docname.Test Description -:docno.20/152 91-CRL 113 200/3 Uen +:docno.2x/152 91-CRL 113 200/5 Uen :rev.A -:date.2013-01-17 +:date.2015-04-27 -:prep.ETH/XZR Krisztian Pandi +:prep.ETH/XZ Jeno Balasko :appr.ETH/XZ (Gyula Koos) :checked.ETHGRY @@ -33,7 +33,7 @@ :xmp tab=2. REV DATE PREPARED CHANGE __________________________________________________ -- 2005-02-19 EGBOTAT New document for TITAN R6 +- 2005-02-19 EGBOTAT New document for TITAN R1.6 - 2005-06-30 ETIBHRA Added select-case, alive, interleave tests - 2005-08-16 ETIBHRA Deleted select-case, alive, interleave tests - 2007-12-03 ETHNBA TCs for IsBound are added @@ -3644,22 +3644,19 @@ testcase tc() runs on Empty module bad_arguments { type component empty { } -type record of integer intlist1 -type record of integer intlist2 +type record of integer intlist testcase tc () runs on empty { var integer a := 0 var charstring cs_1 := "My name is JJ" var bitstring bs_1 := '11'B var charstring cs_2 := replace("My name is JJ", -1, 2, "xx") - var intlist1 il1 := { 1, 2, 3 } - var intlist2 il2 := { 4 } + var intlist il1 := { 1, 2, 3 } cs_2 := replace("My name is JJ", 1, 2, '11'B) cs_2 := replace("My name is JJ", 100, 2, "x") cs_2 := replace("My name is JJ", a, 100, "x") cs_2 := replace(cs_1, 1, 2, bs_1) cs_2 := replace(cs_1, 1.0, 2, "xx") - il1 := replace(il1, 1, 1, il2) il1 := replace(il1, 1, 1, cs_1[10]) } } @@ -3670,11 +3667,8 @@ testcase tc () runs on empty <RESULT COUNT 2> (?is)\berror:.+?Fourth operand of operation `replace\(\)' is of type `bitstring', but a value of type `charstring' was expected here <END_RESULT> -<RESULT LTRT COUNT 1> -(?is)\berror:.+?Fourth operand of operation `replace\(\)' is of type `\@bad_arguments.intlist2', but a value of type `\@bad_arguments.intlist1' was expected here -<END_RESULT> <RESULT COUNT 1> -(?is)\berror:.+?Fourth operand of operation `replace\(\)' is of type `charstring', but a value of type `\@bad_arguments.intlist1' was expected here +(?is)\berror:.+?Fourth operand of operation `replace\(\)' is of type `charstring', but a value of type `\@bad_arguments.intlist' was expected here <END_RESULT> <RESULT COUNT 1> (?is)\berror:.+?The sum of second operand `index' \(100\) and third operand `len' \(2\) is greater than the length of the first operand \(13\) @@ -4301,31 +4295,6 @@ control { <END_TC> :exmp. -.*---------------------------------------------------------------------* -:h3.Adhoc:: TR 935 - concatenation of incompatible list types -.*---------------------------------------------------------------------* -:xmp tab=0. -<TC - TR 935 - concatenation of incompatible list types> -<COMPILE> -<VERDICT_LEAF PASS> -<MODULE TTCN TR935 TR935.ttcn> -module TR935 { -type record of integer intlist1 -type record of integer intlist2 -control { - var intlist1 il1 := { 1, 2, 3 } - var intlist2 il2 := { 4 } - il1 := il1 & il2 - // Merge this small test-case later. -} -} -<END_MODULE> -<RESULT LTRT COUNT 1> -(?is)\berror: The operands of operation `&' should be of compatible types -<END_RESULT> -<END_TC> -:exmp. - .*---------------------------------------------------------------------* :h3.Adhoc:: Type Compatibility - Sample tests for structured types .*---------------------------------------------------------------------* @@ -4376,13 +4345,13 @@ ro2 := substr(myrec1 : t_myrecof3, 0, 1) // !OK <RESULT LTRT COUNT 1> (?is)\berror: Type mismatch: a value of type `\@Compat1.myrecof1' was expected instead of `integer\[4\]' <END_RESULT> -<RESULT LTRT COUNT 3> +<RESULT LTRT COUNT 2> (?is)\berror: The operands of operation `==' should be of compatible types <END_RESULT> <RESULT FTRT COUNT 1> (?is)\berror: Type mismatch: `\@Compat1.myrecof1' and `integer\[4\]' are not compatible: Incompatible record of/SEQUENCE OF subtypes <END_RESULT> -<RESULT FTRT COUNT 1> +<RESULT COUNT 1> (?is)\berror: Type mismatch: `@Compat1.myrecof1' and `@Compat1.myrecof3' are not compatible: Incompatible record of/SEQUENCE OF subtypes <END_RESULT> <RESULT LTRT COUNT 1> @@ -6116,13 +6085,7 @@ module module1 <RESULT COUNT 1> (?is)\berror: \{ \} is not a valid value for type `\@module1.myro1' which has subtype length\(1\) <END_RESULT> -<RESULT LTRT COUNT 2> -(?is)\berror: The operands of operation `==' should be of compatible types -<END_RESULT> -<RESULT LTRT COUNT 1> -(?is)\berror: Type mismatch: a value or template of type `\@module1.myro1' was expected instead of `\@module1.myro2' -<END_RESULT> -<RESULT FTRT COUNT 3> +<RESULT COUNT 3> (?is)\berror: Type mismatch: `\@module1.myro1' and `\@module1.myro2' are not compatible: Incompatible record of/SEQUENCE OF subtypes <END_RESULT> <RESULT COUNT 1> @@ -6202,13 +6165,7 @@ module module1 <RESULT COUNT 1> (?is)\berror: \{ \} is not a valid value for type `\@module1.myso1' which has subtype length\(1\) <END_RESULT> -<RESULT LTRT COUNT 2> -(?is)\berror: The operands of operation `==' should be of compatible types -<END_RESULT> -<RESULT LTRT COUNT 1> -(?is)\berror: Type mismatch: a value or template of type `\@module1.myso1' was expected instead of `\@module1.myso2' -<END_RESULT> -<RESULT FTRT COUNT 3> +<RESULT COUNT 3> (?is)\berror: Type mismatch: `\@module1.myso1' and `\@module1.myso2' are not compatible: Incompatible set of/SET OF subtypes <END_RESULT> <RESULT COUNT 20> @@ -8323,10 +8280,10 @@ Temp :exmp. .*---------------------------------------------------------------------* -:h3.Adhoc:: modulepar invalid simple type: component, port, default +:h3.Adhoc:: modulepar invalid simple type: port .*---------------------------------------------------------------------* :xmp tab=0. -<TC - Adhoc::modulepar invalid type - component, port, default> +<TC - Adhoc::modulepar invalid type - port> <COMPILE> <VERDICT_LEAF FAIL> <MODULE TTCN Temp Temp.ttcn> @@ -8343,76 +8300,7 @@ module Temp { type default default_DT; } <END_MODULE> -<RESULT IF_FAIL COUNT 3> -(?is)\berror: -<END_RESULT> -<RESULT IF_FAIL POSITIVE> -(?im)\bnotify\b.+?\bcode\b.+?\bnot\b.+?\bgenerated\b -<END_RESULT><END_TC> -:exmp. - -.*------------------------------------------------------------------------------------* -:h3.Adhoc:: modulepar invalid compound type: record, set with component, default -.*------------------------------------------------------------------------------------* -:xmp tab=0. -<TC - Adhoc::modulepar invalid type - compound type> -<COMPILE> -<VERDICT_LEAF FAIL> -<MODULE TTCN Temp Temp.ttcn> -module Temp { - modulepar invalidRec tsp_Rec; - modulepar invalidSet tsp_Set; - modulepar invalidUnion tsp_Union; - type record invalidRec { - integer varI1, - default_DT varDT, - charstring varStr - } - type set invalidSet { - integer varI2, - comp_CT varCT1, - charstring varStr - } - type union invalidUnion { - integer varI3, - comp_CT varCT2 - } - type default default_DT; - type component comp_CT { - var integer v_int := 0; - } -} -<END_MODULE> -<RESULT IF_FAIL COUNT 3> -(?is)\berror: -<END_RESULT> -<RESULT IF_FAIL POSITIVE> -(?im)\bnotify\b.+?\bcode\b.+?\bnot\b.+?\bgenerated\b -<END_RESULT><END_TC> -:exmp. - -.*------------------------------------------------------------------------------------* -:h3.Adhoc:: modulepar invalid list: record of, set of and array with component, default -.*------------------------------------------------------------------------------------* -:xmp tab=0. -<TC - Adhoc::modulepar invalid list - record of, set of and array with component, default> -<COMPILE> -<VERDICT_LEAF FAIL> -<MODULE TTCN Temp Temp.ttcn> -module Temp { - modulepar ListRec tsp_ListRec; - modulepar ListSet tsp_listSet; - modulepar compArrayType tsp_compArray; - type record of comp_CT ListRec; - type set of default_DT ListSet; - type comp_CT compArrayType[3]; - type default default_DT; - type component comp_CT { - var integer v_int := 0; - } -} -<END_MODULE> -<RESULT IF_FAIL COUNT 3> +<RESULT IF_FAIL COUNT 1> (?is)\berror: <END_RESULT> <RESULT IF_FAIL POSITIVE> @@ -8448,7 +8336,7 @@ module Temp { <RESULT IF_FAIL COUNT 1> (?im)\bcircular\b.+?\breference\b <END_RESULT> -<RESULT IF_FAIL COUNT 2> +<RESULT IF_FAIL COUNT 1> (?is)\berror: <END_RESULT> <RESULT IF_FAIL POSITIVE> diff --git a/function_test/Text_EncDec/TEXT_1_TD.fast_script b/function_test/Text_EncDec/TEXT_1_TD.fast_script index fd201d4c0..9b834137d 100644 --- a/function_test/Text_EncDec/TEXT_1_TD.fast_script +++ b/function_test/Text_EncDec/TEXT_1_TD.fast_script @@ -9,9 +9,9 @@ :lang eng. .* :docname.Test Description -:docno.21/152 91-CRL 113 200/2 Uen +:docno.21/152 91-CRL 113 200/5 Uen :rev.A -:date.2012-06-27 +:date.2015-04-27 .* :prep.ETH/XZR Ferenc Kovacs (+36 1 439 5511) :appr.ETH/XZ (Roland Gecse) diff --git a/function_test/Tools/SAtester b/function_test/Tools/SAtester index 73c46e7f9..6c2d49bfb 100755 --- a/function_test/Tools/SAtester +++ b/function_test/Tools/SAtester @@ -78,7 +78,7 @@ proc _compiler {message} { } -proc _executor {message coverage_args rt_2} { +proc _executor {message coverage_args} { global sh_id if {![file exists Makefile]} { @@ -162,12 +162,11 @@ set tc_counter 0 set err_counter 0 set errpostfix "_error" set coverage_args "" -set rt_2 "" set start_date [exec date +"%H:%M:%S"] if {[lindex $argv 0] == "-coverage"} {set argv [lrange $argv 1 end]; set coverage_args "COVERAGE=1"; puts "Coverage mode enabled!"} # RT2 comes after coverage -if {[lindex $argv 0] == "-rt2"} {set argv [lrange $argv 1 end]; set rt_2 "RT2=2"; puts "Function-test runtime enabled!"} +if {[lindex $argv 0] == "-rt2"} {set argv [lrange $argv 1 end]; set env(RT2) yes; puts "Function-test runtime enabled!"} set errorfilename $argv$errpostfix @@ -249,9 +248,9 @@ while {$i <= $tc_counter} { } if {([string length $result_mess] > 3)&&($tc_state != "execute")&&($tc_state != "pure_execute")} {_compiler $result_mess} - if {([string length $Line] > 3)&&($tc_state == "execute")} {_executor $result_mess $coverage_args $rt_2} + if {([string length $Line] > 3)&&($tc_state == "execute")} {_executor $result_mess $coverage_args} if {([string length $Line] > 3)&&($tc_state == "pure_execute")} { - _executor $result_mess $coverage_args $rt_2 + _executor $result_mess $coverage_args } incr i diff --git a/function_test/XER_EncDec/XER_EncDec_TD.script b/function_test/XER_EncDec/XER_EncDec_TD.script index 098c99a1e..e110cb134 100644 --- a/function_test/XER_EncDec/XER_EncDec_TD.script +++ b/function_test/XER_EncDec/XER_EncDec_TD.script @@ -9,12 +9,12 @@ :lang eng. .* :docname.Test Description -:docno.7/152 91-CRL 113 200/4 Uen +:docno.9/152 91-CRL 113 200/5 Uen :rev.A -:date.2014-04-29 +:date.2015-04-27 .* :prep.ETH/XZ Botond Baranyi -:appr.ETH/XZ (Jeno Balasko) +:appr.ETH/XZ (Elemer Lelik) :checked.ETHBAAT .* :title.Test description - XER coder @@ -828,7 +828,7 @@ control { <RESULT> -Dynamic test case error: While XER-decoding type '@Temp.any_elem_rec_of': While checking anyElement: XML namespace "http://www.somewhere.com" is not in the allowed namespace list. +Dynamic test case error: While XER-decoding type '@Temp.any_elem_rec_of': Index 0: While checking anyElement: XML namespace "http://www.somewhere.com" is not in the allowed namespace list. <END_TC> @@ -875,7 +875,7 @@ control { <RESULT> -Dynamic test case error: While XER-decoding type '@Temp.any_elem_rec_of': While checking anyElement: XML namespace "http://www.somewhereelse.com" is not in the allowed namespace list. +Dynamic test case error: While XER-decoding type '@Temp.any_elem_rec_of': Index 0: While checking anyElement: XML namespace "http://www.somewhereelse.com" is not in the allowed namespace list. <END_TC> @@ -924,7 +924,7 @@ control { <RESULT> -Dynamic test case error: While XER-decoding type '@Temp.any_elem_rec_of': While checking anyElement: XML namespace "http://www.someotherplace.com" is not in the allowed namespace list. +Dynamic test case error: While XER-decoding type '@Temp.any_elem_rec_of': Index 0: While checking anyElement: XML namespace "http://www.someotherplace.com" is not in the allowed namespace list. <END_TC> @@ -1124,7 +1124,7 @@ control { <RESULT> -Dynamic test case error: While XER-decoding type '@Temp.any_elem_rec_of': While checking anyElement: The unqualified XML namespace is in the excluded namespace list. +Dynamic test case error: While XER-decoding type '@Temp.any_elem_rec_of': Index 0: While checking anyElement: The unqualified XML namespace is in the excluded namespace list. <END_TC> @@ -1171,7 +1171,7 @@ control { <RESULT> -Dynamic test case error: While XER-decoding type '@Temp.any_elem_rec_of': While checking anyElement: XML namespace "http://www.somewhere.com" is in the excluded namespace list. +Dynamic test case error: While XER-decoding type '@Temp.any_elem_rec_of': Index 0: While checking anyElement: XML namespace "http://www.somewhere.com" is in the excluded namespace list. <END_TC> @@ -1218,7 +1218,7 @@ control { <RESULT> -Dynamic test case error: While XER-decoding type '@Temp.any_elem_rec_of': While checking anyElement: XML namespace "http://www.somewhereelse.com" is in the excluded namespace list. +Dynamic test case error: While XER-decoding type '@Temp.any_elem_rec_of': Index 0: While checking anyElement: XML namespace "http://www.somewhereelse.com" is in the excluded namespace list. <END_TC> diff --git a/function_test/doc/TTCN3_Executor_TestReport.doc b/function_test/doc/TTCN3_Executor_TestReport.doc index 458f786c0c7725b5e73773bf4e43fdc44ffa0591..860c9b06e00f2cb20da5ba5a7f7624facfee12c2 100644 GIT binary patch delta 69947 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 C&PI{| delta 56432 zcmagn1$flj_OS7ljI^B!6fcG1ZpE#oP~6?!-Cc{j!(niD*A7l`clQ=|cR299A<4bK z+>bx!`BnBxvTg01OgnG}9w<8SMEJzu#1%Y6{}WrJ5??EP_x;C@A0o~dS7I0NDN9*7 zl!wdzR_sp7WHpIWdrDF@wa<D#xz$|xY1)+X>b8g^Tx5D0{d%W1isZ0}jLahvhpW!a zD{_WVn|ylw&(Cx7i&V3Uya^Sl$MF@yMAma?d9I`KxgwvnKY#h0@;?Wp*1n1q*~pn2 zw~E~1+pb(7{*+19xQ?Ml6TgS?ZGx0q&DtOH^LJ|2{+OS;Zk+PX5)@%JSP$wQ$wfm) za@_<J4(Oss{`{<6CU!;<vsUvue}1oZ^w&S;b&N7+gXxY8S<E*5{|?qp8cwHYtYEaA z{xxIAbvByr$QQ9<jeZ%ka%Pw*7HMS36m2hlMw|7Yf6Q{fHcUGutyhWUGGf}N{4_Ei zpXc&9n9tfQYk%f&oDcO*-KKwEhx0Sr^zU1VSY*W-XXWXR5@oc89N`%AK>hIlj!x&b z#7P^oqvmIGG|caR&RyD+|NU0Kkomnf+1elGZjv>veRxNaPby!gEMOk-=V!Agf0qCE z`zc90=H@Wl{oi7}qW}N*TE7d$agT2b@hs^v<bJFX_hTtgVSyDk*x><Bc)9M!a<uDa z&5<R0uyfE*M_gyCp^ijK5f@(%RJ0jx;#7t^oNDRV&Y8m<=^WZZ)BiY+4|hac5|-KN zT06o~r$Ev%z9K&`CYDHYe~~3|MRwvciaFC9a;$S**yqTkM0k~sO?sd)nxGH*q8|og z5QbtH=3*Y^V=<OsDQ@5<KHwuh;VZu3JANP$tq4G3Bt;OC`A2XdUwlLSI4m$EL}CPD z56z82Rg$qTmSa6m<05Y27GiJ*ckuw<KE3*O|5ePZZ?C>x(mwI+asAt<pWklXykcw2 z)=x`5#a_aPIg|Ns^yHr->GVD7D659Ych))T$Q*HyYuP=O1g!>!Je2C5N_^FGkflwj z|5<vRcK$rJLxX(UvGxS5Di-TNzkZ%m>5phE3rmL%n^)%O<k=E(1-&F!G3uz-m=9es z9~-a>TGyZ8UnGhz5{iMChuwIO%xqN6FdG-(!-Y$tC&u9-qH!aUbKo&Y66b_t4qq1^ zIx7*{=sm<EXw_&{Bu7eQK{n(;UgSf56hJ`~LLJmaJv2aDbU`olMj!M=KlF#z^br_| zQSqgLjOL3m7>jY3f|;0wxiI^Aldo^#HllF{_wWj@@dodpjfb{zCr2jN%@dAPN<=2U z*2X9=%Ag#|qXH_TGOD5>8lf?oLL1YL7>wZ<ff>-oc^S52FZSasw6VX9H*hfC+8ne= zC}pJwUucst36rrBtFRjDu>l*g2`6w8r*IDEp-tdzL??6}JLRaM7D(VsdD@Xn-4owg z>$GEegf_X?6KNAH@*FRaH-H&K7{XBkrO^WeFc7;TiFrJL3NNHYDilNrLQw?aD27UC zf<YL9VTq-LEaHnLScV0GbP!dNinK##Ohgo>28m=$#$r#-tYaQ7AbScPE1U<<IF_ld z1kMg;9h1{)ebL%&wo|LSBDDJJLTf|Q#Ck%9pL4WTb0l;v@bu24IIo>|qz!0FSZm^N zjDXg{<@oG8d(08w9P`TI>kPZ#SgK}A<m9yY&g35*x1855I@0=ShpoUt98T=?`^1tN z^MK<+V|#COKEC8guD&x*y6lMdJIrxM@EA}3_wlO&j7m5@&r^<jh95}4K;=e7G(i>y zDbp_lG~+*m<jix;ab9hb*tpPjM|4CEMlC1Gp*$*}3aX+y8lx*FV=Df^CTu|@CZrTO zfE1~icBDcGLQx3eD2n2!jHVcjAsC)Yf@CpYEWvUN;^}M`Qt%j-5(S-eZa5~X{gXL^ zZ#t%`0fEj#Hys61XtS-gtr4{LwS(5iZqVBK#pyr8FTgqAmXEKq<Sj=vby}b?tw(M< z^2OH<nFc4cuDI~Q8FYs!%^K}Es!mDr%WOW2am4f2j@XI|xP-y_(G@oO`8tzbi=Dz* zDcUj9IdG+q-?Y09FSS<E|IU=ZcKl_0!k7R1+*m>XJvWPX{8#ufz-dqnEzlREU=F@E zxRsn)9yo5Ohs^UII--+SqFfvFde8>G8MMJ4fiKReTRv%>MISj@s9%z4<C8^kUU}?D z@25paLYtWtshob#9PibClm9X%VK@EkvBk22_(~kY5#zWcDgM*^TTbJ+BgBv537#3p z4NLjQafQY5jQDd18ITZpPz&wR7iM-8BQq+32Z8_o>EoQZkvSh@_fBklc;)D&hNt?Y znh5bO$f+R+MG=HUyJRIa!5|FAd@MlUv}8I0(y`AWCvqV-@}mGkPzrU>8+|bYv(P;~ z$&DY7<QcdS5+e}Fpp~UWRup#5dE+Rl-p}lO@W#<fZJOR$>8)dG?jH;b4+`;H4J{MH z1HjpgF;c0FMSEnBblOm8ZLbTh{Y|0uVTd!}onxWeFSYAGTUxw0Jlola5Y%2`XdPUb zM%$ads=d<~1ND*3Xd!_`*n_>s0fo~3XC$Nj_7d2KySQ&0@cx$rvfn500H5&%{)}HR zs-Pvh!yH#_>`FSbe{)<>SEn;7`IqD^Nx3$rRiTY*U1($54`%XyCwZgOYaOhp#QUCR z6TQ>I{h<y2>~u~)tM_~LZifH#?v}IDqo3J3oA?}T!w%!PwHg1@$^RU;gZNI|#BJla zwweAoj_kcnJQ{ED4&F?6MwCNibcC4-+HC(H*=zUirKZpPM>VO$TRSz2ku3SOgh3HB zL=zZ$U%7bR+?%uy)jYk+s!g)E7^8+tgm$=gXk$cR5b9=Rhd=}d;uOwn-)9mTjWO7U zDD1~^T)|b`#(gZw%#9n{upOsx8h3FIpYS;|o%YSbc7_y4i5$p@GAN6tXok+{f&qxY z1Wd$YEWsvh#tEE6G-B`yuVKqdE+7#CkQU!QxxPERRmD#msHVmU49@T~N0jEy`JUbh z^jo-*B7-?(2<BmdewZ4Z?T<NOBV0gyA@<{-aoqDik0V765<i5ixQ5rzUjOGnNmPe9 z8QMhrA1M-t6j>SkM{@$jTRU|r<E_od8f=6%FTbRQi`3Yw#4%^<7||0rmDw35f%gEl zWp-y|BJZNEiwSrZiet{@ZH|b+U5-lRy-=y=oRq-3nCo+pkEh~Kxi-)5@ByDVrkc+p z*Oo-yWfgy8_Qi{d@rJL{Kauw$<+~9!b0P_$WJvKdte(#0q7`Kne=}FI5DP{QJw89T z5jS(F1hG;mqsKevG2&)!H6+#;P4#$qUL$ViTzg_2(OHkj&1b~TT<k-v9|q|0d&JMt zz1S3KDLMw@FhLJ*$#0x)rtUmq3$a*_4=><~TxguGW%N31z$QIhv!HRhndyg#9m5Gd zo<78gn=9Z3v0I4N<DZTAw2a=KUe73hfmeF$Sg3KXxmpxfhXppLe`fDR>a0RW++0QR zh$TQGJ>D+N71>E^Iz`&zN`cf!tA|4i8>efFE*<hBKMLw`zan}(!i*Or7J~AqfO@Ep zHfW2U=!KyehRK+Md6<vYSc6Eoun+rj0w-|^m+=@+@C9G9YP(T3b|VBJG14F{f{`6z zD2y^Fi@K<XzUYVXn1Cf%ib%L{8fS0^ckvGIVGU-C5f|}-S>I{-A|3Lh0Lq~}>Y+Z` zpe=f#H-=*brs5wg#3HQ62JFTjoWf~b!BsrQ6MVtPC&quyQDNRCofE^neVk{)yo3GC zX(+|;ltp=cx^5fO<!??;O=5LWPmiw;cSX)LvO$}*=4gdBdU#M#BOA=w>`JUVdg}2i z#f-Q)%L9oG#!x+;s<;t1XMY^AiI}X%-x2TTqbH-56tge~^Yrk+62|FfvMeXI607z2 zw30^LOrnj%HX~Axw=Cs~ykhiD%dOpr!ahBmue5QxnR7>o9Rtf$TS{JK^!T(AEW>k@ zU%(|jcFl<SoB4U4*h4(l<EzRV*EaL^J+V(<C)cjsubdG#@>#q{F>kQHmLp!iyb(9k zJRY%x2+-p}6^yu<{wav1LK;2((u|wSA~Uh92-f3K6^--F<x+rHD8lskq)JBITt>x- zl>!^I*1jf{jkvkIY7(oBx_Ufk6(epgyB@@Pqpu#fR&_--@UEhGjiPKU#_Q!5DgSxn zFqh|iVvDduk1wre#LZ>9f!Jm+<yyOXRyU@cB5gGv$4Q*l!=-8%r<<$%Cb4MT(c=L% zjkvk`UlMzRcY6GZ88>%@AH-A^rq$`+f$DeEaz!4}GL9l`vxo(M#MQ%NYa5r>HxYJU zVyVIItDRoIjuAKamR!X0BEKHbTGtg>N?R`!X<JSyltDQ?{Dbh%!85m_n#AgW)vjIs zOg&?@Q>5)sEzk<Ab}hW1zHz#_b9E!u1HJTkmj*`M+|dRT8;aq2yl6usZtipwiA}~- zJsz)-D>At;INAm{7xS@D58o&Jv-Rf2xSH5ntk>g_jg7duVQwe36T9{Jh$gPc!CFck zrR)Sw>E*SW8t0iC>jh$$a7B-2XlBIC4fh_ghhQmd!}7(9n;Y>5VxPcL*5b#T8|P~q z^jCOh=jVU$ar%!XKD&h;k1*pt#C#EmB*=u!2uD#gKtpsvR}97wOoJ0^uok<q2j_7C z_wfMl@E(>N<R#)GK@M)2Y55`@LJ*3IsD!3yhCb+vaTt$<ScENz#7Ue&G-B``AK;Ob zP9q7DA{g0G6va>t)pK&oY{?g`&=b8d5~DB;PAtJvY{Vw)!+u=AMcl<byu~|s=HiEz zNQxk2M-CK55mdr|Z<+n)cn|S62R{J=6o5c|lG?X)McTEMMUgfq>5u`L^l+h8#vGe- zRft$&gzNEGtzD5hwA7|Zo5I?thX#5$n()umHm9~du}<is$2YVw;^veOAT|(#_4wen zM%+w=NyMgNnjWv(&WM{SvVzzutkL7C+Z%B+b+!@P36_qQqVI_hHkz+x)G3_Bc|Cln zgDWzv5!Mnd8h3GD4?8;=S2q*z6|py9)6}lss*@2n6Z1PUg}kvi{Z|vu-`R+p2^*VO zT*TMojxMgq;o96#L>@~Dqz0R&cKUU~KL^)L@4UncAViO^?rOx%v@c7nJSyt({@skY zxf~i0YYbj%XxFdM-H4mZq&u-*=%dGz^>9Vz(?*9PZS{=87>v`yuL%Eap1G>#5StIS zJ?-*)dm3?bwXG+%30w5|<X%SHT!lx79mh#M-n6$7H&^F%Vz<DH3GMp1`WSI@)xIM3 z7Vq`At*<Mxi7~p`Vz#iZZ18aUAL8^&gnu^QT;vIfB}NiGzO0`SHy3|qVp+k1hIW3h z{zlx~6vBuVK~X(kdVmo(H;anIs-T)4PaI*y^-YAIln`r<mU{fD88`QquEe^7M^vr; zodb>Y%{^x*vEdl0$HxtFMfTHXk0Na=nvAJnWof537;KzwZcz(}EdtLYT0GkjJwELU z&xmU&UyqG?OoqB5KN*+ScC+1x!ahBGmhjJ!HFvo)#LnS@9$z@jh?~3LEn+datH-+z zcSQzi6GxG@DZa#Oyw$_SMi{4?o27-#&<;<h{~cN$f21oiTsxg2Z4XU^KqS?}4+#Hk zow>JWCYBA^^|))45jXeTg2W1;upS>d+K8Kbaam#&P)U#19%IC{J-RY#p)Ts{@r+~j zc!U|RPpkntp)(>d5aTc&GcgM*uoBy_9Y=8tH*pL1a33G>37)y>KN2GlnUEO;P%t-l z&C+~P1`W^<ozVq@Fc_0C8OyN(JFyE#a1_^Y9rth_FYyZB@dLhjcp;0V2tpQQMInUc z;jUScFDjuC8lxjRVE`g98B?$n%diEJIDmt=j4Oyn3|`|6)V!>A#6x_fMLOicFL%wa z+%?U?Z_9vnKqq~Yz8aI{Z%#^IV*L@J$4`vYCvn;vR>vsH$AEoN%fC6}jRY_!a2m1c zn5oA*Ofcf+#4aYb3@h|_*hC|4PWTpLE^O1|u_qaEGZ79FJB*`xJjRTh338R#b==hB z8z;LW+i0toA}w#CaR>MG@Q^94$mK>@OQ$z@kB@q|+Ek-<GtI2bv>mKItIr}e%|FKK zqe#oXcu0iAdiVq3pR3Qz%Cy8XfaekI^uyEi_%w%)r&k`z^Pzwqo9=W)PSsjQ5eY2C zQ4*!~aO>&DrAt$$<#lb;1J5ejr3=h3;%2_LBi0f8XibZI&otuZI_OU<0)zDU4Kr@8 zk8#8%V3HnRGs`&NTsI4eEyZ#@K47*HH`mivV%xD(k5`;y#LabffY>1%(c{VI8gX;| zT_Sb`*Yx;nGj6WSXkvH3#A^N9H_w<@inQhW6wmQe4^NrDB~sfpDbW`37ktBaJ=$!6 zQMtLey;x`7@OAp9<l?y(8gX;c2M`McyRH_uFEZlhW{`ncCS=j$m(94jN#rLMf<k(H z`C{XIee>XFLBz^~XC3YOy_Xnqb5E&9tN|M7@iI&G__Sc3&1&E>S7fjcFR1!(KtBx7 z4|+!V&mW#rr0qZBF%kSwN2_Dka^r_O6lvSiLM+BoJv@Ge(FAk5+CXd*c;3-YZ@AKk zo7-3vv3)q8$AecHadUe+N9-al>v3hZ5jVHJ>%?w>=OOL-=ZyHY!YrNVl)uDlJ+^3# zajv;Vej_GqhpN**oO8RaHR9&h8Jk!f#M9%&*BNnhOHD~EHF#9j&QGvjk54N_-8m@F zg*<xfp%L@fw%@!6M=_Mp<6AfA=SG<E62wZP25O=?TA&-cV>HHK3Z`NeR%18z;5;rM z26ylVZ(+&D%SOaOT%<rs1S5MsZiq$rA{>=a84b}09nlF97>F?#i)nCTF_vHxHe(<5 z<2)|lF7Dwi-ocumCsD*jJfuXb{6)Dt@<ld;p)hKpHaemcA}|osF$2r69LJHQfVP;5 z)b`oqZw_D;I$aGl^no6=(G}T4+dnDN#<ek;qPZTfv&j|NLE8Z+(uTVex}cjL&a~M` z0dpFL6B~)qdi<LiH>YPju}PSs$4_o?MZPg=*Jf=QR$!GLo*T*KjoP)z+=`vpt%p0h zj2ChgX>)uMXTb|OE&mE{HD1V3q)q)z+(wKZ_TT1;oNHWM%ZL|vg*STm4&k3SB{Nfg z5L1{aUdJ`#>YKJ3aWjMbh{Z-6Jw9}YD{{QnHHx&vN{VFQcShRj)pr`Fn+cbRSXS^# zLW`%}WyFIiBM~J8VJM=<KbmnfKg$uT0G>Ft^N;K{&aXt7mbZ0L9}V^Rj6Fu&%;&bm z+M}Z$Zxf|$hkElnQQQ~(!LyEb`GR|m)6MiBL2MMp=y9KYM%-K$lZj0QuQastZ<=v) zxy&cF5R3Kr+Wp4woG8*((K>9vCOsT+z_`4*x^@$b0<Si-%U3#R#LZQAir86@8d^NX zAtN;?(iY=w#DEtYTKEm&pD#8j($?rpyvAESy#KIqb#v|hAf~e1tWN)-oIdr4@pDm% zv?U!2{)nrGn;$h!H<x-4vE)dp$MYOB;`$cAZ|8|+MpixUaomWTJ3~QYq2Q<4TJ=}V zxVd9gB~}Bq^!SPs#`)$>(uP=jF!kE`eNGxvPm#94^hJL#^;)>>DdTi=<C#os8m8;< zB&S`G)wIl^NZXI*V+oe&;pc?4brtaEKDCRzDosJ2;GDiIeFB_07W*_%cb{=`Fu&hj z?2}1JtVMSsO9*3uFqA-r5a)t<z8Rd`miqa+DlPR{uSA%KR3uy<4bT}~&<nlM7n3m^ zGcXHluoio91jld#H*pL1@erT!1z(|tGV_Rs_(&hhZ6h0BWJggHLvfTt1vElqG(l^$ zMSl!H1cqZI=3zdTVFmUe3VU$`#}JJe+`(gffW1&$ejZzh=P<-VMzF7}@OkM~fd>B^ z6sOlpp9$)wv(D_teR8@^uJp;N_?si8jgmG(eO&&leG)0^!gJbD37kdNa3kqMz#KYl z*mwoA*5{lWeE#Q^oLniEGu=9$t6nn+{v1>7fTYenc5go???0Qaz5gtZ^H!vfUHR>t z4L(=>{~Z6LMhog)_@xC$xv(}d=7c=ZTkz!PF**O+0{;gbq|KH&OKjacea<Tv|7@v+ zLHjv_PXEpSqouoP>7`%K(OUY;Z2z3>V3+?!ZLC)RJkl7eU@oj>fjRr-wF=Iu1up-3 zHO9)nJO^p1VWtGXq|gpL<91*h4$|_)%##uNfi155dBqVNq$QD=K)m44uK3OEz~vmI zWtW*%ykgW2oP71qD<0(_E#=Hqd!iqh{@Nc0I-YRQQ@js#I*#~URd@e(gf@8ZiRziE zC#j#y|CmpZqE@@EUF)>J-!F-qov(8^{rAzPQ$NGM%y2|7LG6H?2uEp@MN_m!8??g+ zjK@SQ#Tu-`0UX0|oWvE}!fnLh9cqTLb)qx6U@(SYL>O=B9?2J@FdF}08l0Ge?bw6! zxPdr@xd$K>QX?HQAR}@iKMJ8JYNMm`<|&^|>VRnH<kLPK{BzKjU;A0+=b$LfoWaL^ za{ZF^WjM|p1FipU_2a($d0bm!zmClWeUK;K{9``-Cvf1e1GiQ`Fzu~B4_wQE=BR2T z%CDBSY1{eRfqQ(e#U^Hswl>ndSkaEFa{G@9W{4(ePJ=eW=ICl8y8{<+5uVNrH+;6M zkAAzrO`ogHJsC!A$hF}-hIB=kJ6uM=aAB-@GJ*?ni;*+f2G8O=Dd9OPmf)TMTS>NU z?15(~Ru|Ue%g=Z5x_B4wU?rj>m2^T+^g<u>g;t?I6>6168WkSl^HH3@DV#?fD%Tp4 z8flOo8IcXGpf#`$`eFbEVi>l9hPRYsd~qD7a0VCQK`*o(1t2k!A{kPn0kocWLT7YC z5A?+|Xe00)KcF%SR(O?g9*gz~D!;}UnLT`t!hRgYF<2QTZNw5FArd1AQlJsEk?ex5 z=z(6&$}v9cB6{&<f9!@f&{3GhAg{v)tSQYxFGF9;@^h97JU5LeLniTy-zgk3m4*M0 z_UeH}dXZN_mpL|;BI*4VNnKMBkN%3Z9;!%{rHb6Rp-A1EiVTcVB=Ei>MM_#^N=Zu< z+1A=3@!D7<q`gJD<3u-$1a!B^@L3kAH`^jFFno?hs;#t0u2mK(fPx6Ynl%<Vhc0QX zau^pgStX<E>>ZzMN^31sv<{rZTa=(9t8ocM=+GWip;KG&1cl16q2K`ulxO$CT@;|x z<8c=SD{>4TqHrZP9(-_3yyuftah|#7lg>G4h+l~F@qM3!ZM4u+<gd)>c!aW5cqm4l zs*D{xsxd9tg9O#t9Iy|GYA{teg{(E%_;4F}YcU6Sfts~xI^xuEO?u+PJGAFNq5j<u zeZt$sslyE89CFs>N1}LuBK3H9z&BK>&yPgl-+*dy6sa4s#t@AnjYtE$L&e5SEgVhA zBt#*gDcRf9t?JGcA4jTY{O%rCk*7H?)DeSxEocs&BD5vHq{k;zZpGxl)|y|vU>6d% zVUge<lC-5doJNXvY$@&Bsvbh|E#zy@3m?2d<qrJ11U?;kfsH5xbYiXHEOK<FX}FKV zU3e<RS5)rG&kzv18@oA<AXRrp2hX~@RsD?OVm){(C_bWGPkxJoPpH|8frdwKnt+{% z(}x=+qL8dFbB#;L*^l|fbCmASCJ2uK9E(Fp5%F8qReg)Lj$l{9RfG;CIq?d`29cb2 zhOog*C7vRD2tNwI6BHiGqc}dG)G!7O50G~_cURm+i4i;%<I9NOYSyys3&piZvc}*! zij5M75jdKu!f^zRVG3~q$;Z-ETtM(R(g0_WY&?qqi}4O+C-C-cyhfpk%+Ex(s>f1% z19>OW8$=`bWS--38!4yIG>pR`B%jLbEv&_Jr22;kKP<#^<eA3v9S$S8Q~OyAzvO{s z`fpWdXS}ELXo4BIjbt;ponancA^%KPJMJRYENaCXc+O_i$1FTWnmG&@*5E5j&*hr9 zk2Ldm5}Ef~&DwZ(q<9@1^BFJ9!E>ZrK#pP^{zch^RD*}ezlfjy-~s{{v(m8v&roCu zw|6{4=u#dya0hvoxmBHK89$-LDI{OctphutuHa4hn2z&Ezmj_i&Lj0I?#Vccq^r44 zU<*E>_!=@5_mO@rKTpI)d|vBT^=FE6uH#bJ1zAs(n25{p-@uzcFblVkeIr$29<;xn z>#>QXM<48j=Vp=}BXJaows1UFZE>r56~(WRFOvNR7m?A$sW^kct;{d>A^A2Y1*`E2 zg|?GXI0nBR{00Or#M#N_f|+=QY`YlEU2awPqWBa7cXPkSaU|M9THpvIihB|IV;>xQ z83jzlDa6{xO$KxE459m(Bs@T&11xWxN1}snRVO;gsaS#cD0qlvizs*>X7I5bUr_uA zm%>$~J4%nS6CV(IjNjQ{FTSJHarQQxL!uL`u@i1pH>Y?DzM|MkHY7Ymu2VDtrx19W zLC0RGXZRHpoQOfZvkWdK;X0C^qZ(|6?|GIy_Tt<5->UXvSyNi#0-FhLAoE2UkL~ck z#AbqR@VLwmcCZXz(EJK>gREES96qDjHF^Q{I*SG$(CG$SF7n>|t!5`R-{j>CE+Y9Y z?o2q3(A(^Y_==j*^Z{Nm+<$Qi<?gWJq1<Kl;~WC-v6OHfh3>N^@B_^skZ=!vt6AGn zW>WkRxgPSv2gIPvBUTs!9<!U`1!_KF=^^b?c2wL)`e$tNxPZLR*|6~eEncuQAl6H! z0yFUSrCZfsDX#yD*+Amgi~w#T_zh!)NF;d6Qw**k+dHbj3xvIAWZ?CIV{rn7KC&!v z4oN<dEr>?3&wp0kw%BL3PWXHwmoXDDDDsv20luT=HwGMW{$+5n7s<c#?2qfn`Gcgx zH`EhFwjqI{NJkt%B2|%Ls^U!X&}WYJTo(EBxvVWk@&?5$iY$evRgosxi3B!9nqwn8 z?26RGL1gt%WI9y-LRTA{Lx>mW;{|d#6zPY3@bgxr78ZKDRZWq+Kz<)Z#^WNA`6|*B zEAbu${S+C3efWVQJjsv4Y52!hq&lYKKGN}o-vaxQGY(b45tk8&>sB>Ias#E~acP9b zSNOZvihMzx1d7~5>x7DY$J#`UPJkkj$dp)-`A8JVVB!rLCSe4SFR3Ck@f|IK6xof; z$=s@@NXFt7LX#^p1^1CVg(4lW1y4{oB~{=sVyB{6Sc<r*6&Zn-sGmlWlPH{)<4`>v z6NIqzbSJ%A)fCA)l**v+w}cdVgn}6rS%-|76qy0P%v6gX7?(wnlvydq57f)1@D5`| z;s-PDI0S2Ug?Djs46Yz?4hB4jTh$ct4lYH!aw<|1GjSRDb1CA4<W^)P{PHL=8~O7x zsOXZ9S8e&pU^FkF$X#?QsK`e+Lzuu&g`apTGP)3{8>aBn7q_Y@k|c%6Xmlu|NWySM zE?`nono^8WK$GH%JVm<_WOYfJfKsItxr6?t75Nuq%h2<(#E`8V-NDfEq*?`X37sms zRZWpRLdQyqe8%L;WH|z=FrSzMuc}-c$Ka?&k1!o?5msH1K3I*92(Q6P!BwQH$s)rC z6t3k~HAONRPf)Hlivk7ekj?O`%fR9(n$=U}8ba!m;mF;9c|~|bMRp*6BSns)aAQUg zWtu3m2??7rGPvK=t!j#-Ml&vh0?id!4yA=66A-^83kca-DY6T}tw}}1Z==X?d_e2A zid;wic1!>ow5J-h>%e}2t{q874DaMtHAUjvS&@lI&_$8O$l8^xMd5CY0!nvh?oh3V zB9~CBC)J^GFGcR5O>ae>p>rPw8b$iD1z{hO_ha$lU_ZC2DH3~sQVJt+0)7J&sfY=< zfPe_9!3w-Wv4LbP9wFZ#vKZHqbuhg{G>QzN8?X&kq!msL{jKVbzD3(mnq!#4Yb7=$ zR2WXiz-t84i@iuUQjsxujT)o4J0NH@8H6jyGlm@l>R8Uf5u_hSEARlt$FrY~|E*?j z*KH{hWr8A&unS2hDlz~!P+*cGv+xe(C$r1Ie+rq0^T;xlvBZ58`G+*X57eJVCc@Xr zK8hnqKi#criexmNqRb3MR>3xt)8Rt=Sxg~LBX~BO8J?i@9D0JUs5h5pBk4Sn8JCc4 zKI;(=QEY)Cix#+5O%eBHMQUR`ycUr)IEsvmX%-%#)DlG&;1en@Rb(rYE@RigGgMiw z$aW-O!9e2?%B-X-@L8ou_f>9HQzW-gcs0F%=Ni@p&LP)YasVGta~*?-gzNd~79OI~ z25#kuvr&<5xQ0TT$S!zqW&^`zglwVNTimLqNYqGf&)APtE(QwkQDZBEjwIU@iNHM+ z-_E6B+rie2{YbTwbMO}Rb}{%!vYWxj4dma$=C|j!sz3V_ZA0lN)QF-}h_{!W9EXu% zALETjD7K$L!8cSpz+MNBgKQvhA>fcAy>T5OhsjQSL+BAY49}y#)vP5rMbZs7Q05q0 z9|DiFA>awBo?x3q>XWQ5yhWW;ibNslX*z~GD0GG!2jnb+finm_N40RASER>zx2h?U z^T>IDF~M!*zDRHJ5XCQX*Ts93xy<^(dxT%%#saUatV?Wz&oxE?+Yt9U>k3Qo2$^oU zRZWp}#&rbVq(@kcdnk5`Jqvdcd|Q#eID{0@EPY%+<`~idSCRG(_b?nnz+EN|#}IUn z$++iMHAQj=iSH{?7X7dWw-D<A>j-0T0A3HtM!4YnNRjq9fy|FN566+>36q6;DDjk$ z#AB3v_FL5{*hZf*Zup4u&p8tBQQ-xf0OTb(i*1PWN|Ba0h@jVs^uigWeM8N-h^%kf z`0*O0-?8aKea|)C|5o!DYNm86Qhs0v@dy<@a=%5sPl_yq-)E)-CsFJRH&yt4Wn055 z)cwYKK*oQW9w^^=GQ~k;{=xo&M?Ze6S<7#V_}6+=S%tWYD*bR7!Kx~g@D^n(s_aCd zRh7PoMtPemN08O7%0xUxV-HmhAgw25c!PRgs%%4$L;drW2Sw5oSCH3RmAUwYO8on4 z>tXjLj*BShr^-5b$5N#O&LUfERYu`4!u?fQ36D6cw8d#;jjPH8yp8KtHARv&o+_=e z7lHAq3g?kM0jJ?P$|h80Bp#wfB2`A?ED{8$QWs0{8W|I-(gurh4;cbgX$n`MTh$cF zcT`Qn>G+P2q^k7CUi?78AXWO{0DO|EQWNv=3dNGEG9FiuA_cw07W_b|l&Va|B?P8& ztC}L|jw{HNnz_aaq)bCOjv-lEReInwGNe;wC?29jdL{^8P$L5q1n-Q@Id&j^CRN(w z5Yl9JtC}L|kE_U;g&yDuie^=1Hr}FIHdQtvZm=qyaRIrqt1=DmQ7wlm8xSiegNwaL zl1r6tIEgg5Ro<ZPRy9R(6M6G6ICzBcyi|*KD4$Q2)v)GQr4hCxegT?*V@Oqy$-s5w z4^d?%KA~<XJx9_)j3llXa;usm$rnZs@C2m_tFj2+(4dGahmk2<l`(jYN=4}jvK3Qh zI=-P^aaHyqRS8uF<2LG*WT26^6xV}yX}78=lHRz3(q&Xxi-59Jg->W)PL(q#P+paV z@T|b3;3aBSWE2okNtFS(g^<cL3Gu2hk$8?;RaMzj)vaoZBy%-Yrs4}4R97Vm8EU99 z4$o1wCUcE!wU`uqL*v?PDTrT(bFd6AQK&8p5=UXLM=D|<w$^j2nj(3N{PpQQcEQ?! zfyZ>*N2Z3%Eh6y^;f+}1IElE8Ni$5tIe0fwr2<Cc04z;OS&VM_Th*D^!YMrgk7gW! zX?To+&Do@I3E5jPp16uME!i=!9`6y_N|oU_g#@itX^3Tbk78{YBwRz9w!hV^ZQ&G2 z2W*F>ohs!p2QN{mJ(s~Fr0bwcODx9&r0K{8h_!fy9GzJD*n;=S+gX*aSdW*;(Z#K5 zilhfN<1GqxWvuWG?Yps8B3E}+X5n8n=%LDfr0dBT;x(%F;(P@3X8Ga~s`lZofuO#s zjKI^rZdFqx75dRy1oh`Iyg|JIBsOwJsPYfKqV+%~03`>hvI#+hNeB20VL{*_!iTD| z0A9m59!HRAI1@SCt!j$II)Zy4ZlcggmLXz~Vkf{eG#^bqAjcSX8pv4Y6#I~D9OvSS z_IW%z$OJMK9Ve>dH;K_es>$4cC%aWmk$gv+DXQE+`KgQmlKi9c%Of^2d_du8Y}fdT z22R!=GEHZR;}h!7;2JoE>!>x8tpd$vF_9QC`?soVli;)I#2k_ovF36FeCDyr@gDW( z({MNzs4@hf&}bpc2I&@&g-ErSafjCu(ge1pWEgIv>@v~?)tCQPa|AUnXGT$a1;dB1 zl`LMQTtyP$6>6*|kD;#N3W!A9wW@T%Nu*mxi*XM%)-&8lwSlFH7pSt4{b=KFHET<Y zB8jt!TMSMj(`N37xP`o1*p_e?xg$vwyhbG#PgAgNRiy<EAo(`7EZjie?Np1)$hL#Q z!i^nnRZ}F{ck&>Gr^vaB<ib(p+Rc)J*B&-wJV&!AHVBm4OO;5okI}(XRM=0JAkhJi z#{-l-$cQ2SA-Ae2l3uuiki+CJexSt>sz=(R3?}ZO*fBN~cpg`!9WEf>300i<g4!q9 zs1bOIyC`m<#AzPZ;CIHYYKo)>t|8<sw<cK6k*m0X0_Q1%-vy4t4V1V@-XrcMwpZLo zsmnYsBF+`Mf;%X6m8Qby8cn_CRy9R(9)+%}yfk7bzrh}c)5w049^o_U-r~^%scx$> z3{O!$T9q~MkKx{eiwM2Lh60bfl;JW8-eae@=T<dE;&Go=;UWq=V16MFxhvuzvOHo# zz)MtqOz#ly3G<0N2!G1+B<#<aC>%q^=d3q4UN8!H@WQQXilo*{9w(6F6@v@E*X&Dp zhT3n~v61~PO@hxmc4@ppgZFG8DDZ)*k>DebD0qlUpGY|*{!E7B(Py`+DUz~ZSa*p3 zmF&htRQSe&GgAM{^8((X;dh#dtUq`F19v)UjSDEKSY#eNRExC5d4yRkvJ4KZMLJt8 zf4=mfNG>3+%_4K5*ts0eBg}(;<QcI&Ez$?KP~6KR>yf}=;TIbgd59|B7TJOHJ{EDp z>dRYxa08|NI37W<+^VKXM&K1{$F|5mWbn7hR48#Q(hgTpIIcxjA$B~f#9fq$Z;?I7 zm4MzMFrh`p!kWk;J@EuJ0=OnJCw8lvBAE$CphbG&A*v^_NEEUqwa5%uf@lIRp>Q&b ztVWXL7G82#<Oh1Du*hwcN@<ZzD45D3`%y8qMJ}U78jHM6<5o3A(l0HSPiK*$7>+}z zo!%nP5Rt(maWYzD2_B+SCW|b>bL7ixk)b$;bXhF?n^zXug#=kG(ikqhLc44hd7I6x zYKo+Lu!VoVf>X0w<R0qeV6IU-r$x3Qb1n;iftJhXw#XdB&SQ}w_>7KuE&N>}i`2@; z+rUsXKUE@A0n!d}3o;3?hPYKtk@Uw0v<|iK7HtdfQ?<w-oJP_xi?qT<d_&Q~78!@j z2r6QcmROGus2pyQb?_`|k>)srRK<9^8Z5<stD3ijv?*?plDLYtC74bWE@_d;c#N{8 zEV3Lg5M0_K192IJ$}k7;DQl7TIElRFEHV+-kh8o+M&l{URj|n73cuB?-7_hYC&*Qi zDaT>>R<cMl?0};(;}0jUB54&C1m2-iRXU6qq^(A_;Rxbar_<O1rG`Z+V0I0+swt9a zgw?djEWAafS{7LgwKhqMd3b_Mb;ua3!3z|uYmrHKfUtV3M?6Q-`lJLtqGAKqBs?0r zRZWr9!xs28qP2)ZU}KAP#VMq0!n(srq-|=EzPNx4%`7q)*O8++DS$^P)WRau@dBk< z(sX=j=~gvGQoR+ugm-H)3R@Ak4b|Z$inL{3@g3#c(Ni3Sr9C}IH>|~Dr0l@RU^PCY zdPn9T7dpCCO_9Xw#C%{JE+Ro^HX*FQR}}5SWZ)S>y0Wa{=w^{NIF3Z!StN)?-5wU+ zuSR;Id`}V{?@_#$Th$cF6g))U-Yh}fM!r7G9bThEU*-<?khve*0L~z^Kk0`rC^>*Z z##4ku&<)%`@IZQvF9Y4GrbsFeBAbzNutlcfCbAD9lkpZIL+L4ABWxH0j!)<@oL(dQ z2+qSdv>3^DfPAAYG9R9!*>w;z+O2Aeq{<jl3w~qSH}L|M#<7ba-gwdtr;%X-DTaMW zG|?jUu@pa0Y!W@ib>yCGk&(E7q*E9roS))WHARwnszpZO3bOyhwt*|iIE|j+H0)01 z91+-okH|jVBAu`eACY?o)nFZ-BF#*TG{SUToat6IMG|Wkw^a<o3HZ+@U9bVqk#7z$ zTtKq9?0VRY?<hWx-r^ck&*!#|Bls6}7Fc8_axP@F7P?hUk(@=EMO+f=@EJuGQytDA z@e&pcP9Vinb|!p7(Pi`qfy>DUgrhyWVhL8`30@=nia)EaOOZ6gcx=UO*jHL43$*tg zSI0c0Sj8HK_TJ;-D1lyx#3MXL;A-}KG{Mx>KdY+ea?SQFtwivx%*SRNL=5a}*gjAL z%`get+nUe9vX<6jCbr-@lywX`vS1a8u4gcD2<bPl;4lD-a1r*6EG+r?$2DWVFTcHB zKhHODgjQfJAT66!$kUrQ=xIllKo4xeeWc!Gk(!u+i%7niR$>-T!fy*VCd|Nb_(Zb) zFbJFR0qI@bj<EobkZvp42#*zfc(&Eznl#_H(f@7|QC`ehq$yTG-A-0w9v-654i*K@ zBJNHG538W;qM6u^cL?3hb163C0n+W^SqL+64gpcj7d*!D;aJq)nnY9*?&aYSV-W?* zKGFe0aRh<;Ez%HCh<kvluof>7c93TsTtd7<JW^pH-k|VdHc&i8l_O+7Jbv(@!_mJr ziKv`}a*Uk@y|4qXkn1?#<2YiUV1(erRrs9bR)WDe2+vcjPt3(@q&dyq4YP0)anJBr z29I%kID6)AO(H7xvy2i3U@zVy-#OMb*5E!epQlM!g?q?+fqOaD;4yMtWGBN8d_?#q zu7{(rTqgH093H3n;JEU)CJ~itn1HK@chw>dFaviHc#ZXnnTSEab&E8@blgUw8+?x$ zh(Xeuj1Cs#B{JP&>0l%Ng-71oB<JnFHHoNfhb5X+#z^dkZwxCD<8c_V?r`J8cpQT7 zUE&yzBk;dR`eG_hA>n=Qn3#zJ_!k)-(4=O3nDpRpO(H5M@fo=u@=S~sxPhQYtSZdG zc_ezw1YiR8!~Vn~dC(op@CZqsvJ@~8XP`V|Ge<|PhQ|#)1U~;;lZZ-9EW~xBdcj0t zJ)R-&OBM(=;{!^*;z<}$c#Z6@*+8%u*OB54D-!c@1L@wfKVdt*!lUdvi;Q{qw<Zyl zYY2MJzJj&*f`T776Gss5Blip}!DS@+#B#tG?80{hf98BF!aXGTLRT>g$M6lIUujZD zKCJ)xw<Zyln+W*E2w*67K>3$_1>+F~<vUNk=z@iaLF^xF1Q?04@D{67!$9nSRk8B_ z*0Rc29EYcB6_09sn5A0(vU?Mi*C=YS%3@qbfYmA?=z!&Tjm$Qy^uT(2M!4N7GjR-F z9#$!ZY1oCgNa|^o8W@aScz_@;npBbx5ng|55>Z)>Xm~lSQUq<V5XWKhra5SaaX5$< zNb6(e7o}Dig-v*d1in_Oh~C(U8;I{`l`!<eLU>%~gDuwInnY9zp#|pPAig1WY^&78 z5NyXC1o+cr^ul~x#t-C)W0eN@2fOhB$>Lh2CI(_FVh|9ICWZ5%PrSc1iKr~Xby(vw zVQ7yvxP_nu^c)iq1xaX??C6YzxP!QftWp&b*p4R{6u|L#fnkZQvJY?J5fNw=N0Pra ziKvvpU>t>iQmeFr6Bpqb#Hio^4&pg{l367s%Ag?{VKOe`1(GMH*(i@Lh`>Iafycjm z2uSg_CJ~ifsDpu+i`B@O(kk6?8PAX<l~t->C}tvlYO54P2i!oKG*-!ks?h!t+bC?n zA!vW0?K29erAamUFe>fennYCo!3JEyU8GG%Gtn6RF&(>c4{Ca=#Kw4BMZpZDIVK?z zkMJG6GSWSqMOY@QjKp|&MDl^ZaQBx@K>O=>&k!%ORWcwW>R~Z<;5j}ceio|~KuL_o zbR0wsz9D5+HUhLjH@rb;Hml6TX1qt@V475p4^4vq)+C~G18R1w<i;XA!*j&X!Dyi@ zx?&_oVF#=^trCdxXn;PLht+tAe~~elRZ5^SMqmv*j`QJauD>-&8x^futtw|enuDi> znD;Oy6O#&4j_H_zl0~c%=aiQWMyJzW(i6SW2L&H`Nhk`T7HY%a(;;y%6f2QsNh*h= zPvejbxS7@=tI|7UYJ`K|;W=a)oS1=`nC+Z%#5b$|-qgHeh-Ln7#`w;4<A`r+C4!zw z&D^YfSo5%IPzMp%fWrvOYnA4h4m*9Th)U=Mt-ot=2~VN*Jt)6bT4Dg!V=rz(Ent;c zsDl6d6^(XOBaFie9KaLAE@+jk2*GyPLZ}V>unTt(FO<o|6l}vY)L}*zVKGiXn<16i z$%rs`Xwy|A?AM8|^T&%UqS6`zF&#^xP4G7i_+^3@^7SHIM0_S&oA5P=8_uBNX1LYa zc%E;#GwBTeH$y-FXGXIo@h@>~KIL0ZX-ibf6lGDMWie8vI2}WV5>~l@!X+69)GWom zTbhm|TNyfz3T3ULlw-q3vhv*YQM7_pwxC@_tE8&L#*Y$}x$RZ9{`#~2i@y90kK$HU zXgG>gWoD7M8jAsMQM)?Z4^q`2+wlTbYcj?Ns>SUNk5QpEcUlD0VPJ3<rR#D%#I46& zx1L+o6v-_VtxwXRZUd{FM6ZTa*T^apQLwR9mZ3@$nt@hLX(|RbV@tuD=4>-9=q(zx zWSY^l71d*0YmyF2+Wb~^Z@;2#+E^uFTkalc-_9!6FswaKH<;alyHiKT3duV0RD+Pt zR(XiYUATW^Wmg_2x{>C{(w$oeiuGVuLF1m>$$DAEh19)&t63XwisUp3_TfPYRr-=l zXx)z-?r)Xh$UcA#52Yil@(zs#TE%-19Yc!2Y~{#5#44*$V<^)<jJp#8hSLoMkDwbP z+^VKXN{nRtMXOOPV2m2g(+5_LVMNB#TZE2dB(P*WQ#XMP0l6n~cR}?@Jcv!^`41VU zPz@?gWh42An<3Ipv&z(IZdFqxC7o1_R@0e6jGSSWuUI$JDotl`v%;|1WF3~yq3XF* zja>5>eAJn56~6^c8iE&cLqwHD>;{Xe8fllX`j@y>O_7vXO2VT3G6rxt>j6bqu#(Yi zB~@eCDl!U7R$C>}8Zrq3*OKs9xQ<O|y;b%jcmq|V@<w{SiAh1G%~rX+*{y1dr2H0I z7|G2E8C~q2sJPWCJJEF;Ie@v_na3UMcj&j1rH%!==<RNvDv)yzWvCy;=CYSXf`a=P zDKy?sa}T&xO_2;k=t1TdjSsPtVC-Qs^$6LGHb<>;1rv^ug4leV(K$gG%AVxm`V{w3 zWH`-j9Tm@TGdN4Lk?9=!Au67CtC}L&hdvjqlH(!|zNmGHo}m9_dV+;lxG!9#4Ee8- zZdh@h6uiOeK<G^}AB}I3)wfv{2#sc&K&u!Y1@Ev5?zmM=k$gq#yJR<t-eZmtbf2E% zGg>}iBoO|P)I-uoJiy=+nm@M6c@%!a#)ZJAtPp%avuET9!k+U4@!YLyiX`z1_D#G; zlb1Z0BJ>sO6p3Eb3%o_+H&!`?khk<23EwgI$ornu!lVyuGg$qRE$9=eh~A%B1^DNS zTh$ba=U1Kp(d-+$5r+Ls+I%OCQ1J(M6SNnbL}Q|2lftS^)}n#MCTB6oYLo0Xo6Lic z-6nnT5Y;_wvJb(YHkspT`}6KWk$8LAq!%8bs>3FGk=5HKv*G1qlb*PTD!w+^gDieF znF-HWHtCMLm>An87Jr+pNBuZ9IgXxjIS&)#+2ngXx2h?URq<`SxZ!a0N=OqhIgw3% zU{!!k0utNg5b_5S!;~a8QIgtZ4H5?tL#|{ti9xmG#8NOSNRrYfN02)eu~cqVQ^ap{ zZSoBr({OlNn;b>nbo2(5(i20Q3^qxa(I%sjHxs=<mCW=8ZL<)|YLkI@jLz9?at%#_ zZT!DoY*H&bla<}AYKo*)4(1H`bJ}DfGUlRZNSxcoKR?W%=V9>h9mDh5<RyCMV^q*8 zzfE4DR{?s4(gkg@5d}hQvIrSN89@XTa;usm{)r%)_=VYc%O;n@h{86BRfNky!fi4V zuTi@wX@fGwY_bUjiqlkNC}9&Pf=b$CDPoo4dn7B(xrklHCezEfRZWp7Wo^<L=TN7d zP4=Tqd0LPB6>PE$Su5Hk63Hs@J+f8ia!6jqCd(1KDosT+T2`~kMbxX##GqUao1CxV zRy9RZrzX8Y##%Pnfc&*>vH<DpFcPrV<#ITRO!aIs1I6pxWGk9ApxTBu8Gww9=q-vi zCeu;33Fn}HQzoUUTh$cF;%1~mb21fuTCgTDt0jx4l}&aaLu=*{)!MLb+uGy+a<n6b zP_sP)+`%UOkh3FAhF>SX$79s&%<;(4#jR?JWC==lwaIe~?nVnSwYyC`da$@qu_ptE zD!pv-0W*8s#J3M4gz9~10&4YRC7@$}o5UT!Bp^YAO}3-KK+<@iTh$av_d#UfVAdj% z46#WRnhmwdW%M1!{0_ItW~3a!$Y8}to0K2LE;X7gM!7M}{aBmC8OJDL?s#^%2~<7N zCPR^Z5_3Pvt!j#-_hg$q!`vx0DLa+LgDL+o*VCA56m>EQ7&Dy(hV?Vpv1XE<vluZH zm`yKHeU42&<N92iM9i~E<M}qZfZ+?6jD^2d{V#7wSZI?Q*uBUm^A|JjOUR_9jOQ}e z4Pq~+!>F}_%?=$`GM=lb2?<s+o@lVfChA(&70Rr$$qP(gZ<9P5*jey#BdN3Lx0<yF zQi`P4W*WSO2IEj99d@x{ZDmK<W|Q|gv)v}$c91bU$(CI-Yd0GgQtx4(M7t=OxR)lP z);^{j^Y_z@12$=K&?Z9;*(CE}x2h=;uOn>D*mRVoc#MQTPBvlx2`+n*#6Cq+PBWEf z$V41D%U*eo9p=1ELN2g}UbM*@oV>)|d6}l7=oPMsYFFtsW?uWP>ax55xJD<gGkd6d zgBsE7Cb@mfCM%KjHc5x3(KfNi(0L@h!vNv>T~_lwn>4y_lkf*N*@F5HZ4&m#CMh1< z<Q--|;h3i!^X#{ppEJ|XnE&TCxrAab$R%uf$q>D=N!r((jeT#p^}MyoO{{uHPQJHE z$q(crc6}uGKGFZr3^Uq%p(kJ2b#d{VO}72ZIDY2_|KqoswV9?!Qj1;qUz1B;q*CqT zVX@0ooVMC!lg%!5?RMVcMa+|!7cq=?*yS7MdD|u2$1Yn?%hxVnG1t#7KC$ew4&!6n zrM<sh%Eht&`J6zJyu_)vc3Bh8&i~xoE<dm=fnA0tv`h0ucK#AM)h4#fajXoq%cvxF zeq?Bul0kNPf?CP!VoPq9<tUrNF1yhwrCpMyvP%@2rnZYcja$_eNjE%1zqDKm5$Wvm z1|!njB}oRmj7GAIcG-+{ne4I?l{4Gr0jg!O%VP}4YL{mil+Din0gmPc+a)MFT|tT* zcK&xbZdFqx8FJE6RLy0VN2rmTLB+s4c6p1DdFequyKF@A{0uJ26tK%KR4GWa(JzE% zqkgDeltOk{f&yWT1j-e*%bvn+RZ}EQi!g`bc9{)FQM;@~m11@|h}OmJ;#<Nl3lX~{ zJx97y3_co_W}?ugj9n6xrKiYJ&Ms%sqP$%$pjQP(uA*HgRCKGFBFS0FE|<}+vR$rW zKoz^BtZJ8kkiVK;ZlX(dyF_DX4ZEbTX_ph|RLd@RF`~Aew;++0=vtSQt!I}WNL-)M zM3V;0bwjtRDU#ku+Q=?@(Y&!;yqb`u@M&t7^{Cd&E}t;Fxm{wlAnQ@HCE1L5t?ZJk zHKT$OZ5VWnZ)@j{%Alikd%HZxqz-OXQzW@N+T|GXb+XG1tmtf)@?Go_h1Ol|lBXM^ zfsWl70SxM4moz=?aun@*F&Y@!o6+dQXrNPHGQJ-pg#`WWvK<WuxK&M&s1Y2FcmwUS z74-($`S;!IvKXa?khz#Rl->=q%M~mcPH#roCGAMNSVplB(QUL{ij1+#eMF75%dBzi z1>+g?33hppRukQ-rbv7yF|epMnSsUZDRwD5)h_oi@*lfoo@SSeSm<QkPN#P>=+#WS zoI~GPG;g+D;?J?m9gLYvip`@L^GUA-q$=hw<hVs{RZ}E27PFX8dkF)E#!E>VG+Rdc zq1|#8%nAk^)|Gad0iRWNS%5sN$#&#lL$;&oTDx3A+jWfGdQugZ4R)En!L4eF#Cszx zL+(v>S%iF>?YzT+o^PSIXcNf}hxRTeXRBSDaBL&RkZU`0j=Vc)HX83_QK9uNyL`u# z-86d-leFizs<j_nQCd2R4GN9+(y4uP3Lg7e!l-qCo#CKeZXxOr>+mqsiOEOoQt&7X z;~1^N^5blJCm5iU)O3mgLXy+$BxrJm9-R5DX6^1lk&HM?<Igd+=yRUSU0}+P?V?@c zTw)KzjLVGi6*e+Vzsl5IvrFphH1P)O2@yA0Lzr}n!MjaUP%hdouP`izO)=)TssrdW zrOrEa;4XU@s@${72aLII=M_B(_kcY8f0f+@ToqaW`0?)rVP>v!x!A6Sik%>KfeNk| zh~0?|il~dRdc}6dj%%T)*y!5W-77YBV7IQ_^7|a)dDdm0=l}e9z25f@b7Rh&nmcpO zoO72d6pikY2{HRVCI0~>A0;0;)AyUtKXR56==j)KPNT~cXZeJ%r)0=Kon_XaKWth3 zOki#CXM7uqJf~7du@^)W>b-Q9>!|aJ=tj@i6kzmvLxR605s{3E?|AJ!dFq3+TtmH& z99OXa6Q%Pr$(8IZSw#E$5tCK&7Gq4ByuwHaO*%Si@*0V$H1T)R<TAE8YcfmII6>FM z)zBDVMiZM^lZW^<wI(gnXtaK6@`sBi6)l>a!WvhNGj2`txoP5*HpQk{CAZKwoklC9 zCgJHd3Cf_!4eZXSiB~2~4q-`Vf|W&+Y(Hu80T;7s(mk6d=P)$8Ch2l$5{nEuHQA3a zca1Y_O(r8xZjA}=Q*4@5Qa%r%MN1D&5-=#QCI#|ovKaySHMxWu1vGh%VFfiwUr3V? zC{<XKB=jnxi9=CMrXW=@jp;u%X;WO2KM`3%leC_i4E9X1X;z7=m&Qa~nz)tJIJ4HI zq_-yfP@)ujj{2oF*^7o{G`Wpm$`UIWS5A{0<u&;o?iDmSfq@k@NmEIaXcVhVBEheU zCTFXp*fgu8vyUd{G1`~SR%NqjR85mRs9#-^PZ;l~F$4?CxKu-v+COXZ5ld=nQYk=_ zthF?GhY7Vc39X|^t-9n9{2Zvs3k<K9V$-aW_CdUill3*J+JJ~fbVGvCh?r=s$y1DI zqDhCQn)o&&3!!pzP3~hr3r(7~WElrrX;QYeCigI<jV1-#YNE9xrZBL5icPahnsv~m zOfcCA-W@f$hOkbW)a}eNws#@&x@vM2W4dXQvpai_OCh9ls3w6uG%4CslN~4&MrlCp zUVIL9!}$(`^-i&AR>@_A_R-`sdiK>AxJr{r$Q?mMBWFKNRwGw`P1d5?08P%oXCN_! z_P=U!8o`4opcpxrn8Pp|S#k(5hK!LZHq9zog0e#?94IwRlLII-oLE4!5t=+e<B^)& zMZZy+7^BHPNIgcAIVk!YdyK%bnk1oilqOfuW1J?*m^hw-HX+5PStXN^XCj3Hev`<J zs5+TFLGTpz1S6+v@&==)X_95SCd*O5t}#+E!JeVXVKkpf6@y=AY4R9@XH$CSP<r4Q z{llh1sYjzV*@I$pHQ9-J^Qc)69;3-k^qEgZv_O;T$iGmNP4I}-WCQ#cQKO*CVofff z+Y)LUL@m`M`!Y>d;iu&qqk>Sut@vTf>afKsNkHp3O^&1ON==?&=qf6x-$?^lS8FmK zUTY}cXt<UN3ys&22I#k*G}u5Iz<Hx4cC?PCV4&?L>SS!+oMO|glDb>Sgs8QZ9EZ?t zWc2NtEJEoW#3`oiWN&woY{<2n+=e`RNF(^|C5=#ZA8CZ({Z#+xbbvI%=!2TPJeXqB ztdbFj$bg468HLP8G+Bo7e`vB8WsZ{DP%c4}BWQ7qqXe2Brzm5<33A&>avNMuX)+hZ zPiwLZL1(D+P&biXOH8q8R!P`dGT=FK8ywGTG8K6*XtEJCE>h8<+9k>pI$kCMG3pBC z2g9yXey$NiD4j$-jFQ)>5Ygxc6(XA4q?WmvV$-Z*%nVJ;w>1XR)1=59O=h6rT}`$i z_8#T!KI#5|W&HM#tc0jX6#K_i*G~uvqMnk?{-oY~M$LnL&nW~iC<HGlyD0nWhfUka z;IAkaSod0!>TmeAw=84kJ3{lG(7^KpHS|X^`X~NJ|Ih45GQ|g{MVHMcT>>0**@zmB zx>!=_G7lx3beRt?XI&0C>wo{Dz$%%b>Ef>IvIf}=T~?v5S(mY?b;*`Sm-iU!qRS<V zF11~CxdAUXU52LBC38BR%j~=-y)M>_x-7=<OuDqstjh}oXVK*qM*fsy)2xzAS#=qP z^x1S-gwok{If$k?bh(cKIdw_xuFD+s&cz<)CKy<dN0+W1Y!+_$_#ct^b!l8cm%;^g z*@oGLbO|f0i(ioxn`V`4M2(`loJZGUd=<tPXOBzhvJ#a&b!NfUWrY`eT2hyq-nv}F z;!?VVme!eSNtYwIURIa4<#ZWeUYGC+x&&3!C0`|7KHx;<6q{z1bgIIh_~=s5SC`K? zT~(K*)pRLWomfC=KVkt*{fPw(s6j0JOe~;iO<k%7=#q%ITEt#$Vy_Odf(3PTDH*6s z+IqU&t(Rictdea(y40z!OOXb;m>TMG7M&Xr3+URISismO#6nYI0hOESavW`&>+%{d zEp_o|rOOsfYOPC`Ho6pVtIK{wwbP|RdtH9&kYdxU;`CXUsllXUN1aA@vRY?do?~<u zT|&C*QmY%;ushiWM?!RI5lSqeX%Aun19}n*VZ;K8_R?hs0>gDlLa*Msl<lL-;XWxg z%_@oMt4qW$y66$?4W{?gC4YZiKH}s6a_c}{%KWNJnnAh@f@Ls;2PJH}>_+_|y4*yc zNL`$U@_7^)Mh?fA;l$1eK0oq@P3NUpk0g09brd@@T9@2o*b&%%)1~29l0S;qF?Aeq zKc2Xrpi8=my2QddiDC<{$-3-C!zsGl#xGNK(WdD#0|lq+@+TtgKWteYw^+rf#U#y4 zU3OvAEM4l(CIe&r90DCpGR@WHDfZ3NrBRG72he1`F89!XfiC8Slpz#})nz;CF5>g( zyI7ZsOLRGfWlK|RnpHAn8D(p^E>{q{LYMAw?8!<hAVjaCoczw~t9c!3*ATq5y0l!U z%VRWKPx7Pd1~NJNY$R6Vsa23?lg{9~y0qJ@OTy+9n`V`SY$2Cy)#X=Y-9|=5v+ZP1 z1n<zraVKAibi3Fzf_AfaXt{?Xi;%s1exEMOQFFg88_@6oS>Yhr;}F#WMjcMEX;w*x zBh(n^_Xi(2%107(`Gon$$W_M)#tCYMlLQ5xr>GqecbWolhTND)(9ROUsCQ16mpE~r z*DsJ57bz^4ba{uw%PBU^Dp_zv7vHNCS=7EpjgX|vWemKoOSK#9(M@6m?zc!^tiDY! z?@-L|Qhg)t9<g$tSb0G9M2?5L+`+0xR2PqR$?$~4dh)}jbCSVXTlXoY7+e0NntVpR z_FR`I*!V)1!7p|3e?`Vc&}%X)CcM!Z5}M+L%J2AA)O=5<FzN$UDeNDq13$5|@cm2) z|NO(2RR(93>`10E5W2yc49VhP$QvX&8nP~xAs$W!Lns-t*x8Wbnj!6VLwpQFZefqv zkeJkl3{GQ6OBaJH(S~%k7~<^8>)2!EbvHw*q%|aaI^*w$OjgMUTu5(l)36~=a5SSK z%QG1=I<q02vKV6i$&h<EkkydbZ1mjAZb+^ihKxgzoCa5-4Y`W=T!u8xZAkGvhUgxK zTu1%9hP=k{d?_}~Dp{J}kjMgtG%sk-Thowpg$!9;*pM+r*vq1Zn2H$^iZsOyxs4qq z3}$&Zq_mg8=spAsyS)wZDrLx7{9c-1mocPWSwqT~BUp$ppJLOjl8F@z=~~f{s+9;S z>Qpx5E$mhJdLKiUpoy;`4pj}A51(p=Ttltu>=CB<8RG44$RaeVVK79rA@fkVrXg2Q zGr*9S0Vy`kDw$G?5Z5+jAsW<S&k<eMkcxqZTtba{hCIilAVW&jXY&YZV8}<zZpfZB zBEjI-m^8+)CTt2*n)1EP3^|EP%~NceRdN{vTNv^PV_O<hsFfjyQK~hYflC{DW8yY~ z+8VMQ1>3Q=Sk>N;oE;1)8_a7Rc@5J$8Pc<}AxYTW#gNHe4QbIW#im&$2eGufA+`{* zNhtqgWe-Ef_cWwq7<=E#kaXd^j<&rGDbvRgOJDv+$6pNbk01y4V^8r%e_kIz48nCF zyM()F@N0@qvr0-1BIjcGU_*j!hMd6aA>`snve;14A9aSY2go~|h{q>%9YH#dG-L~A zjiPXlHslTtjA8S?8Iox%1r;5l45>CQ#im&$>oIk_A$=wgN!T^fpv{$Tt&<IThE`K3 zbZ9fxkU!CKn!%v{h9pcUE7=X^yXHG)@EtSBVzUSudd)WE2KvpRn`|@*GWUl~s~_QW z*<pmvBQwX4nGrVMka7#i&<hRefn<cm5&?_&MqEeGV#*UdmyjLcwv_UTXK1&KoCV+I zhO9xZ6@+HR4_j818LPw;$5-Myf>!dC@La`L!tHmy63@_XHD3weHGCy<t>r8630>Eb z9oCa(D7L|n^QgYjkoy=PPjTOrV$-aW8k_lQOy6Qi{;g!rZS4JazG{adn=pMR-Hdk` z5{JgSDZ+b*k-fYJW%uzORM=1aWB36>vK}OP@d{Cg`2R4K<Ke$=I*?UT?g-U18vQ}? zpvO^zkxdL4nP7bB@tp3MA%#&HjSz}~h=l45eFm+LldQ+Te0^8@qoEdW`!)68KFpG2 zWBtE+O2@H$2boWBxIiro!z>)d6?mUCq#l07DO`c~DH0tcuolN~AFijV1JD5Na2||I z{_nqMV&A&hlG>hTgk`VYXM|;_{rCurr%k;t+Zm1pxQVBzlt@Y;1W{OkBe;enq&;g$ zLv%+pR>A2UsgF8Xh*fYpPtHJN48uHZK@$F34{G09nYbrZz03Im2Tyom86KncMG6%5 z!gR@yd}xXun1TcFzD%rP5{}~~@?D{dLOV=_!&Q!$sD<9pCh)N6s_~CE6nqU5uSx>$ z;vRmw#z*lRwjlu?NgQerf;~up$8~B%^u+?~zy%~D?+vOR1mO_U+%#kmPD8uNL#|u@ zEl9j7{^*DCc!A8f*(+>@=?;5}LhwgR498r|!v-9}d$`@@SOG6o#NT`Jt2B$B9^>+p z>1)?-vXYCv##OV6ea$#apiOo5cfV)ILu|ZHk$7N8-G_#xenghWxW|SBK4CLY$xayd zC#C%vuRkY|Fy#dY^Oux<ta!yS<28q?H^dZT-tw#H9YK3f<$}W>h^3EY`A`2nD`l&n zm#n1T^%#pkQ%@%oL1LDZm}W9dGY7L|cQng&j7r7r2~K9YiV4nUsjivj9o|FT#^8ZQ z2!XntVJVj3A&MAg8Hgi@pB&@jX0k_4ve<0u|J-J?^u#d~Pi>aLSc2!Mn8wVlU2GGj zUCa`Lk7#N!%Lb%%H8T#TS+*mK)lAO>Gvi>IrM{b4Hlk2kvqZxoomsjg5mnL?=C4Kn zA8)!|+hH)VqTaOvMh3HV!2x8-XqLV>jetyM*^P3U%@T*=S<JEqd4FPy$e5K_!a3y0 zW|lB)g>!bZ)WSq0;-?&DX#*{mhle@L|5(7j28mb2E2mk0!yQy}H_KeSL)~0vS%|l& zliMr{@CJ3con$eV;2e^X--Gq&i#gbfWPHEvq$9VUe9z6^rY{qT+H0pzoy&g8ZYgF{ zuXe%+B*Mf^DnS?rb;C;5{6sZ2qI`j`H?Umc*}tG!B9Me^h4?)7pm1Tb8TQ~AnipXY z@d6%2`CfcWE|qBUwi%X4lTEEX46kBj9-N1Bah5R`S_!k1!8TO$B#CeZ{$6Goiiapr z(kzp(69v4@(geHkCz_Qa6nKH+rOh$}iAb4o?008cEVk_G#mZ&K{YXTrvSwxwCNCgw zIZ6*UAy;{FC${1Z+E(B_aIR<;Z$#rLN>wsTM;yc(G^=cuaGb#>w5eidy2bASik}hV z((LQ4`rpE%Ud!x5352h&SuP^Hs##K3BXgj9bxIY6`H=_x&9W9XY7j~2_p@2j*Cf1X z6~Oi}xt3W<)@I+(yACC<u31(iFwiVF@Jl_jI0gOZ@Tk|OAy0j_1)m0HIgY*!$qtRE z70{qDH4Va=P|7i;De=|JEL#xR+$^^-poLkiExG>*d0UZSXxW-<h440np)EI3p<X+) zyu{Z8OBp}vwVCZnvkqpth2MhB;@Oe-MZZpD<IZFZwC_UNbR`~9ryE%m)4Q9cY>1i0 zDYFa;HH&)>v+P6Ho@Q|gWB<^gmswt6S~xXVZwep!_xaD^QLkm`%f6!dFJ}3G=m_Ge zAMuM3{VBKus6kO<AT=Jmf2Gbr@j+%;g!F@{d9e%aY@`!x7>&Q)LpFo||5BuwE+;-F z#-+@+qP}O5rLwPji@MEhHs)Y1=3zb-U?F0$2&Zudi8zN$L(Ed!?z`A>%i%+kJ^vER z1)KVcXsEA<f%=N?A79M!Nt}ZEinCB(a~`SqDko$>MyRjOjLN8j0MtTl)InV|MKd%< z3$z+yu1g<Os&RBh2tv^l^RWO6aRh%L3D<E0H<2!qs6`PJMR9w=QcHPTrhsjdu}fyZ zR#Gh>4bwbj?4s6G3rNqLl^MP)e_c~Sk5nuFwN8EF+q!Iy-Bg|S{oQ|grIF5TC*Rlq z>wD9DU&A{C_?%<6{?~u}IG_91$G!%Q;ABa;85JVl`!!JZ6U!`Fyi?ppsNO)CCk9m1 zs@MucG``2$YkR#@<}CKo%PlP&mOQY(TW!f|U$xva#v$(md$|>sgSk}Hs%R{xq77x? z13%P6gZNx=mb4~^To3J~R$BhBsrNKMLo~u**f1GWFcs6V72B`}d$AAuaS!+L0x$6j zuaSMInbA(ok`wO8h1>{0E!0Mxp=OQ&EHp(k`<PXhkB-ENee~~^?B5dmUkUO56UTph zFInZU$w+TG!l(9E?VH*U6=oGa6()v%`SNG?SZz7&F#BOVQLLFfzXez7@|Hl<LlEkt z0UDwa8sp0z**(`<{&1-BDE{+Wi-XDdvWL9(+U{vhz18kxO&zBuqaGChc!Q-whWP16 zEs4kU?PM(`SF^<Tp6z-%^~R;Hqx0&`sC|B-*OYx?f@^hKO)ImOk-rLO6iMQ0t5 zlJS$$ryvtj6{A`yAyUtqS?kJtou*vPPu$aoN!4n|m)nh1t)No889}MaeFg2%0m0~q z?)U{mF$eS(7J9)-K|0w4(Nj)>SqMcB(053JXx(pU?|RI2pshOLx}2HsBe+X(5D#(2 zoq5g)XFSg0J?iCQ8c!_4Av{80UiKXeup75gBR{i-VGg$98gjF*?J*Sdu^&SUG3WW_ zB20>gn|KSCqRbHqF9e_idSNgoAQtOz6iN6KPDEm6sK~5<I%tV*h`?}6#yrGfBlh5E zG42RH%ffxUhf8s40pvvqR6zh*U?9e05jNsDZr~+Sk%H-v59LrBEzu4AFcMR-0IRVB z$8g@p!+oeMkj9hg&rldu(Hh|xis@L19XO5KcnL=@>NVs;MFgS)24EZ(U;`46gjdi? zGQk*1z*dcihUkn4jK*{<!dmRX8QjDR=;YJv@PrRkzHNmt*f0*Wune1V7*}u$Z=jcA zwlow*`BJ2RO%__C7a}nUOR)`ya1pog6rbTzngF0EDkBhW(G!C)8H=$2`*03Pcm@Xw zSbF4xDs28`NdLwxbVMKghACKq9XO5acn-(1Os0lhC;?y8LmTvj4P!AKu~>&aIE|Zl zfmG$lC&-OrsAA)xDSARJ&%hGot-#do6^U95z$~a~?$s>zYJz$-`MjD;Ud<J+rh!*8 zysOFE)x7L#%5^oHx|%Ot&55q209Vs{tEs!ytlVnC?W0ihWZQJ=nbkjkodsCUx!bD) z<vE11-B(T3O2!<eW-n!fGYI57HM6Fg;!@2usV03?vo8{RN7a0UYGyzJdPhx`r)I5V zifIRvn#WB|sHSE%Q&WtoxxUn-TWa<zH4T+bO$a4w8YVR#5_1))S%cK{J!&2uHKC1~ zSw>Cqq9$8Wv!1BwN7OtZ!h{@ZY78|=g_<owP1~U6Pf!yXs2K&wOJBy=SA*TFQRmh0 z?`j-&H6pqinp}+$&S2fPFT-XF<5#PZq}7<tYH(#W%CQ=5SdIIu2H;gA;i@5N)!49V zkXAKXsv5RbjUTE8@)SnYRAXDJK_=B`k80ROHU6O*h)|6PsD|cKW8|s9>eQ%lYWOxa zu9`U8)_xg6OpV#42FX&RQmJ8})VND(pd&T1kQ&NIjh&+gt5KuFsNq=D_$O+>5jDbx z8dBrSq|s_v2sM_08Z|)Ormt?IS9i0k+se7+TitxE?t)ggBdhy@)eX9gZo)mW>IPMH zr>MGRQ{6kMZemn-6JF2bq;9!W_r9r{(A3>v>b5L(f0VjWN!>A|ZrxEg(Wtvw)NLi| z1`l<sg}UcK-F%?#0#M!YRlj)EL0$C}S6#MM-)Yr}*`~S^tA4$zhpp=Bsydyj?w_h3 zrs@!>dM2taf~v2c>NKZ%uc>Zisy~<NSf#o+slG<4(~s(Xqq@PU{wS(vi0Y!D`bwxy z3##{kYQ|UX>8fE{H8IoHYx~mbs+vDlJEUq5R84cLjZ8IGsa7M^e52Y?RD*_USx}ew z)wOnY)mvSDR@Z^m#o8|yOV#B@b$w4=P*Yd3)HNe@?M7WCQI{puMFDk6uFithnWvKn zr+P2jeLdw-=Mw5yr1~+ae(b1UFJFISMV@sXXlietlwi$dk4vx?aEfrE^x1vSx#o8o z#^P{$=sDLm_ON5tP4*(kt(%;<_eDP1eJ{AKv&WvW&aqcNY5mzg@ubz=sV9g3u=r0G zUH6*eho81?Gui5EOd^R!XpAP{<5CFzXh-YjKn%ff%tI`QE>SI?v~CJfCRq$BW^hrB zfsd)>G0Byh0;{nW2{?t^X*pcMH?0JSR~G6p)JN{DOdE=-$d#Qp!53L_GRG&%A=#ZT z=jTXHG@)W1icx45U+0?ZeP^4B5oJ+oCJIi&yq|c0h;JKK8?TOJluGwiAkSknQ#n&f z3w3V`#KWly5rAEPG1`a7q7W-<%TUHJ>;TP|{OIG)zTuARZrg7J;QwVS0o+Ewj^QJs z2w+tLrPM_R0#)~$c0A7@fK3Tta{{&zZX5{O60jYA3EUBuXZvtmolEFG5VF&R?7MFv zl;dnH5f^a<w{ZvcUHI{5VM0~{k_u_y3M<l~08S$jZQTgKx4_OPa7%FmWixUp&1mCb zPH1zHqz&MfRiqj$BxP01au<ogMI<4JUy^NM$;(e5<VF#cgdc(tf^hVQ4ZmR`=3+e# zAOV-)Y|BT8kp=F^kJ6}!8mNoLXoX;$!!3M(o}c^$cjQB1c%mG9P#rDN7wTv3XiUI7 zEXHcs;(0iN6S$0<c!F2>45tF@Ez-js`B4((Q3G|*7&~zY7jP2~@CqNG@f+F&8ITS6 zPz03<lK$0LXo@xnL2nGgFieCUOR)-@uoDS5gKM~hr+9@=NL7fufQ)cQew0Qf1fU*T zAsBrMk^Tc&7>)6mgN67V8*vcFa1qz>6tCe>nCM4FWJh6mqB5$ZE*ha7x*#0=Fbrcb z33kNTcvy^;ScmP{i{nVd72LuT1QnqkL2GnFFATsCjK+9O!)z?X5uArQTXE#<!$3L| zK`B&#tvV0t^rb1<pgY3xD~2KplQAF55RdKHi^E8SI<<L+WayloSfEaGa-aZ;p)9H( z0QJxU?TV59>f9#`{b9p6Ou>9C!D^`Upq<!{lQ@ryxQ<77jt_7wPTC^_av?uFQ3k%K zfgm(NTXZT;`uAj^FGgT2#$hTJBM$M{iK94!%TVW2kMRPZq0XyZpw6wbAvX%a6BSSu zwGf2nXbW}D6{gOs2EdMaScFwrkL@^vtGI<Hc!|$&;+)EY^vDh$)JHRPMHmKP2qvL0 z)p0STufQO3s1H>=+j{a4j(vDRJ^cahl|=HO9NHiP127Zw;lvMe9r;llozV?rFbPvI z8wYS0_wXmOQ|G&*KYqpRDy08H7LuX)5F)h4VyuFjFX@OpD1&nFg<hSahs?->Vkn1} z=!OtPU>$a2FOK0Xt|OHnr$|WeXXEh9LQ`}?7xczp3_~2YU>gp?<WB~J8?vD(I-v`C zBMw`z4F_SW!TaHcY-ong=!!mAXX9Zv_Tm_vekKzk1KiOXA?Shr*nqv*j}tIzlAg!{ z4>UnXbVfMhum#(25XW&7&H?N_Y#DjT1uyucD<aSz!|@cKkPLGzYB7w&XiPx@F5wF9 zA#ZJt4=4p6*f0(gFbh}k5RdV;HtC<K4w<Y8dx%$K_^F1yQS2cOP9OuJ++?a#gv_L9 z;@&JaFq^y(O+XR6oL^9ww3$+aoyUn)c%7#tpt8Y99JZBZ!bRLuDl$W5B^$GDR${`( z>de517HEaeIEoQ|Oiqo}Sc`4&_Gb#rzD((jE_0b775kSmrzLK{aXr(MA_o>6VSZ4Y zN2Ww3okU|aM=$iY@!-kqlO^%`Hg973M{f+yz+^tSUySMSiaSVwo(|F+4+bzN4QGTW zM>1s!I!@v25QXM*5{PSYOi_eXE16nvvxDry`F%{Dga(`_c0)KeU1DM_*!J^Kj(J$Z z(D(&2lE9srNOGen+*30aF~($KykaayQb`6G#`r4Cyntm`f%CphX;78v4FWkagll`o zGDaa3L0Csd<i}X3$pF%aI@%<2D5DjlJdO|NLnAo#oXXhw@SetNh{Omi!V+x94jh0! zopDvsd?v#O;}#lo`q~1m5sc30iMd#a#fZc2vusRy!NP=S&T}yx^Y9ce@fyjfK9}*Z zQ40;R6Z>!g$FVzxv1p-wYPUjbbVAjId=_)C0sCVaXc%gE^|Lr<<KZga<1<W)9K{Lg zkqH54fad6cVTi&?Y{VWM!Vw(9-o-4V$`Uq?F!aVD{DJFuh(~w^+jAbYrJT$o12RJm z?4BJ3PzatViP9*GD(Hd!7>)6mjA=N61iZpW2v-ms;f;!ziTNnRRfXDdq<>o$hNAcH zj$(%zXZ<+#ZD166e1^wHE?dO27q|@B#MsPR7+)9u=#KH&fm3kU%Ane4gqg^`jY%%h z0n_ksC*wBnB1ZO-{=4=u(((bus>TOoJ;<~%2t+dsKFnTXDgMAige5Q}JC{Jl;}3K@ zL*NjbNcx{;h~sl)I4+Ouzerl+CA3Rl$FJ6|GN?R?;<PQvQ4B_&o^X><q!Et`D0r9Q zn-PpqG-HV84j6^>Pr0~*T4;kPEMUClt9XK+8Ebjbdx|4Ipxg(d`ZJ{n3-NO@qn=|B zY%x5n!$DlcC!~{9k{^}O7X1)~SR8g_z_wHjTZ~7z?!?e$&WzZF2;4$tjnTZ|p?@7a zco@&?k%fyweuzN{Go$I6Q`w}Il~G(V2J^8GNf_(K0D?GzTbPhGl`O+i+{c-8j9Z#9 zm1N7rh;-TcJXT{3_TwPl;vF95A+Sj2!B~ALfI?{DVPlX~76J+}avH+X8>27=Td)-? zOE9h&5^)v}@CeyG8KVr=k_@DXAlNVz2a$l2I0J)AUTNTs3aEmrHXeFoAkHHRtx6Fi z@F-0v@dEGh5hl)*3!yloF;6K=%;5vlmt(v>^juHxR?Nj(>_8%};>ZRr2%+>wx~o>@ zp)uOy67J#yw0OEyVLvY5Hd=EPsT+>t5}x7%`fsL-9%f<@nrxvLA|fyhdAHJ`5`GB6 z5uC+?t%glrv(RFjAzg3@_wW(Mb~cFauptV6;uG9<7?J}^upWnyh{`+Z3x<)Hf+bjw z%)1B#%E2EyaRhaD+qnL<o6d%~hmbvl8Xw@im)_Z!f(-lU?S=V>L(%<QTf=7TLpT>N z`rre7E<Ym~&RlQPV1X;rA`9{%KfK`GkcZN!0zdep4#Lm}5g3S>n1g7<ViDr75~~r9 zeb|o^_Jbc?OWMlQxziU_;fG*^VjzYi7Ax@vpV5y_pf(J_FhnB;xA71!@c|!^j3P(r zstj+GK`qorV>CNT%Gy{Mg)xZ2a;(HEY`{ir#}4eqAtd4~uA@={9SGq@Pt(2h`pib} zO%E(OOK(#Ac8-AI37+CL-rzHm&vmCO;CZqUG9nXl!vpzH9HmeimCzQ!=#1_dgD8x{ zR7}GhL?Z@EupS$*%iiX*YZ+Ui3uJSs{+p%H5UtQ1eJ~Z#xQi#~a*+<d2t#j-!$c(F z5^muk9^omnT{0vOJdht1P!;~Dd5H+`$wCDB<5$c=H0ELv7Got=VGTB6KMvp|F5(6% zUZzVdMqHuWJqli<D=?xEjTKmj{Wy*WNyJ@}jbgyU07PLra$F~(Q3-x%f_Au%_t0+` zVnuEg!3G?_8C=E_yhY?q5&)~Q1(k1+)ewpZBqN>eHeIh#7Q1i;Pw@^z?+_rY!B$k~ zns*~~Kz9tnD13s29-Z0Xfzt57MjS*UuHY%&VZeQ22s2@u&%-)wN96}}|3oWvL<Az? z@Q{!q7Yd>R{BQsl@e0Z4`-m)vSgeA_V|EM;&<a=a94>S*&4d|GNdGt%4&o&0)917k zA~6<e=zp3Wg;5fI2*hdJ!gIVw8v3Ya#4N19X6(jkTtP?ruKt4Ih{9YfMTr-rzwZma z6iv_-z3~y&m!vU@U^VvPERxXW6`2*|F$3<esZ!vNdbohcNQUu-qZ$@s4L0KsB%+q> zEggQ*4dED$@ksTK`Wtyr7?n^1hj0OR@f4=_^v*>TqOk(&uph@!?*o|^JrRL1n1b{l z4JiOyc^;}`3yvWP5771#<sTz45pJJ38len)u?J^y56=;iOp+lQOHfMa6@r<VhXf?T zVxkij0@1`|wn=jqI-(mQFc*ul4C}EO2k;oL@D@%EW-%i(es-jr37VrLZs7sSI<WyP zz;1j-c4yv){)op}XIh2QYji3^7$#sRt|F^W2SrT8?@(Qc%``VPL~m@uITWGCPA$yC z4x~y=2SbD+3g_?|zG=+T7AtWSsa@zAY~!ID#^4a{B8!F4BLdTrh?l7CN~c!r#SK)j zvNu?T1bDj92?y(N3i;F0)fDrv1DVs&9Tk(X8W&)D%R^oo(5fRGldv6^p=aPrPzNEH zj5Roi*T_aoR0Xud5G=-iJVu&KbPYrUL}3N)LCZ|XD+D7ZGwHvRg%9{C3!z6(EW$p# zM;4m80?`Ap*o$|_oR#;ZC$46rKPu*Crw2Dwf93!z##ubV3uMhn4=i{i7`<}Z=rqbg z1R^mC<8dC>P~P1vm0-tm?8jx4$;Dov4SvB%TtlkdYy`hxIF@5KvgIMIu@1XY%YzO_ z2)FSt2Dk7WY4VbJFc?u-gG0!ZkMza1f&>DWQKk@qKsQ9<G9JKMm}J9HOhlF<{Es!* ziSu}hfTE;-Qy#)G1`9BvBz-OM22S3@2Ie4NDWVN^5RBb8fCQY!HM~ZH(zL5$Zh5+` zSE3=ds+mbG$v?H|_|}}AXhr9^Hgs9-NWO_6{evSYx9EZ1_yyB29WyZVo7p_i!CcJ4 zd@MjL7U2}mA!9#!XrdPCpaohX6bo=2sxNEN{uJf@gm4NAQ?VEO@Di`!K7cN8sD(f@ zfokKU_53^g8ml#(eWKNx#+1#z#zF(~;7ryu@%40Tu!G6bZn9W2*mqg2>D3ym$sTL5 zdfR<0R&)GE7wc7{q-rU=57iR*eV5hl{5{yU|Gi~<qQ5nlZLHJRmg7kMYpXGLS$}CU z=04ajt;IPEu8D)9@ui{mTxwc)*idi8;1e>t(7c2p*Z~!Y8c+?ns%3c%RI9RTl1zeX z*i~((H167@0}GKDg@ss#{WygC$VgkIYW-~w)$%(JswG-AS2jW)OokonunA{y4sVf{ zPIA@J2?H?!s`XkmbNXfF`gbr3Loph$SdIfYj0eb+jRrI{MJOVnn!Hu}XmxZzB!(jf z3$YV>a1(Ah=>CKH=!^lVn3EPD^tbUa2s06l&De%3NbOD|3TmSr`XYBOuKJ=4I>3fu zn1=<}i)XOrCYDeGEwRLdoy-5V-Sek{Uz;JF3-fu^idP(}^==wetK5a6T+_xAsJ5-8 zG@ultPuL5(W~rW6iO|b(p&t3m5!FzQ?>iCfLrkI~R|Bge6ut2bp7Xh~#8ttD_=J87 zx&GChv-U)!JHXEqlsm`|cnm-sdY|KVE4;tT5A$pMvP3hu3HMW=5tg76mGy9pCf85J z_fqh^;Qw=>xBd4LAN>y{y*LHh4-N6Z6!<zn6nMG?QRJDz<12fmKx^vwxdGOtCY$QO z@xK(qzZa?R#p!#g_@29mk$FdA5tib6rfo<5P*mQDgi6*iWhjbkNVk=~<m{?s#A*~3 zT5#M)(qu%FMDww<3P+LY#?ez`0wpGaFFnqCHM)V(wBSKMF|DtO=^#u}f3Arc+-XhV z;{K2eT=nPTzHb%gb;ag(T)=D3wa|{t--e?hOeMyp?~zk%%(Tlj?<W{J?Q16a-g{#W zS9uh5WhX6pB=Vc@{Uua>`JQJgkT+C5Q7U~?kbH54gZ2vdAM?f!2L>CN=ASdkf6gN* zj{^T&p7?$MpjVoFXK!8Cx+*?>ptV%R43C6HI*=peHq_rkd+V{*oAG{8)}yBQ4CAf3 zsrvWutCvkk_DM5DJ^%a9^kx0O|EJ+8zk~JL|El-%iTHLCtaiteW$Js?*wSHLK8G(K zsF&L${*AbwQL<875k~9b;<Q`;u=a3#;VITOCZ~bTxEIboVX8I2R5JeJRBI1YCO-+0 zjttv>U&6&*YO@?7U8Vb!NvSf}`%JfnOrK#bVLMMq-3W;a@I*LZ2Go9U0|zF#3}@)P zN#nT$&nix6ni395OcqB&CeK}X<^Uz5c}~sqRGv97Nes^}Jjd~D;dv9!9Drn(iGNiz z9AX6r7OolXpJ6R&Pc_pTTGp4AdseB>*X<b|+AgG6aL+!WU)HIQ_=R)~y&vvgyJJY# z?)>{@y$Z9Jec4QF0U!UpdDL1T^$>fq*Q(%yrZ3CwCtr2;JMqJ^BX6M?kpsTQt$Oy4 zcbjE>>M|uJRr={mtv+4r5x_JGukj>Zp!OgPDu#wb#ZVMfY)(Zc%z=uDSg26PLG9>z z(DUa@46B&g2ld^L>}!@<^SG&GR>4rouAT?RKVE9}cQpChz2mGwsl1AMmaylTY4wWV z8fW!OO(?A!H(A?ePxCoBIk`D0)B^D#iPjS)t6FuEe;I*GPOH_m&sl>_zG`(b(y%y6 zz!P3532&&^OY>X?Wl;|0Q2`b4+1~4dwTgYn1qwi*ea!`H;G~#-(=S>>j1wb@C8;P5 zviH4cwK+Fqn^zy%-(R#2aAs66`MB9W;F8s5T5W%S$vVJP)ZX_p|CNe=b=jKQ>Hh#7 CmHN*B diff --git a/help/Makefile b/help/Makefile index 3c4191bd7..55bbae00d 100644 --- a/help/Makefile +++ b/help/Makefile @@ -26,17 +26,17 @@ exception execute extension external fail false float float2int \ float2str for from function friend get_stringencoding getcall getreply getverdict goto group \ hex2bit hex2int hex2oct hex2str hexstring if ifpresent import in \ inconc infinity inout int2bit int2char int2float int2hex int2oct \ -int2str int2unichar integer interleave ischosen ispresent isvalue kill killed \ +int2str int2unichar integer interleave isbound ischosen ispresent isvalue kill killed \ label language length lengthof log map match message mixed mod \ modifies module modulepar mtc noblock none not not4b nowait null objid \ oct2bit oct2char oct2hex oct2int oct2str oct2unichar octetstring of omit on \ operators optional or or4b out override param pass pattern permutation \ port public private procedure raise read receive record recursive regexp rem remove_bom repeat \ -reply return rnd running runs select self send sender set setverdict \ +replace reply return rnd running runs select self send sender set setverdict \ signature sizeof start stop str2bit str2float str2hex \ -str2int str2oct subset substr superset system template testcase \ -timeout timer to trigger true type unichar2int unichar2oct union universal unmap \ -value valueof var variant verdicttype while with xor xor4b)) +str2int str2oct subset substr superset system template testcase testcasename \ +timeout timer to trigger true type unichar2char unichar2int unichar2oct union universal unmap \ +value valueof var variant verdicttype while with xor xor4b profiler)) IMAGE_FILES := $(addprefix images/, $(addsuffix .jpg, ao left right up)) images/titan_transparent.gif diff --git a/help/info/on.html b/help/info/on.html index 4768cfbe8..944626b78 100644 --- a/help/info/on.html +++ b/help/info/on.html @@ -23,7 +23,7 @@ <td><a href="../titan_main.html" alt="contents"><img border="0" src="../images/ao.jpg" width="53" height="40"></a></td> <td><a href="../titan_index.html" alt="index"><img border="0" src="../images/up.jpg" width="53" height="40"></a></td> <td><a href="omit.html" alt="previous"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td> - <td><a href="optional.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td> + <td><a href="operators.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td> </tr> </table> <p><br clear="all"> diff --git a/help/info/operators.html b/help/info/operators.html index e08e10e28..66c7482f4 100644 --- a/help/info/operators.html +++ b/help/info/operators.html @@ -22,8 +22,8 @@ <tr> <td><a href="../titan_main.html" alt="contents"><img border="0" src="../images/ao.jpg" width="53" height="40"></a></td> <td><a href="../titan_index.html" alt="index"><img border="0" src="../images/up.jpg" width="53" height="40"></a></td> - <td><a href="altstep.html" alt="previous"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td> - <td><a href="and4b.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td> + <td><a href="on.html" alt="previous"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td> + <td><a href="optional.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td> </tr> </table> <p><br clear="all"> diff --git a/help/info/optional.html b/help/info/optional.html index 41ed700c0..22c315789 100644 --- a/help/info/optional.html +++ b/help/info/optional.html @@ -22,7 +22,7 @@ <tr> <td><a href="../titan_main.html" alt="contents"><img border="0" src="../images/ao.jpg" width="53" height="40"></a></td> <td><a href="../titan_index.html" alt="index"><img border="0" src="../images/up.jpg" width="53" height="40"></a></td> - <td><a href="on.html" alt="previous"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td> + <td><a href="operators.html" alt="previous"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td> <td><a href="or.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td> </tr> </table> diff --git a/help/info/procedure.html b/help/info/procedure.html index 9c773f922..11a0b8153 100644 --- a/help/info/procedure.html +++ b/help/info/procedure.html @@ -23,7 +23,7 @@ <td><a href="../titan_main.html" alt="contents"><img border="0" src="../images/ao.jpg" width="53" height="40"></a></td> <td><a href="../titan_index.html" alt="index"><img border="0" src="../images/up.jpg" width="53" height="40"></a></td> <td><a href="private.html" alt="previous"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td> - <td><a href="public.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td> + <td><a href="profiler.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td> </tr> </table> <p><br clear="all"> diff --git a/help/info/profiler.html b/help/info/profiler.html new file mode 100644 index 000000000..1f5c2bf29 --- /dev/null +++ b/help/info/profiler.html @@ -0,0 +1,134 @@ +<!-- + Copyright (c) 2000-2014 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 + --> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<meta http-equiv="Content-Language" content="en-us"> +<title>profiler</title> +</head> +<body bgcolor="#DAD3C5" vlink="#0094D2" link="#003258"> +<table align="left" border="0" cellspacing="0" cellpadding="0" valign=top> + <tr> + <td width=105 height=40><a href="https://projects.eclipse.org/projects/tools.titan"><img src="../images/titan_transparent.gif" border=0 width=105 height=40 align="left" alt="Titan"></a></td> + </tr> +</table> +<table border="0" align="right" cellpadding="0" cellspacing="0"> + <tr> + <td><a href="../titan_main.html" alt="contents"><img border="0" src="../images/ao.jpg" width="53" height="40"></a></td> + <td><a href="../titan_index.html" alt="index"><img border="0" src="../images/up.jpg" width="53" height="40"></a></td> + <td><a href="procedure.html" alt="previous"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td> + <td><a href="public.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td> + </tr> +</table> +<p><br clear="all"> +</p> +<hr> +<h1>@profiler</h1> +<hr align="left" width="75%"> +<p>The keyword is used to start or stop the profiling or check if the profiling started or not. </p> +<p>By default the profiler is automatically started for each component when the program starts. This can be changed in the configuration file. </p> +<p>Detailed description can be found in the Programmers' Reference Guide.</p> + +<blockquote> +<p>1. <a href="#1">Stopping the profiler</a></p> +<p>2. <a href="#2">Starting the profiler</a></p> +<p>3. <a href="#3">Checking the profiler running state</a></p> +</blockquote> + + + +<p>Related keywords:</p> +<ul> + <li><a href="start.html"><b><font face="Courier New" color="#003258" size="4">start</font></b></a></li> + <li><a href="stop.html"><b><font face="Courier New" color="#003258" size="4">stop</font></b></a></li> + <li><a href="running.html"><b><font face="Courier New" color="#003258" size="4">running</font></b></a></li> +</ul> + +<hr align="left" width="75%"> +<h3>1. <a name="#1">Stopping the profiler</a></h3> + +<div align="center"> +<center> +<table border="0" width="90%" bgcolor="#FFB599" cellpadding="4"> + <tr> + <td width="100%"> + <h3 align="center"><font face="Courier New" color="#003258" size="5"><b>@profiler.stop</b></font></h3> + </td> + </tr> +</table> +</center> +</div> + +<hr align="left" width="50%"> +<p>The profiler can be stopped using the <font face="Courier New"><b>@profiler.stop</b></font> command. This only affects profiling and code coverage in the current component</p> +<p>When stopped the profiler does not measure new data. </p> +<p>This command has no effect if the profiler is already stopped.</p> + +<hr align="left" width="75%"> +<h3>2. <a name="#2">Starting the profiler</a></h3> + +<hr align="left" width="75%"> + + +<div align="center"> +<center> +<table border="0" width="90%" bgcolor="#FFB599" cellpadding="4"> + <tr> + <td width="100%"> + <h3 align="center"><font face="Courier New" color="#003258" size="5"><b>@profiler.start</b></font></h3> + </td> + </tr> +</table> +</center> +</div> +<p>A stopped profiler can be restarted with the <font face="Courier New"><b>@profiler.start</b></font> command. This only affects profiling and code coverage in the current component.</p> +<p>Similarly, this has no effect if the profiler is already running.</p> + +<p>The execution count of a function is measured at the start of the function, thus if the profiler is stopped when the function is called, its call will not be measured, even if the profiler is restarted during the function’s execution.</p> + + +<hr align="left" width="75%"> +<h3>3. <a name="#3">Checking the profiler running state</a></h3> + + + +<div align="center"> +<center> +<table border="0" width="90%" bgcolor="#FFB599" cellpadding="4"> + <tr> + <td width="100%"> + <h3 align="center"><font face="Courier New" color="#003258" size="5"><b>@profiler.running</b></font></h3> + </td> + </tr> +</table> +</center> +</div> + +<hr align="left" width="75%"> +<p>The boolean value <font face="Courier New"><b>@profiler.running</b></font> stores the state of the profiler in the current component (true if it’s running or false if it’s stopped).</p> + +<hr align="left" width="75%"> +<h3>Example:</h3> + +<p><font face="Courier New"> function f1(inout integer x) runs on C<br/> +{<br/> + var boolean stop_prof := not @profiler.running;<br/> + @profiler.start;<br/> + x := x + c1;<br/> + if (stop_prof) {<br/> + @profiler.stop;<br/> + }<br/> +}<br> +</font> +<p> + +<p>This function is always profiled and returns the profiler to its original state.</p> + +</body> +</html> diff --git a/help/info/public.html b/help/info/public.html index c98d49ac2..7448a817f 100644 --- a/help/info/public.html +++ b/help/info/public.html @@ -22,7 +22,7 @@ <tr> <td><a href="../titan_main.html" alt="contents"><img border="0" src="../images/ao.jpg" width="53" height="40"></a></td> <td><a href="../titan_index.html" alt="index"><img border="0" src="../images/up.jpg" width="53" height="40"></a></td> - <td><a href="procedure.html" alt="previous"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td> + <td><a href="profiler.html" alt="previous"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td> <td><a href="raise.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td> </tr> </table> diff --git a/help/info/running.html b/help/info/running.html index 474c7b85a..40abdc673 100644 --- a/help/info/running.html +++ b/help/info/running.html @@ -33,9 +33,10 @@ <blockquote> <p>1. <a href="#Checking components">Checking components</a></p> <p>2. <a href="#timer">Checking timers</a></p> +<p>3. <a href="profiler.html#2">Starting the profiler</a></p> </blockquote> <hr align="left" width="75%"> -<p>1. <a name="Checking components">Checking components</a></p> +<h3>1. <a name="Checking components">Checking components</a></h3> <hr align="left" width="50%"> <p>The operation is used to <a href="#Example 1a">check</a> whether a given parallel test component is running (i.e., has neither timed out nor been stopped). The Boolean value true is returned if the component have been started but not yet terminated or stopped, false otherwise.</p> @@ -53,6 +54,7 @@ the component have been started but not yet terminated or stopped, false otherwi <li><a href="any.html"><b><font face="Courier New" color="#003258" size="4">any</font></b></a></li> <li><a href="component.html"> <b><font face="Courier New" color="#003258" size="4">component</font></b> </a></li> <li><a href="create.html"><b><font face="Courier New" color="#003258" size="4">create</font></b></a></li> + <li><a href="profiler.html"><b><font face="Courier New" color="#003258" size="4">@profiler</font></b></a></li> </ul> <hr align="left" width="50%"> <div align="center"> @@ -85,16 +87,16 @@ the component have been started but not yet terminated or stopped, false otherwi </li> </ul> <hr align="left" width="50%"> -<p><a href="#Example 1a">Examples</a></p> +<p>See <a href="#Example 1a">Examples</a></p> <hr align="left" width="75%"> -<p>2. <a name="timer">Checking timers</a></p> +<h3>2. <a name="timer">Checking timers</a></h3> <hr align="left" width="50%"> <p>The operation is used to <a href="#timer_start">check</a> whether a given timer is running (i.e., has neither timed out nor been stopped). The Boolean value true is returned if the timer is running, false otherwise.</p> <ul> <li>The operation does not block TTCN-3 program execution, i.e., it reflects the momentarily state of the timer and does not wait for timeout.</li> <li><a name="stop_all">The</a> keyword <a href="any.html"><b><font face="Courier New" color="#003258" size="4">any</font></b></a> may be used to check whether <a href="#default">at least - one timer</a> is runnig.</li> + one timer</a> is running.</li> </ul> <p>Related keywords:</p> <ul> @@ -123,16 +125,18 @@ running, false otherwise.</p> <p><i>timer_identifier</i> is the name used to refer to the timer. It must begin with a letter, may contain letters, numbers and underscore characters.</p> </li> </ul> -<hr align="left" width="75%" color="#0094D2"> -<p>It is possible to check a member of an <a href="#array">timer array</a>.</p> -<hr align="left" width="50%" color="#0094D2"> +<hr align="left" width="50%"> +<p>It is possible to check a member of a <a href="#array">timer array</a>.</p> +<hr align="left" width="50%"> +<p>See <a href="#Example 1c">Example 1c</a></p> +<hr align="left" width="50%"> <div align="center"> <center> <table border="0" width="90%" bgcolor="#FFB599" cellpadding="4"> <tr> <td width="100%"> <h3 align="center"><font face="Courier New" color="#003258" size="5"><b></b></font> <i>timer_identifier</i><font face="Courier New" color="#003258" size="5"><b>[</b></font><i>array_index</i><font - face="Courier New" color="#003258" size="5"><b>].runnig; </b></font></h3> + face="Courier New" color="#003258" size="5"><b>].running; </b></font></h3> </td> </tr> </table> @@ -147,17 +151,19 @@ running, false otherwise.</p> <p><i>array_index</i> points out the timer to be checked.</p> </li> </ul> -<hr align="left" width="50%"> +<hr align="left" width="75%"> +<h3>Examples</h3> <p><a name="Example 1a">Example 1a</a>:</p> <p><font face="Courier New">var boolean v_Tbana := vc_metro.running;<br> </font> <p>The variable v_Tbana gets the value true if the component with the reference vc_metro is running.</p> <hr align="left" width="50%"> + <p>Example 1b:</p> <p><font face="Courier New">var boolean v_Ubahn := all component.running;</font> <p>The variable v_Ubahn will true if all started parallel components are still running.</p> <hr align="left" width="50%"> -<p>Example 1c:</p> +<p><a href="#Example 1c">Example 1c</a></p> <p><font face="Courier New">var boolean v_metropolitain := any component.running; <br> </font> <p>The variable v_metropolitain is true if at least one parallel component is still running.</p> @@ -178,6 +184,6 @@ running, false otherwise.</p> <hr align="left" width="25%"> <hr align="left" width="25%"> <p><a HREF="BNF.html#runningop">BNF definition</a> of <font face="Courier New">component running</font></p> -<p><a HREF="BNF.html#runningtimerop">BNF definition</a> of <font face="Courier New">timer runnig</font></p> +<p><a HREF="BNF.html#runningtimerop">BNF definition</a> of <font face="Courier New">timer runnnig</font></p> </body> </html> diff --git a/help/info/start.html b/help/info/start.html index 65b655a6f..dec0f968d 100644 --- a/help/info/start.html +++ b/help/info/start.html @@ -34,12 +34,13 @@ <p>1. <a href="#1"> Starting a component</a></p> <p>2. <a href="#Starting a port">Starting a port</a></p> <p>3. <a href="##1">Starting a timer</a></p> +<p>4. <a href="profiler.html#2">Starting the profiler</a></p> </blockquote> <hr align="left" width="75%"> -<p>1. <a name="#1">Starting a component</a></p> +<h3>1. <a name="#1">Starting a component</a></h3> <hr align="left" width="50%"> <p>When a parallel test component is created it is not executing any behavior yet. -<p>The start operation can be used to execute the required function on the addressed<a href="#component_start">parallel test component</a>.</p> +<p>The start operation can be used to execute the required function on the addressed <a href="#component_start">parallel test component</a>.</p> <p>The function will be executed remotely, thus the start operation does not block execution on the component on which it was invoked. <p>Normal parallel test components can only be started once, but alive parallel test components may execute several functions consecutively. <P>Some limitations apply to the argument function: @@ -61,6 +62,7 @@ <li><a href="killed.html"><b><font face="Courier New" color="#003258" size="4">killed</font></b></a></li> <li><a href="running.html"><b><font face="Courier New" color="#003258" size="4">running</font></b></a></li> <li><a href="stop.html"><b><font face="Courier New" color="#003258" size="4">stop</font></b></a></li> + <li><a href="profiler.html"><b><font face="Courier New" color="#003258" size="4">@profiler</font></b></a></li> </ul> <hr align="left" width="50%"> <div align="center"> @@ -87,7 +89,7 @@ </li> </ul> <hr align="left" width="75%"> -<p>2. <a name="Starting a port">Starting a port</a></p> +<h3>2. <a name="Starting a port">Starting a port</a></h3> <hr align="left" width="50%"> <p>The keyword may be used to start a <a href="#Example 2a">port</a>.</p> <ul> @@ -129,7 +131,7 @@ </li> </ul> <hr align="left" width="75%"> -<p>3. <a name="timer">Starting a timer</a></p> +<h3>3. <a name="timer">Starting a timer</a></h3> <hr align="left" width="50%"> <p>The keyword may be used to indicate that a <a href="#timer_start">timer should start running</a>.</p> <ul> @@ -165,9 +167,9 @@ Otherwise it is optional and overwrites the default value. The value is measured in seconds; <a href="float.html"><b><font face="Courier New" color="#003258" size="4">float</font></b></a>ing point value must be used.</li> </ul> -<hr align="left" width="75%" color="#0094D2"> +<hr align="left" width="50%"/> <p>It is possible to start a member of an <a href="#array">timer array</a>.</p> -<hr align="left" width="50%" color="#0094D2"> +<hr align="left" width="50%"/> <div align="center"> <center> <table border="0" width="90%" bgcolor="#FFB599" cellpadding="4"> diff --git a/help/info/stop.html b/help/info/stop.html index 8978e338f..0bc493c5b 100644 --- a/help/info/stop.html +++ b/help/info/stop.html @@ -35,9 +35,10 @@ <p>1. <a href="#Terminating a test component">Stopping components</a></p> <p>2. <a href="#Starting a port">Stopping ports</a></p> <p>3. <a href="#timer">Stopping timers</a></p> +<p>4. <a href="profiler.html#1">Stopping the profiler</a></p> </blockquote> <hr align="left" width="75%"> -<p>0. <a name="Terminating execution">Terminating execution</a></p> +<h3>0. <a name="Terminating execution">Terminating execution</a></h3> <p>The stop statement is used to terminate test execution. Whenever a stop statement is reached, the execution of the underlying testcase is immediately terminatef. The result of execution will be error. <hr align="left" width="50%"> @@ -55,7 +56,9 @@ error. <hr align="left" width="50%"> <p><a href="#Example1b">Examples:</a></p> <hr align="left" width="75%"> -<p>1. <a name="Terminating a test component">Stopping components</a></p> + + +<h3>1. <a name="Terminating a test component">Stopping components</a></h3> <ul> <li>When used in a test case, altstep or function that are executed on a test component, the keyword terminates the relevant test component;</li> <li>when used in the control part of a module or in a function used by the control part of a module, it terminates the execution of the module control part.</li> @@ -68,6 +71,7 @@ error. <li><a href="all.html"><b><font face="Courier New" color="#003258" size="4">all</font></b></a></li> <li><a href="component.html"> <b><font face="Courier New" color="#003258" size="4">component</font></b> </a></li> <li><a href="create.html"><b><font face="Courier New" color="#003258" size="4">create</font></b></a></li> + <li><a href="profiler.html"><b><font face="Courier New" color="#003258" size="4">@profiler</font></b></a></li> </ul> <hr align="left" width="50%"> <div align="center"> @@ -99,9 +103,11 @@ error. </li> </ul> <hr align="left" width="50%"> -<p><a href="#Example 4:">Examples</a></p> +<p>See <a href="#Example 4:">Examples</a></p> <hr align="left" width="75%"> -<p>2. <a name="Starting a port">Stopping a port</a></p> + + +<h3>2. <a name="Stopping a port">Stopping a port</a></h3> <hr align="left" width="50%"> <p>The keyword may be used to stop a <a href="#Example 2a">port</a>.</p> <ul> @@ -141,7 +147,7 @@ error. </li> </ul> <hr align="left" width="75%"> -<p>3. <a name="timer">Stopping timers</a></p> +<h3>3. <a name="timer">Stopping timers</a></h3> <hr align="left" width="50%"> <p>The keyword may be used to indicate that a <a href="#timer_start">timer should stop running</a>.</p> <ul> @@ -177,9 +183,9 @@ error. <p><i>timer_identifier</i> is the name used to refer to the timer. It must begin with a letter, may contain letters, numbers and underscore characters.</p> </li> </ul> -<hr align="left" width="75%" color="#0094D2"> +<hr align="left" width="50%"> <p>It is possible to stop a member of an <a href="#array">timer array</a>.</p> -<hr align="left" width="50%" color="#0094D2"> +<hr align="left" width="50%"> <div align="center"> <center> <table border="0" width="90%" bgcolor="#FFB599" cellpadding="4"> @@ -198,7 +204,7 @@ error. <p><i>timer_identifier</i> is the name used to refer to the timer. It must begin with a letter, may contain letters, numbers and underscore characters.</p> </li> <li> - <p><i>array_index</i> points out the timer to be stoped.</p> + <p><i>array_index</i> points out the timer to be stopped.</p> </li> </ul> <p><a href="#timer_start">Examples</a></p> diff --git a/help/titan_index.html b/help/titan_index.html index 5e17b135e..a35510a29 100644 --- a/help/titan_index.html +++ b/help/titan_index.html @@ -89,8 +89,8 @@ </tr> <tr> <td width="17%"><a name="d"></a><a href="info/deactivate.html">deactivate</a></td> - <td width="17%"><a href="info/decvalue.html">decvalue</a></td> <td width="17%"><a href="info/decode_base64.html">decode_base64</a></td> + <td width="17%"><a href="info/decvalue.html">decvalue</a></td> <td width="17%"><a href="info/default.html">default</a></td> <td width="17%"><a href="info/disconnect.html">disconnect</a></td> <td width="17%"><a href="info/display.html">display</a></td> @@ -268,13 +268,13 @@ <td width="17%"><a href="info/procedure.html">procedure</a></td> </tr> <tr> + <td width="17%"><a href="info/profiler.html">@profiler</a></td> <td width="17%"><a href="info/public.html">public</a></td> <td width="17%"> </td> <td width="17%"> </td> <td width="17%"> </td> <td width="17%"> </td> <td width="17%"> </td> - <td width="17%"> </td> </tr> <tr> <td width="17%"><a name="r"></a><a href="info/raise.html">raise</a></td> @@ -304,8 +304,8 @@ <td width="17%"> </td> </tr> <tr> - <td width="17%"><a name="s"></a><a href="info/self.html">self</a></td> <td width="17%"><a href="info/select.html">select</a></td> + <td width="17%"><a name="s"></a><a href="info/self.html">self</a></td> <td width="17%"><a href="info/send.html">send</a></td> <td width="17%"><a href="info/sender.html">sender</a></td> <td width="17%"><a href="info/set.html">set</a></td> @@ -349,8 +349,8 @@ <td width="17%"> </td> </tr> <tr> - <td width="17%"><a name="u"></a><a href="info/unichar2int.html">unichar2int</a></td> <td width="17%"><a href="info/unichar2char.html">unichar2char</a></td> + <td width="17%"><a name="u"></a><a href="info/unichar2int.html">unichar2int</a></td> <td width="17%"><a href="info/unichar2oct.html">unichar2oct</a></td> <td width="17%"><a href="info/union.html">union</a></td> <td width="17%"><a href="info/universal.html">universal</a></td> @@ -384,6 +384,15 @@ <td width="17%"> </td> <td width="17%"> </td> </tr> + <tr> + <td width="17%"><a name="@"></a><a href="info/profiler.html">@profiler</a></td> + <td width="17%"> </td> + <td width="17%"> </td> + <td width="17%"> </td> + <td width="17%"> </td> + <td width="17%"> </td> + <td width="17%"> </td> + </tr> </table> </center> </div> diff --git a/help/titan_main.html b/help/titan_main.html index c866f9d53..1c7e9a32e 100644 --- a/help/titan_main.html +++ b/help/titan_main.html @@ -57,7 +57,9 @@ <a href="titan_index.html#u">U</a> <a href="titan_index.html#v">V</a> <a href="titan_index.html#w">W</a> - <a href="titan_index.html#x">X</a></p> + <a href="titan_index.html#x">X</a> + <a href="titan_index.html#@">@</a> + </p> </li> </ul> </li> diff --git a/loggerplugins/JUnitLogger2/JUnitLogger2.cc b/loggerplugins/JUnitLogger2/JUnitLogger2.cc new file mode 100644 index 000000000..825056ea0 --- /dev/null +++ b/loggerplugins/JUnitLogger2/JUnitLogger2.cc @@ -0,0 +1,346 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2000-2014 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 +/////////////////////////////////////////////////////////////////////////////// +#include "JUnitLogger2.hh" + +#include <unistd.h> +#include <sys/types.h> + +#include <sys/time.h> + +extern "C" +{ + // It's a static plug-in, destruction is done in the destructor. We need + // `extern "C"' for some reason. + ILoggerPlugin *create_junit_logger() { return new JUnitLogger2(); } +} + +extern "C" { + ILoggerPlugin *create_plugin() { return new JUnitLogger2(); } + void destroy_plugin(ILoggerPlugin *plugin) { delete plugin; } +} + +TestSuite::~TestSuite() +{ + for (TestCases::const_iterator it = testcases.begin(); it != testcases.end(); ++it) { + delete (*it); + } +} + +JUnitLogger2::JUnitLogger2() +: filename_stem_(NULL), testsuite_name_(mcopystr("Titan")), filename_(NULL), file_stream_(NULL) +{ + // Overwrite values set by the base class constructor + + fprintf(stderr, "construct junitlogger\n"); + major_version_ = 2; + minor_version_ = 0; + name_ = mcopystr("JUnitLogger"); + help_ = mcopystr("JUnitLogger writes JUnit-compatible XML"); + dte_reason = ""; + //printf("%5lu:constructed\n", (unsigned long)getpid()); +} + +JUnitLogger2::~JUnitLogger2() +{ + //printf("%5lu:desstructed\n", (unsigned long)getpid()); + close_file(); + + Free(name_); + Free(help_); + Free(filename_); + Free(testsuite_name_); + Free(filename_stem_); + name_ = help_ = filename_ = filename_stem_ = NULL; + file_stream_ = NULL; +} + +void JUnitLogger2::init(const char */*options*/) +{ +//printf("%5lu:init\n", (unsigned long)getpid()); + fprintf(stderr, "Initializing `%s' (v%u.%u): %s\n", name_, major_version_, minor_version_, help_); +} + +void JUnitLogger2::fini() +{ + //puts("fini"); + //fprintf(stderr, "JUnitLogger2 finished logging for PID: `%lu'\n", (unsigned long)getpid()); +} + +void JUnitLogger2::set_parameter(const char *parameter_name, const char *parameter_value) { +//puts("set_par"); + if (!strcmp("filename_stem", parameter_name)) { + if (filename_stem_ != NULL) + Free(filename_stem_); + filename_stem_ = mcopystr(parameter_value); + } else if (!strcmp("testsuite_name", parameter_name)) { + if (filename_stem_ != NULL) + Free(testsuite_name_); + testsuite_name_ = mcopystr(parameter_value); + } else { + fprintf(stderr, "Unsupported parameter: `%s' with value: `%s'\n", + parameter_name, parameter_value); + } +} + +void JUnitLogger2::open_file(bool is_first) { + if (is_first) { + if (filename_stem_ == NULL) { + filename_stem_ = mcopystr("junit-xml"); + } + } + + if (file_stream_ != NULL) return; // already open + + if (!TTCN_Runtime::is_single() && !TTCN_Runtime::is_mtc()) return; // don't bother, only MTC has testcases + + filename_ = mprintf("%s-%lu.log", filename_stem_, (unsigned long)getpid()); + + file_stream_ = fopen(filename_, "w"); + if (!file_stream_) { + fprintf(stderr, "%s was unable to open log file `%s', reinitialization " + "may help\n", plugin_name(), filename_); + return; + } + + is_configured_ = true; + time(&(testsuite.start_ts)); + testsuite.ts_name = testsuite_name_; +} + +void JUnitLogger2::close_file() { + if (file_stream_ != NULL) { + time(&(testsuite.end_ts)); + testsuite.write(file_stream_); + fclose(file_stream_); + file_stream_ = NULL; + } + if (filename_) { + Free(filename_); + filename_ = NULL; + } +} + +void JUnitLogger2::log(const TitanLoggerApi::TitanLogEvent& event, + bool /*log_buffered*/, bool /*separate_file*/, + bool /*use_emergency_mask*/) +{ + if (file_stream_ == NULL) return; + + const TitanLoggerApi::LogEventType_choice& choice = event.logEvent().choice(); + + switch (choice.get_selection()) { + case TitanLoggerApi::LogEventType_choice::ALT_testcaseOp: { + const TitanLoggerApi::TestcaseEvent_choice& tcev = choice.testcaseOp().choice(); + + switch (tcev.get_selection()) { + case TitanLoggerApi::TestcaseEvent_choice::ALT_testcaseStarted: { + testcase.tc_name = tcev.testcaseStarted().testcase__name(); + // remember the start time + testcase.tc_start = 1000000LL * (long long)event.timestamp().seconds() + (long long)event.timestamp().microSeconds(); + break; } + + case TitanLoggerApi::TestcaseEvent_choice::ALT_testcaseFinished: { + const TitanLoggerApi::TestcaseType& tct = tcev.testcaseFinished(); + testcase.reason = tct.reason(); + testcase.module_name = tct.name().module__name(); + + const TitanLoggerApi::TimestampType& ts = event.timestamp(); + long long tc_end = 1000000LL * (long long)ts.seconds() + (long long)ts.microSeconds(); + testcase.time = (tc_end - testcase.tc_start) / 1000000.0; + + testcase.setTCVerdict(event); + testcase.dte_reason = dte_reason.data(); + dte_reason = ""; + testsuite.addTestCase(testcase); + testcase.reset(); + break; } + + case TitanLoggerApi::TestcaseEvent_choice::UNBOUND_VALUE: + testcase.verdict = TestCase::Unbound; + break; } // switch testcaseOp().choice.get_selection() + + break; } // testcaseOp + + case TitanLoggerApi::LogEventType_choice::ALT_errorLog: {// A DTE is about to be thrown + const TitanLoggerApi::Categorized& cat = choice.errorLog(); + dte_reason = escape_xml_element(cat.text()); + break; } + + default: break; + } // switch event.logEvent().choice().get_selection() + + fflush(file_stream_); +} + +CHARSTRING JUnitLogger2::escape_xml(const CHARSTRING& xml_str, int escape_chars) { + expstring_t escaped = NULL; + int len = xml_str.lengthof(); + for (int i=0; i<len; i++) { + char c = *(((const char*)xml_str)+i); + switch (c) { + case '<': + if (escape_chars<) escaped = mputstr(escaped, "<"); + else escaped = mputc(escaped, c); + break; + case '>': + if (escape_chars>) escaped = mputstr(escaped, ">"); + else escaped = mputc(escaped, c); + break; + case '"': + if (escape_chars") escaped = mputstr(escaped, """); + else escaped = mputc(escaped, c); + break; + case '\'': + if (escape_chars&APOS) escaped = mputstr(escaped, "'"); + else escaped = mputc(escaped, c); + break; + case '&': + if (escape_chars&) escaped = mputstr(escaped, "&"); + else escaped = mputc(escaped, c); + break; + default: + escaped = mputc(escaped, c); + } + } + CHARSTRING ret_val(escaped); + Free(escaped); + return ret_val; +} + +void TestCase::writeTestCase(FILE* file_stream_) const{ + switch(verdict){ + case None: { + fprintf(file_stream_, " <testcase classname='%s' name='%s' time='%f'>\n", module_name.data(), tc_name.data(), time); + fprintf(file_stream_, " <skipped>no verdict</skipped>\n"); + fprintf(file_stream_, " </testcase>\n"); + break; } + case Fail: { + fprintf(file_stream_, " <testcase classname='%s' name='%s' time='%f'>\n", module_name.data(), tc_name.data(), time); + fprintf(file_stream_, " <failure type='fail-verdict'>%s\n", reason.data()); + fprintf(file_stream_, "%s\n", stack_trace.data()); + fprintf(file_stream_, " </failure>\n"); + fprintf(file_stream_, " </testcase>\n"); + break; } + case Error: { + fprintf(file_stream_, " <testcase classname='%s' name='%s' time='%f'>\n", module_name.data(), tc_name.data(), time); + fprintf(file_stream_, " <error type='DTE'>%s</error>\n", dte_reason.data()); + fprintf(file_stream_, " </testcase>\n"); + break; } + default: + fprintf(file_stream_, " <testcase classname='%s' name='%s' time='%f'/>\n", module_name.data(), tc_name.data(), time); + break; + } + fflush(file_stream_); +} + +void TestSuite::addTestCase(const TestCase& testcase) { + testcases.push_back(new TestCase(testcase)); + all++; + switch(testcase.verdict) { + case TestCase::Fail: failed++; break; + case TestCase::None: skipped++; break; + case TestCase::Error: error++; break; + case TestCase::Inconc: inconc++; break; + default: break; + } +} + +void TestSuite::write(FILE* file_stream_) { + double difftime_ = difftime(end_ts, start_ts); + fprintf(file_stream_, "<?xml version=\"1.0\"?>\n" + "<testsuite name='%s' tests='%d' failures='%d' errors='%d' skipped='%d' inconc='%d' time='%.2f'>\n", + ts_name.data(), all, failed, error, skipped, inconc, difftime_); + fflush(file_stream_); + + for (TestCases::const_iterator it = testcases.begin(); it != testcases.end(); ++it) { + (*it)->writeTestCase(file_stream_); + } + + fprintf(file_stream_, "</testsuite>\n"); + fflush(file_stream_); +} + +void TestCase::setTCVerdict(const TitanLoggerApi::TitanLogEvent& event){ + TitanLoggerApi::Verdict tc_verdict = event.logEvent().choice().testcaseOp().choice().testcaseFinished().verdict(); + switch (tc_verdict) { + case TitanLoggerApi::Verdict::UNBOUND_VALUE: + case TitanLoggerApi::Verdict::UNKNOWN_VALUE: + // should not happen + break; + + case TitanLoggerApi::Verdict::v0none: + verdict = TestCase::None; + break; + + case TitanLoggerApi::Verdict::v1pass: + verdict = TestCase::Pass; + break; + + case TitanLoggerApi::Verdict::v2inconc: + verdict = TestCase::Inconc; + break; + + case TitanLoggerApi::Verdict::v3fail: { + verdict = TestCase::Fail; + addStackTrace(event); + break; } + + case TitanLoggerApi::Verdict::v4error: + verdict = TestCase::Error; + break; + } +} + +void TestCase::addStackTrace(const TitanLoggerApi::TitanLogEvent& event){ +// Add a stack trace + const TitanLoggerApi::TitanLogEvent_sourceInfo__list& stack = event.sourceInfo__list(); + + int stack_depth = stack.size_of(); + for (int i=0; i < stack_depth; ++i) { + const TitanLoggerApi::LocationInfo& location = stack[i]; + + stack_trace += " "; + stack_trace += location.filename(); + stack_trace += ":"; + stack_trace += int2str(location.line()); + stack_trace += " "; + stack_trace += location.ent__name(); + stack_trace += " "; + + // print the location type + switch (location.ent__type()) { + case TitanLoggerApi::LocationInfo_ent__type:: UNKNOWN_VALUE: + case TitanLoggerApi::LocationInfo_ent__type:: UNBOUND_VALUE: + // can't happen + break; + case TitanLoggerApi::LocationInfo_ent__type::unknown: + // do nothing + break; + case TitanLoggerApi::LocationInfo_ent__type::controlpart: + stack_trace += "control part"; + break; + case TitanLoggerApi::LocationInfo_ent__type::testcase__: + stack_trace += "testcase"; + break; + case TitanLoggerApi::LocationInfo_ent__type::altstep__: + stack_trace += "altstep"; + break; + case TitanLoggerApi::LocationInfo_ent__type::function__: + stack_trace += "function"; + break; + case TitanLoggerApi::LocationInfo_ent__type::external__function: + stack_trace += "external function"; + break; + case TitanLoggerApi::LocationInfo_ent__type::template__: + stack_trace += "template"; + break; + } + + if(i<stack_depth-1) stack_trace += "\n"; + } +} diff --git a/loggerplugins/JUnitLogger2/JUnitLogger2.hh b/loggerplugins/JUnitLogger2/JUnitLogger2.hh new file mode 100644 index 000000000..702981540 --- /dev/null +++ b/loggerplugins/JUnitLogger2/JUnitLogger2.hh @@ -0,0 +1,119 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2000-2014 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 +/////////////////////////////////////////////////////////////////////////////// +#ifndef JUnitLogger_HH2 +#define JUnitLogger_HH2 + +namespace TitanLoggerApi { class TitanLogEvent; } + +#ifndef TITAN_RUNTIME_2 +#include "RT1/TitanLoggerApi.hh" +#else +#include "RT2/TitanLoggerApi.hh" +#endif + +#include "ILoggerPlugin.hh" +#include <stdio.h> +#include <string> +#include <vector> + +struct TestCase{ + typedef enum { + Pass, + Inconc, + Fail, + Error, + None, + Unbound + } Verdict; + + Verdict verdict; + std::string tc_name; + std::string module_name; + std::string reason; + std::string dte_reason; + std::string stack_trace; + long long tc_start; + double time; + + TestCase():tc_name(""), module_name(""), reason(""), dte_reason(""), stack_trace(""), tc_start(0), time(0.0){} + + void writeTestCase(FILE* file_stream_) const; + void setTCVerdict(const TitanLoggerApi::TitanLogEvent& event); + void addStackTrace(const TitanLoggerApi::TitanLogEvent& event); + void reset() { + tc_name = ""; + module_name = ""; + reason = ""; + dte_reason = ""; + stack_trace = ""; + tc_start = 0; + time = 0.0; + } +}; + + +struct TestSuite { + typedef std::vector<TestCase*> TestCases; + +// TitanLoggerApi::TimestampType timestamp; TODO + std::string ts_name; + int all; + int skipped; + int failed; + int error; + int inconc; + TestCases testcases; + time_t start_ts; + time_t end_ts; + + TestSuite():ts_name(""), all(0), skipped(0), failed(0), error(0), inconc(0) {} + ~TestSuite(); + + void addTestCase(const TestCase& element); + void write(FILE* file_stream_); + +}; + +class JUnitLogger2: public ILoggerPlugin +{ +public: + JUnitLogger2(); + virtual ~JUnitLogger2(); + inline bool is_static() { return false; } + void init(const char *options = 0); + void fini(); + + void log(const TitanLoggerApi::TitanLogEvent& event, bool log_buffered, + bool separate_file, bool use_emergency_mask); + void set_parameter(const char *parameter_name, const char *parameter_value); + // do not implement ILoggerPlugin::set_file_name(); + // it gets a filename skeleton and can't expand it. + + virtual void open_file(bool /*is_first*/); + virtual void close_file(); + + enum xml_escape_char_t { LT=0x01, GT=0x02, QUOT=0x04, APOS=0x08, AMP=0x10 }; + CHARSTRING escape_xml(const CHARSTRING& xml_str, int escape_chars); + CHARSTRING escape_xml_attribute(const CHARSTRING& attr_str) { return escape_xml(attr_str, QUOT|AMP); } + CHARSTRING escape_xml_element(const CHARSTRING& elem_str) { return escape_xml(elem_str, LT|AMP); } + CHARSTRING escape_xml_comment(const CHARSTRING& comm_str) { return escape_xml(comm_str, AMP); /* FIXME: --> should be escaped too */ } + +private: + // parameters + char *filename_stem_; + char *testsuite_name_; + // working values + char *filename_; + TestSuite testsuite; + TestCase testcase; + std::string dte_reason; + + FILE *file_stream_; +}; + +#endif // JUnitLogger_HH2 diff --git a/loggerplugins/JUnitLogger2/Makefile b/loggerplugins/JUnitLogger2/Makefile new file mode 100644 index 000000000..98bb5751e --- /dev/null +++ b/loggerplugins/JUnitLogger2/Makefile @@ -0,0 +1,96 @@ +############################################################################### +# Copyright (c) 2000-2014 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 +############################################################################### +# Makefile for the JUnitLogger2 plugin. Unfortunately, we'll need four different +# libraries for each plugin... Plugin version information must be +# synchronized with the code. + +TOP := ../.. +include ../../Makefile.cfg + +LIB_DIR := $(TTCN3_DIR)/lib + +MAJOR := 0 +MINOR := 0 + +SOURCES := JUnitLogger2.cc +STATIC_SOURCES := ${SOURCES} +HEADERS := $(SOURCES:.cc=.hh) +OBJECTS := $(SOURCES:.cc=.o) +OBJECTS_RT2 := $(addprefix FT/,$(OBJECTS)) + +SHARED_LIB := libjunitlogger2.so +SHARED_LIB_RT2 := libjunitlogger2-rt2.so +SHARED_LIB_PARALLEL := libjunitlogger2-parallel.so +SHARED_LIB_PARALLEL_RT2 := libjunitlogger2-parallel-rt2.so + +CPPFLAGS += -I../../core -I$(ABS_SRC)/../../common -I$(ABS_SRC)/../../core +# RT2 needs core2 (for RT2/TitanLoggerAPI.hh) in addition to core +CPPFLAGS_RT2 := $(CPPFLAGS) -I$(ABS_SRC)/../../core2 -DTITAN_RUNTIME_2 + +CXXFLAGS += -Werror + +LDFLAGS += -g -L$(ABS_SRC)/../../core -Wl,-soname,$(SHARED_LIB).$(MAJOR) -o $(SHARED_LIB).$(MAJOR).$(MINOR) +LDFLAGS_RT2 += -g -L$(ABS_SRC)/../../core2 -Wl,-soname,$(SHARED_LIB_RT2).$(MAJOR) -o $(SHARED_LIB_RT2).$(MAJOR).$(MINOR) +LDFLAGS_PARALLEL += -g -L$(ABS_SRC)/../../core -Wl,-soname,$(SHARED_LIB_PARALLEL).$(MAJOR) -o $(SHARED_LIB_PARALLEL).$(MAJOR).$(MINOR) +LDFLAGS_PARALLEL_RT2 += -g -L$(ABS_SRC)/../../core2 -Wl,-soname,$(SHARED_LIB_PARALLEL_RT2).$(MAJOR) -o $(SHARED_LIB_PARALLEL_RT2).$(MAJOR).$(MINOR) + +LIBS := -lttcn3-dynamic +LIBS_RT2 := -lttcn3-rt2-dynamic +LIBS_PARALLEL := -lttcn3-parallel-dynamic +LIBS_PARALLEL_RT2 := -lttcn3-rt2-parallel-dynamic + +TARGETS := $(SHARED_LIB) $(SHARED_LIB_PARALLEL) $(SHARED_LIB_RT2) $(SHARED_LIB_PARALLEL_RT2) +# .so with .major appended: +TARGETS_MAJOR := $(addsuffix .$(MAJOR), $(TARGETS)) +# .so with .major.minor appended: +TARGETS_MAJOR_MINOR := $(addsuffix .$(MINOR), $(TARGETS_MAJOR)) + +# OBJECTS_RT2, TARGETS_MAJOR and TARGETS_MAJOR_MINOR are non-standard make variables, +# not taken into account by "clean" in Makefile.genrules +# Delete them as "miscellaneous" files. +TOBECLEANED := $(OBJECTS_RT2) $(TARGETS_MAJOR) $(TARGETS_MAJOR_MINOR) + +all run: $(TARGETS) + +$(SHARED_LIB): $(OBJECTS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $? $(LIBS) -shared + ln -sf $@.$(MAJOR).$(MINOR) $@.$(MAJOR) + ln -sf $@.$(MAJOR) $@ + +$(SHARED_LIB_RT2): $(OBJECTS_RT2) + $(CXX) $(CPPFLAGS_RT2) $(CXXFLAGS) $(LDFLAGS_RT2) $? $(LIBS_RT2) -shared + ln -sf $@.$(MAJOR).$(MINOR) $@.$(MAJOR) + ln -sf $@.$(MAJOR) $@ + +$(SHARED_LIB_PARALLEL): $(OBJECTS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS_PARALLEL) $? $(LIBS_PARALLEL) -shared + ln -sf $@.$(MAJOR).$(MINOR) $@.$(MAJOR) + ln -sf $@.$(MAJOR) $@ + +$(SHARED_LIB_PARALLEL_RT2): $(OBJECTS_RT2) + $(CXX) $(CPPFLAGS_RT2) $(CXXFLAGS) $(LDFLAGS_PARALLEL_RT2) $? $(LIBS_PARALLEL_RT2) -shared + ln -sf $@.$(MAJOR).$(MINOR) $@.$(MAJOR) + ln -sf $@.$(MAJOR) $@ + +$(OBJECTS): $(SOURCES) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $? + +# The `-o $@' stuff is necessary, otherwise the result will be put into the +# current directory. +$(OBJECTS_RT2): $(SOURCES) + mkdir -p FT + $(CXX) $(CPPFLAGS_RT2) $(CXXFLAGS) -c $? -o $@ + +dep: + @echo Doing nothing... + +install: $(SHARED_LIB) $(SHARED_LIB_RT2) $(SHARED_LIB_PARALLEL) $(SHARED_LIB_PARALLEL_RT2) + mkdir -p $(LIB_DIR) + cp $(SHARED_LIB)* $(SHARED_LIB_RT2)* $(SHARED_LIB_PARALLEL)* $(SHARED_LIB_PARALLEL_RT2)* $(LIB_DIR) + +include ../../Makefile.genrules diff --git a/loggerplugins/Makefile b/loggerplugins/Makefile index 0d1dd8bed..19b40d502 100644 --- a/loggerplugins/Makefile +++ b/loggerplugins/Makefile @@ -6,7 +6,7 @@ # http://www.eclipse.org/legal/epl-v10.html ############################################################################### DIRS := \ -JUnitLogger TSTLogger +JUnitLogger TSTLogger JUnitLogger2 all run dep clean distclean install: for d in $(DIRS); do $(MAKE) -C $$d $@ || exit 1; done diff --git a/loggerplugins/TSTLogger/TSTLogger.cc b/loggerplugins/TSTLogger/TSTLogger.cc index 5d1514e26..c29a2736e 100644 --- a/loggerplugins/TSTLogger/TSTLogger.cc +++ b/loggerplugins/TSTLogger/TSTLogger.cc @@ -20,6 +20,7 @@ #include <errno.h> #include <string.h> #include <netdb.h> +#include <sys/select.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> diff --git a/mctr2/cli/config_read.l b/mctr2/cli/config_read.l index be8c19348..12978bdb7 100644 --- a/mctr2/cli/config_read.l +++ b/mctr2/cli/config_read.l @@ -323,6 +323,12 @@ IPV6 [0-9A-Fa-f:.]+(%[0-9A-Za-z]+)? /* SC_cstring */ +<SC_PROFILER>{HEX}+ { + /* numeric statistics filter (check this before checking NUMBERs) */ + RETURN(ProfilerStatsFlag); +} + + /* Values */ {NUMBER} { @@ -560,12 +566,56 @@ WARNING_UNQUALIFIED RETURN(LoggingBit); <SC_PROFILER> { -[Dd]isable[Pp]rofiler return DisableProfilerKeyword; -[Dd]isable[Cc]overage return DisableCoverageKeyword; -[Dd]ata[Bb]ase[Ff]ile return DatabaseFileKeyword; -[Aa]ggregate[Dd]ata return AggregateDataKeyword; -[Ss]tatistics[Ff]ile return StatisticsFileKeyword; -[Dd]isable[Ss]tatistics return DisableStatisticsKeyword; + [Dd]isable[Pp]rofiler RETURN(DisableProfilerKeyword); + [Dd]isable[Cc]overage RETURN(DisableCoverageKeyword); + [Dd]ata[Bb]ase[Ff]ile RETURN(DatabaseFileKeyword); + [Aa]ggregate[Dd]ata RETURN(AggregateDataKeyword); + [Ss]tatistics[Ff]ile RETURN(StatisticsFileKeyword); + [Dd]isable[Ss]tatistics RETURN(DisableStatisticsKeyword); + [Ss]tatistics[Ff]ilter RETURN(StatisticsFilterKeyword); + [Ss]tart[Aa]utomatically RETURN(StartAutomaticallyKeyword); + [Nn]et[Ll]ine[Tt]imes RETURN(NetLineTimesKeyword); + [Nn]et[Ff]unction[Tt]imes RETURN(NetFunctionTimesKeyword); + + /* statistics filters */ + [Nn]umber[Oo]f[Ll]ines | + [Ll]ine[Dd]ata[Rr]aw | + [Ff]unc[Dd]ata[Rr]aw | + [Ll]ine[Aa]vg[Rr]aw | + [Ff]unc[Aa]vg[Rr]aw | + [Ll]ine[Tt]imes[Ss]orted[Bb]y[Mm]od | + [Ff]unc[Tt]imes[Ss]orted[Bb]y[Mm]od | + [Ll]ine[Tt]imes[Ss]orted[Tt]otal | + [Ff]unc[Tt]imes[Ss]orted[Tt]otal | + [Ll]ine[Cc]ount[Ss]orted[Bb]y[Mm]od | + [Ff]unc[Cc]ount[Ss]orted[Bb]y[Mm]od | + [Ll]ine[Cc]ount[Ss]orted[Tt]otal | + [Ff]unc[Cc]ount[Ss]orted[Tt]otal | + [Ll]ine[Aa]vg[Ss]orted[Bb]y[Mm]od | + [Ff]unc[Aa]vg[Ss]orted[Bb]y[Mm]od | + [Ll]ine[Aa]vg[Ss]orted[Tt]otal | + [Ff]unc[Aa]vg[Ss]orted[Tt]otal | + [Tt]op10[Ll]ine[Tt]imes | + [Tt]op10[Ff]unc[Tt]imes | + [Tt]op10[Ll]ine[Cc]ount | + [Tt]op10[Ff]unc[Cc]ount | + [Tt]op10[Ll]ine[Aa]vg | + [Tt]op10[Ff]unc[Aa]vg | + [Uu]nused[Ll]ines | + [Uu]nused[Ff]unc | + [Aa]ll[Rr]aw[Dd]ata | + [Ll]ine[Dd]ata[Ss]orted[Bb]y[Mm]od | + [Ff]unc[Dd]ata[Ss]orted[Bb]y[Mm]od | + [Ll]ine[Dd]ata[Ss]orted[Tt]otal | + [Ff]unc[Dd]ata[Ss]orted[Tt]otal | + [Ll]ine[Dd]ata[Ss]orted | + [Ff]unc[Dd]ata[Ss]orted | + [Aa]ll[Dd]ata[Ss]orted | + [Tt]op10[Ll]ine[Dd]ata | + [Tt]op10[Ff]unc[Dd]ata | + [Tt]op10[Aa]ll[Dd]ata | + [Uu]nused[Dd]ata | + [Aa]ll RETURN(ProfilerStatsFlag); } <SC_EXECUTE>control RETURN(ControlKeyword); @@ -935,6 +985,7 @@ static boolean whether_update_buffer() case SC_LOGGING: case SC_TESTPORT_PARAMETERS: case SC_EXTERNAL_COMMANDS: + case SC_PROFILER: return TRUE; default: return FALSE; diff --git a/mctr2/cli/config_read.y b/mctr2/cli/config_read.y index 496d4f399..fa787f2a2 100644 --- a/mctr2/cli/config_read.y +++ b/mctr2/cli/config_read.y @@ -165,12 +165,17 @@ static void yyprint(FILE *file, int type, const YYSTYPE& value); %token Re_try /* Retry clashes with an enum in Qt */ %token Delete -%token DisableProfilerKeyword "DisableProfiler" -%token DisableCoverageKeyword "DisableCoverage" -%token DatabaseFileKeyword "DatabaseFile" -%token AggregateDataKeyword "AggregateData" -%token StatisticsFileKeyword "StatisticsFile" -%token DisableStatisticsKeyword "DisableStatistics" +%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 flag" %type <int_val> IntegerValue %type <float_val> FloatValue KillTimerValue @@ -706,6 +711,10 @@ ProfilerSetting: | AggregateDataSetting | StatisticsFileSetting | DisableStatisticsSetting +| StatisticsFilterSetting +| StartAutomaticallySetting +| NetLineTimesSetting +| NetFunctionTimesSetting ; DisableProfilerSetting: @@ -732,6 +741,29 @@ DisableStatisticsSetting: DisableStatisticsKeyword AssignmentChar BooleanValue ; +StatisticsFilterSetting: + StatisticsFilterKeyword AssignmentChar ProfilerStatsFlags +| StatisticsFilterKeyword ConcatChar ProfilerStatsFlags +; + +ProfilerStatsFlags: + ProfilerStatsFlag +| ProfilerStatsFlag '&' ProfilerStatsFlags +| ProfilerStatsFlag '|' ProfilerStatsFlags +; + +StartAutomaticallySetting: + StartAutomaticallyKeyword AssignmentChar BooleanValue +; + +NetLineTimesSetting: + NetLineTimesKeyword AssignmentChar BooleanValue +; + +NetFunctionTimesSetting: + NetFunctionTimesKeyword AssignmentChar BooleanValue +; + /******************* [TESTPORT_PARAMETERS] section *******************/ TestportParametersSection: diff --git a/mctr2/mctr/MainController.cc b/mctr2/mctr/MainController.cc index 9a7ae8abe..e5d0ca05d 100644 --- a/mctr2/mctr/MainController.cc +++ b/mctr2/mctr/MainController.cc @@ -121,6 +121,7 @@ void MainController::add_poll_fd(int fd) { if (fd < 0) return; epoll_event event; + memset(&event,0,sizeof(event)); event.events = EPOLLIN; event.data.fd = fd; if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event) < 0) @@ -132,6 +133,7 @@ void MainController::remove_poll_fd(int fd) { if (fd < 0) return; epoll_event event; + memset(&event,0,sizeof(event)); event.events = EPOLLIN; event.data.fd = fd; if (epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &event) < 0) diff --git a/mctr2/mctr/ttcn3_start b/mctr2/mctr/ttcn3_start index 700b98422..960342c60 100755 --- a/mctr2/mctr/ttcn3_start +++ b/mctr2/mctr/ttcn3_start @@ -63,11 +63,12 @@ proc wait_mc_prompt {} { proc error_cleanup {error_msg error_retcode} { global mctr_id hc_id + puts "ttcn3_start: error: $error_msg" send -i $mctr_id "exit\r" expect -i $mctr_id eof + expect -i $hc_id eof wait -i $hc_id wait -i $mctr_id - puts "ttcn3_start: error: $error_msg" exit $error_retcode } @@ -245,6 +246,8 @@ expect { } -i $hc_id -re ".*\r" { exp_continue } -i $mctr_id "New HC connected from " { + } -i $hc_id eof { + error_cleanup "Host Controller with id $hc_id stopped unexpectedly" 10 } } diff --git a/regression_test/Makefile b/regression_test/Makefile index 1cf8b9a6a..4b85e6ded 100644 --- a/regression_test/Makefile +++ b/regression_test/Makefile @@ -21,7 +21,7 @@ nonMandatoryPar logFiles logger_control namedActualParameters \ assignmentNotation omitdef anytype RAW implicitMsgEncoding pattern_quadruples \ macros visibility hexstrOper ucharstrOper objidOper CRTR00015758 slider \ XML ipv6 implicitOmit testcase_defparam transparent HQ16404 cfgFile \ -all_from lazyEval tryCatch text2ttcn json junitlogger ttcn2json +all_from lazyEval tryCatch text2ttcn json junitlogger ttcn2json profiler ifdef DYN DIRS += loggerplugin diff --git a/regression_test/XML/EXER-whitepaper/EmbedValues.ttcnpp b/regression_test/XML/EXER-whitepaper/EmbedValues.ttcnpp index fc5cb934a..47007d004 100644 --- a/regression_test/XML/EXER-whitepaper/EmbedValues.ttcnpp +++ b/regression_test/XML/EXER-whitepaper/EmbedValues.ttcnpp @@ -219,6 +219,94 @@ testcase decode_emb_array() runs on EMB CHECK_DECODE(exer_dec_emb_outer, str_emb_array_w_holes, Outer, c_emb_array_w_holes); } +// same as before, but the embedded values are stored in an optimized record-of +type record Outer2 { + record of universal charstring embed_values, + integer attr, + octetstring bytes, + RoInner stuff +} with { + variant "name as 'Outer'"; + extension(embed_values) "optimize:memalloc"; + variant "embedValues"; + variant(attr) "attribute"; + variant(bytes) "name as 'Bytes'"; + variant(stuff) "untagged"; +} + +DECLARE_EXER_ENCODERS(Outer2, emb_outer2); + +const Outer2 c_emb_array2 := { + embed_values := { "one", "two", "three", "four", "five", "six" }, + attr := 48, + bytes := 'DEADBEEF'O, + stuff := { { 3, "abc" }, { 4, "def" }, { -6, "red" }, { 118, "blue" } } +} + +const Outer2 c_emb_array_w_holes2 := { + embed_values := { "one", "", "three", "", "five" }, + attr := 48, + bytes := 'DEADBEEF'O, + stuff := { { 3, "abc" }, { 4, "def" }, { -6, "red" }, { 118, "blue" } } +} + +testcase encode_emb_array_opt() runs on EMB +{ + CHECK_METHOD(exer_enc_emb_outer2, c_emb_array2, str_emb_array); + CHECK_METHOD(exer_enc_emb_outer2, c_emb_array_w_holes2, str_emb_array_w_holes); +} + +testcase decode_emb_array_opt() runs on EMB +{ + CHECK_DECODE(exer_dec_emb_outer2, str_emb_array, Outer2, c_emb_array2); + CHECK_DECODE(exer_dec_emb_outer2, str_emb_array_w_holes, Outer2, c_emb_array_w_holes2); +} + +// same as before, but one of the embedded record-ofs is optimized +type record length (1..infinity) of Inner RoInner2 with { extension "optimize:memalloc" }; + +type record Outer3 { + record of universal charstring embed_values, + integer attr, + octetstring bytes, + RoInner2 stuff +} with { + variant "name as 'Outer'"; + extension(embed_values) "optimize:memalloc"; + variant "embedValues"; + variant(attr) "attribute"; + variant(bytes) "name as 'Bytes'"; + variant(stuff) "untagged"; +} + +DECLARE_EXER_ENCODERS(Outer3, emb_outer3); + +const Outer3 c_emb_array3 := { + embed_values := { "one", "two", "three", "four", "five", "six" }, + attr := 48, + bytes := 'DEADBEEF'O, + stuff := { { 3, "abc" }, { 4, "def" }, { -6, "red" }, { 118, "blue" } } +} + +const Outer3 c_emb_array_w_holes3 := { + embed_values := { "one", "", "three", "", "five" }, + attr := 48, + bytes := 'DEADBEEF'O, + stuff := { { 3, "abc" }, { 4, "def" }, { -6, "red" }, { 118, "blue" } } +} + +testcase encode_emb_array_opt2() runs on EMB +{ + CHECK_METHOD(exer_enc_emb_outer3, c_emb_array3, str_emb_array); + CHECK_METHOD(exer_enc_emb_outer3, c_emb_array_w_holes3, str_emb_array_w_holes); +} + +testcase decode_emb_array_opt2() runs on EMB +{ + CHECK_DECODE(exer_dec_emb_outer3, str_emb_array, Outer3, c_emb_array3); + CHECK_DECODE(exer_dec_emb_outer3, str_emb_array_w_holes, Outer3, c_emb_array_w_holes3); +} + control { execute(encode_emb()); execute(decode_emb()); @@ -226,8 +314,12 @@ control { execute(decode_emb_all()); execute(encode_emb_any()); execute(decode_emb_any()); - //execute(encode_emb_array()); - this functionality was temporarily removed in RT1 - //execute(decode_emb_array()); + execute(encode_emb_array()); + execute(decode_emb_array()); + execute(encode_emb_array_opt()); + execute(decode_emb_array_opt()); + execute(encode_emb_array_opt2()); + execute(decode_emb_array_opt2()); } } diff --git a/regression_test/XML/TTCNandXML/Makefile b/regression_test/XML/TTCNandXML/Makefile index 8ae35fd85..8fff1eb67 100644 --- a/regression_test/XML/TTCNandXML/Makefile +++ b/regression_test/XML/TTCNandXML/Makefile @@ -41,7 +41,7 @@ CPPFLAGS += -D$(PLATFORM) CXXFLAGS += -g -W -Wformat=2 # Flags for the linker: -LDFLAGS += -g -rdynamic +#LDFLAGS += -g -rdynamic WIN32_LIBS += -liconv FREEBSD_LIBS += -liconv diff --git a/regression_test/XML/XER/checkit.pl b/regression_test/XML/XER/checkit.pl index 6c9e7aaf3..893350c80 100755 --- a/regression_test/XML/XER/checkit.pl +++ b/regression_test/XML/XER/checkit.pl @@ -51,6 +51,7 @@ my %versions = ( # built-in modules for the logger 'TitanLoggerApi' => '', 'TitanLoggerControl' => '', +'PreGenRecordOf' => '', ); diff --git a/regression_test/all_from/all_from_subtype.ttcn b/regression_test/all_from/all_from_subtype.ttcn new file mode 100644 index 000000000..421e9c11a --- /dev/null +++ b/regression_test/all_from/all_from_subtype.ttcn @@ -0,0 +1,191 @@ +/****************************************************************************** + * Copyright (c) 2000-2015 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 + ******************************************************************************/ + +// subtyping and the 'all from' clause +module all_from_subtype { + +import from types all; +import from functions all; + +/* * * * integer * * * */ +template RoI t_RoI1 := { 1, 2, (6..9) }; +template RoI t_RoI2 := { 1, ?, 3 }; +const RoI c_RoI := { 20, 21, 22 }; + +template PosInt t_posint1 := (0, all from t_RoI1); +template PosInt t_posint1_exp := (0, 1, 2, (6..9)); + +template PosInt t_posint2 := (all from c_RoI, 50, 100); +template PosInt t_posint2_exp := (20, 21, 22, 50, 100); + +template PosInt t_posint3 := (10, all from c_RoI, 30, all from t_RoI1); +template PosInt t_posint3_exp := (10, 20, 21, 22, 30, 1, 2, (6..9)); + +template ShortRoI t_sroi1 := { 0, (all from t_RoI1, 10), 20 }; +template ShortRoI t_sroi1_exp := { 0, (1, 2, (6..9), 10), 20 }; + +template ShortRoI t_sroi2 := ( { 1, 2, 3 }, { permutation (all from t_RoI2) } ); +template ShortRoI t_sroi2_exp := ( { 1, 2, 3 }, { permutation (1, ?, 3) } ); + +testcase tc_all_from_subtype_integer() runs on A +{ + if (log2str(t_posint1) != log2str(t_posint1_exp)) { + setverdict(fail, "Expected: ", t_posint1_exp, ", got: ", t_posint1); + } + if (log2str(t_posint2) != log2str(t_posint2_exp)) { + setverdict(fail, "Expected: ", t_posint2_exp, ", got: ", t_posint2); + } + if (log2str(t_posint3) != log2str(t_posint3_exp)) { + setverdict(fail, "Expected: ", t_posint3_exp, ", got: ", t_posint3); + } + if (log2str(t_sroi1) != log2str(t_sroi1_exp)) { + setverdict(fail, "Expected: ", t_sroi1_exp, ", got: ", t_sroi1); + } + if (log2str(t_sroi2) != log2str(t_sroi2_exp)) { + setverdict(fail, "Expected: ", t_sroi2_exp, ", got: ", t_sroi2); + } + setverdict(pass); +} + +/* * * * float * * * */ +template RoF t_RoF := { (-10.0..-2.5), -1.0, 0.0 }; +const RoF c_RoF := { -0.3, -0.2, -0.1 }; + +template NegFloat t_negfloat := (all from t_RoF, -2.0, all from c_RoF, -100.0); +template NegFloat t_negfloat_exp := ((-10.0..-2.5), -1.0, 0.0, -2.0, -0.3, -0.2, -0.1, -100.0); + +template ShortRoF t_srof := { permutation (all from c_RoF) }; +template ShortRoF t_srof_exp := { permutation (-0.3, -0.2, -0.1) }; + +testcase tc_all_from_subtype_float() runs on A +{ + if (log2str(t_negfloat) != log2str(t_negfloat_exp)) { + setverdict(fail, "Expected: ", t_negfloat_exp, ", got: ", t_negfloat); + } + if (log2str(t_srof) != log2str(t_srof_exp)) { + setverdict(fail, "Expected: ", t_srof_exp, ", got: ", t_srof); + } + setverdict(pass); +} + +/* * * * bitstring * * * */ +template RoBS t_RoBS := { '1010'B, ? }; +const RoBS c_RoBS := { '11011000'B, '00110011'B, '10101010'B }; + +template ByteString t_bytestr := ('00000000'B, all from c_RoBS, '11111111'B); +template ByteString t_bytestr_exp := ('00000000'B, '11011000'B, '00110011'B, '10101010'B, '11111111'B); + +template ShortRoBS t_srobs := { '1'B, permutation (all from t_RoBS) }; +template ShortRoBS t_srobs_exp := { '1'B, permutation ('1010'B, ?) }; + +testcase tc_all_from_subtype_bitstring() runs on A +{ + if (log2str(t_bytestr) != log2str(t_bytestr_exp)) { + setverdict(fail, "Expected: ", t_bytestr_exp, ", got: ", t_bytestr); + } + if (log2str(t_srobs) != log2str(t_srobs_exp)) { + setverdict(fail, "Expected: ", t_srobs_exp, ", got: ", t_srobs); + } + setverdict(pass); +} + +/* * * * hexstring * * * */ +template RoHS t_RoHS := { '100'H, 'ABC'H }; +const RoHS c_RoHS := { '19A6'H, '999D'H, '1337'H }; + +template WordString t_wordstr := ('A000'H, 'FFFF'H, all from c_RoHS, '0000'H); +template WordString t_wordstr_exp := ('A000'H, 'FFFF'H, '19A6'H, '999D'H, '1337'H, '0000'H); + +template ShortRoHS t_srohs := { permutation (all from t_RoHS, '180DD'H) }; +template ShortRoHS t_srohs_exp := { permutation ('100'H, 'ABC'H, '180DD'H) }; + +testcase tc_all_from_subtype_hexstring() runs on A +{ + if (log2str(t_wordstr) != log2str(t_wordstr_exp)) { + setverdict(fail, "Expected: ", t_wordstr_exp, ", got: ", t_wordstr); + } + if (log2str(t_srohs) != log2str(t_srohs_exp)) { + setverdict(fail, "Expected: ", t_srohs_exp, ", got: ", t_srohs); + } + setverdict(pass); +} + +/* * * * octetstring * * * */ +template RoOS t_RoOS := { '00'O, 'FF'O }; +const RoOS c_RoOS := { 'E77FB41C'O, 'DEADBEEF'O, 'CDCDCDCD'O }; + +template DWordString t_dwordstr := (all from c_RoOS, '0FFFFFFF'O); +template DWordString t_dwordstr_exp := ('E77FB41C'O, 'DEADBEEF'O, 'CDCDCDCD'O, '0FFFFFFF'O); + +template ShortRoOS t_sroos := { permutation (?, all from t_RoOS) }; +template ShortRoOS t_sroos_exp := { permutation (?, '00'O, 'FF'O) }; + +testcase tc_all_from_subtype_octetstring() runs on A +{ + if (log2str(t_dwordstr) != log2str(t_dwordstr_exp)) { + setverdict(fail, "Expected: ", t_dwordstr_exp, ", got: ", t_dwordstr); + } + if (log2str(t_sroos) != log2str(t_sroos_exp)) { + setverdict(fail, "Expected: ", t_sroos_exp, ", got: ", t_sroos); + } + setverdict(pass); +} + +/* * * * charstring * * * */ +template RoCS t_RoCS := { ("a".."z"), ("0".."9"), ("A".."Z") }; +const RoCS c_RoCS := { "all_from.ttcn", "types.ttcn", "functions.ttcn", "sapc.ttcn" }; + +template TtcnFileName t_ttcnfiles := (all from c_RoCS); +template TtcnFileName t_ttcnfiles_exp := ("all_from.ttcn", "types.ttcn", "functions.ttcn", "sapc.ttcn"); + +template ShortRoCS t_srocs := { permutation (all from t_RoCS) }; +template ShortRoCS t_srocs_exp := { permutation (("a".."z"), ("0".."9"), ("A".."Z")) }; + +testcase tc_all_from_subtype_charstring() runs on A +{ + if (log2str(t_ttcnfiles) != log2str(t_ttcnfiles_exp)) { + setverdict(fail, "Expected: ", t_ttcnfiles_exp, ", got: ", t_ttcnfiles); + } + if (log2str(t_srocs) != log2str(t_srocs_exp)) { + setverdict(fail, "Expected: ", t_srocs_exp, ", got: ", t_srocs); + } + setverdict(pass); +} + +/* * * * universal charstring * * * */ +template RoUCS t_RoUCS := { "abc", ?, "cba" }; +const RoUCS c_RoUCS := { "nothing", "special", "here" }; + +template XsdString t_xsdstr := (pattern "<*>", all from c_RoUCS); +template XsdString t_xsdstr_exp := (pattern "<*>", "nothing", "special", "here"); + +template ShortRoUCS t_sroucs := { all from t_RoUCS }; +template ShortRoUCS t_sroucs_exp := { "abc", ?, "cba" }; + +testcase tc_all_from_subtype_universal_charstring() runs on A +{ + if (log2str(t_xsdstr) != log2str(t_xsdstr_exp)) { + setverdict(fail, "Expected: ", t_xsdstr_exp, ", got: ", t_xsdstr); + } + if (log2str(t_sroucs) != log2str(t_sroucs_exp)) { + setverdict(fail, "Expected: ", t_sroucs_exp, ", got: ", t_sroucs); + } + setverdict(pass); +} + +control { + execute(tc_all_from_subtype_integer()); + execute(tc_all_from_subtype_float()); + execute(tc_all_from_subtype_bitstring()); + execute(tc_all_from_subtype_hexstring()); + execute(tc_all_from_subtype_octetstring()); + execute(tc_all_from_subtype_charstring()); + execute(tc_all_from_subtype_universal_charstring()); +} + +} diff --git a/regression_test/all_from/all_from_with_functions.ttcn b/regression_test/all_from/all_from_with_functions.ttcn index 134f2ecb7..5aaa17a6e 100644 --- a/regression_test/all_from/all_from_with_functions.ttcn +++ b/regression_test/all_from/all_from_with_functions.ttcn @@ -11,7 +11,7 @@ module all_from_with_functions { external function f_ext(in template RoI r) return template RoI; -type record of integer RoI; +type record of integer RoI with { encode "JSON" }; type set of integer SoI; type record Rec { @@ -119,10 +119,52 @@ testcase tc_all_from_func_params() runs on CT_Empty { else { setverdict(fail, "Expected: ", c_res_log, ", got: ", vt_res); } } +function f_non_templ(in RoI x) return RoI +{ + return x; +} + +external function f_dec_roi(in octetstring os) return RoI + with { extension "prototype(convert) decode(JSON)" } + +// all from used on regular (non-template) functions +testcase tc_all_from_with_functions2() runs on CT_Empty +{ + var template RoI vt_func_roi := { permutation ( all from f_non_templ( { 1, 4, 7, 10 } ) ) }; + var template integer vt_func_int := ( 0, 1, all from f_non_templ( { 3, 6, 9 } ) ); + + var octetstring v_enc := char2oct("[ 4, 2, 10, 100 ]"); + var template RoI vt_ext_func_roi := { permutation ( all from f_dec_roi(v_enc) ) }; + var template integer vt_ext_func_int := ( 0, 1, all from f_dec_roi(v_enc) ); + + var charstring v_res_log := "{ permutation(1, 4, 7, 10) }"; + if (log2str(vt_func_roi) != v_res_log) { + setverdict(fail, "Expected: ", v_res_log, ", got: ", vt_func_roi); + } + + v_res_log := "(0, 1, 3, 6, 9)"; + if (log2str(vt_func_int) != v_res_log) { + setverdict(fail, "Expected: ", v_res_log, ", got: ", vt_func_int); + } + + v_res_log := "{ permutation(4, 2, 10, 100) }"; + if (log2str(vt_ext_func_roi) != v_res_log) { + setverdict(fail, "Expected: ", v_res_log, ", got: ", vt_ext_func_roi); + } + + v_res_log := "(0, 1, 4, 2, 10, 100)"; + if (log2str(vt_ext_func_int) != v_res_log) { + setverdict(fail, "Expected: ", v_res_log, ", got: ", vt_ext_func_int); + } + + setverdict(pass); +} + control { execute(tc_all_from_with_functions()); execute(tc_all_from_func_params()); + execute(tc_all_from_with_functions2()); } } diff --git a/regression_test/all_from/types.ttcn b/regression_test/all_from/types.ttcn index 862f3de7c..cc8c2e8c0 100644 --- a/regression_test/all_from/types.ttcn +++ b/regression_test/all_from/types.ttcn @@ -16,6 +16,7 @@ type component A { type record of integer RoI; type set of integer SoI; +type record of float RoF; type record of SoI RoSoI; type record of RoI RoRoI; type record of RoOS RoRoOS; @@ -23,12 +24,18 @@ type record of SoOS RoSoOS; type set of integer MySetOfType (0 .. 10); +type record of bitstring RoBS; + +type record of hexstring RoHS; + type record of charstring RoCS; type set of charstring CoCS; type record of octetstring RoOS; type set of octetstring SoOS; +type record of universal charstring RoUCS; + type record MyRecord { integer i optional, RoI roi optional, @@ -80,4 +87,41 @@ type record CAI3gCommand { } */ +/* * * * Subtypes * * * */ + +type integer PosInt (0..infinity); + +type float NegFloat (-infinity..0.0); + +type bitstring ByteString length (8); + +type hexstring WordString length (4); + +type octetstring DWordString length (4); + +type charstring TtcnFileName (pattern "*.ttcn"); + +type universal charstring XsdString ( + char(0,0,0,9)..char(0,0,0,9), + char(0,0,0,10)..char(0,0,0,10), + char(0,0,0,12)..char(0,0,0,12), + char(0,0,0,32)..char(0,0,215,255), + char(0,0,224,0)..char(0,0,255,253), + char(0,1,0,0)..char(0,16,255,253) +); + +type record length (0..3) of integer ShortRoI; + +type record length (0..3) of float ShortRoF; + +type record length (0..3) of bitstring ShortRoBS; + +type record length (0..3) of hexstring ShortRoHS; + +type record length (0..3) of octetstring ShortRoOS; + +type record length (0..3) of charstring ShortRoCS; + +type record length (0..3) of universal charstring ShortRoUCS; + } diff --git a/regression_test/boolOper/TboolOper.ttcn b/regression_test/boolOper/TboolOper.ttcn index 602542aca..dabf6b61b 100644 --- a/regression_test/boolOper/TboolOper.ttcn +++ b/regression_test/boolOper/TboolOper.ttcn @@ -303,6 +303,60 @@ testcase boolIsvalue() runs on boolOper_comptype{ if ( isvalue(vt1) ) { setverdict(fail); } else { setverdict(pass); }; } +type union TestUnion { + integer t, + boolean b +} + +type record TestRecord { + integer t, + boolean b optional +} + +// for TR fix HT60781 +testcase boolShortCircuit() runs on boolOper_comptype { + // create a union variable, make sure the boolean field is not chosen + var TestUnion myUnion := { t := 1 }; + + // reference the boolean field in the 2nd part of a condition using 'and' or 'or' + // only the first part of the condition should be evaluated, since + // evaluating the 2nd part would produce a DTE (because the field isn't chosen) + if (ischosen(myUnion.b) and myUnion.b) { + setverdict(fail, "Error in 'if' condition, field 'b' is not supposed to be chosen"); + } + while (ischosen(myUnion.b) and myUnion.b) { + setverdict(fail, "Error in 'while' condition, field 'b' is not supposed to be chosen"); + } + var integer i; + for (i := 0; ischosen(myUnion.b) and myUnion.b and i < 5; i := i + 1) { + setverdict(fail, "Error in 'for' condition, field 'b' is not supposed to be chosen"); + } + var boolean res := not ischosen(myUnion.b) or myUnion.b; + if (not res) { + setverdict(fail, "Error in boolean assignment, field 'b' is not supposed to be chosen"); + } + + // create a record variable, make sure the boolean field is omitted + var TestRecord myRec := { t := 1, b := omit }; + + // reference the boolean field in the 2nd part of a condition, same as with the union field + // (referencing the boolean field would cause a DTE again, because it is omitted) + if (ispresent(myRec.b) and myRec.b) { + setverdict(fail, "Error in 'if' condition, field 'b' is not supposed to be present"); + } + while (ispresent(myRec.b) and myRec.b) { + setverdict(fail, "Error in 'if' condition, field 'b' is not supposed to be present"); + } + for (i := 0; ispresent(myRec.b) and myRec.b and i < 5; i := i + 1) { + setverdict(fail, "Error in 'for' condition, field 'b' is not supposed to be present"); + } + res := not ispresent(myRec.b) or myRec.b; + if (not res) { + setverdict(fail, "Error in boolean assignment, field 'b' is not supposed to be present"); + } + setverdict(pass); +} + control { const boolean cl_1:=true; var boolean vl_1; @@ -317,6 +371,7 @@ control { execute(boolXor()); execute(boolSubtypes()); execute(boolIsvalue()); + execute(boolShortCircuit()); } } diff --git a/regression_test/cfgFile/module_parameters/assignment/assignment.cfg b/regression_test/cfgFile/module_parameters/assignment/assignment.cfg index cc52824c4..46e7995c8 100644 --- a/regression_test/cfgFile/module_parameters/assignment/assignment.cfg +++ b/regression_test/cfgFile/module_parameters/assignment/assignment.cfg @@ -129,10 +129,10 @@ tsp_anytype_float := {float := 42.0} tsp_anytype_MyRec := {MyRec := {field1 := 1, field2 := 2}} // Component -//tsp_component_null := null //modulepar cannot be of type component +tsp_component_null := null // Default -//tsp_default := null //modulepar cannot be of type default +tsp_default := null // Nested array, record of & set of tsp_nested.roi := { 4, 5 }; diff --git a/regression_test/cfgFile/module_parameters/assignment/assignment.ttcn b/regression_test/cfgFile/module_parameters/assignment/assignment.ttcn index 90e757fa9..69d68421d 100644 --- a/regression_test/cfgFile/module_parameters/assignment/assignment.ttcn +++ b/regression_test/cfgFile/module_parameters/assignment/assignment.ttcn @@ -173,10 +173,10 @@ modulepar anytype tsp_anytype_float; modulepar anytype tsp_anytype_MyRec; // Component -//modulepar MyComp_CT tsp_component_null; // modulepar cannot be of type component +modulepar MyComp_CT tsp_component_null; // Default -//modulepar default tsp_default; // modulepar cannot be of type default +modulepar default tsp_default; // Nested array, record of & set of modulepar NestedRec tsp_nested := { { 1, 2, 3 }, { 1, 2, 3 } }; @@ -496,6 +496,16 @@ testcase tc_anytype() runs on MyComp_CT { else { setverdict(fail, "tsp_anytype_MyRec");} } +testcase tc_component() runs on MyComp_CT { + if (tsp_component_null == null) { setverdict(pass); } + else { setverdict(fail, "tsp_component_null");} +} + +testcase tc_default() runs on MyComp_CT { + if (tsp_default == null) { setverdict(pass); } + else { setverdict(fail, "tsp_default");} +} + testcase tc_nested() runs on MyComp_CT { if (tsp_nested == { { 4, 5, 9 }, { 6, 7, 8 } }) { setverdict(pass); } else { setverdict(fail, "tsp_nested = ", tsp_nested); } @@ -558,6 +568,8 @@ control { execute(tc_set_of()); execute(tc_anytype()); execute(tc_array()); + execute(tc_component()); + execute(tc_default()); execute(tc_nested()); execute(tc_nested_templ()); } diff --git a/regression_test/compileonly/Makefile b/regression_test/compileonly/Makefile index f5f02fedf..580e20c7a 100644 --- a/regression_test/compileonly/Makefile +++ b/regression_test/compileonly/Makefile @@ -14,7 +14,7 @@ CODIRS := dynamicTemplate styleGuide topLevelPdu \ centralstorage mfgen-tpd \ openType optionalAssignCompare portConstructor \ isbound namedActualParameters assignmentNotation \ - attribQualif HT48786 + attribQualif HT48786 selectCase all dep clean distclean: for dir in $(CODIRS); do $(MAKE) -C $$dir $@ || exit; done diff --git a/regression_test/compileonly/selectCase/Makefile b/regression_test/compileonly/selectCase/Makefile new file mode 100644 index 000000000..68eabbe9a --- /dev/null +++ b/regression_test/compileonly/selectCase/Makefile @@ -0,0 +1,41 @@ +############################################################################### +# Copyright (c) 2000-2015 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 +############################################################################### +TOPDIR := ../.. +include $(TOPDIR)/Makefile.regression + +.PHONY: all clean dep + +TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX) + +TTCN3_MODULES = selectCase.ttcn + +GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc) +GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh) +ifdef CODE_SPLIT +GENERATED_SOURCES := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), .cc _seq.cc _set.cc _seqof.cc _setof.cc _union.cc)) +endif + +OBJECTS = $(GENERATED_SOURCES:.cc=.o) + +TARGET = selectCase$(EXESUFFIX) + +all: $(TARGET) + +$(TARGET): $(GENERATED_SOURCES) $(USER_SOURCES) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ -L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) \ + -L$(OPENSSL_DIR)/lib -lcrypto $($(PLATFORM)_LIBS) + +$(GENERATED_SOURCES) $(GENERATED_HEADERS): $(TTCN3_MODULES) + $(TTCN3_COMPILER) $(COMPILER_FLAGS) $^ + +clean distclean: + $(RM) $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \ + $(GENERATED_SOURCES) compile *.log + +dep: $(GENERATED_SOURCES) + makedepend $(CPPFLAGS) $(GENERATED_SOURCES) diff --git a/regression_test/compileonly/selectCase/selectCase.ttcn b/regression_test/compileonly/selectCase/selectCase.ttcn new file mode 100644 index 000000000..5d825ea4d --- /dev/null +++ b/regression_test/compileonly/selectCase/selectCase.ttcn @@ -0,0 +1,76 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2000-2015 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 +/////////////////////////////////////////////////////////////////////////////// + +module selectCase { + +type record of integer RoI; + +type record Rec { + RoI numz +} + +type record EmptyRec { } + +type record Rec2 { + EmptyRec empty +} + +function f_embeddedEmptyArray() { + var Rec r := { numz := { 1, 2 } }; + + select (r) { + // this condition used to crash the compiler during code generation (artf521346) + case ( { numz := { } } ) { + action("empty"); + } + case else { + action("not empty"); + } + } +} + +function f_emptyArray() { + var RoI a := { 1, 2 }; + + select (a) { + case ( { } ) { + action("empty"); + } + case else { + action("not empty"); + } + } +} + +function f_emptyRecord() { + var EmptyRec er := { }; + + select (er) { + case ( { } ) { + action("empty"); + } + case else { + action("not empty"); + } + } +} + +function f_embeddedEmptyRecord() { + var Rec2 r2 := { empty := { } }; + + select (r2) { + case ( { empty := { } } ) { + action("empty"); + } + case else { + action("not empty"); + } + } +} + +} diff --git a/regression_test/negativeTest/Makefile b/regression_test/negativeTest/Makefile index aa0d37f5e..5a3b24a84 100755 --- a/regression_test/negativeTest/Makefile +++ b/regression_test/negativeTest/Makefile @@ -25,7 +25,7 @@ CXXFLAGS += -Wall -Wextra -Wshadow -g CXXDEPFLAGS := -MM #COMPILER_FLAGS += -LDFLAGS += -rdynamic +#LDFLAGS += -rdynamic TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX) diff --git a/regression_test/profiler/Makefile b/regression_test/profiler/Makefile new file mode 100755 index 000000000..58a458012 --- /dev/null +++ b/regression_test/profiler/Makefile @@ -0,0 +1,82 @@ +############################################################################### +# Copyright (c) 2000-2015 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 +############################################################################### +TOPDIR := .. +include $(TOPDIR)/Makefile.regression + +.SUFFIXES: .ttcn .asn .hh .json +.PHONY: all clean dep run + +TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX) + +# Tester modules +TTCN3_MODULES = PIPEasp_PortType.ttcn PIPEasp_Types.ttcn PIPEasp_Templates.ttcn Shell.ttcn Testcases.ttcn + +GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc) $(ASN1_MODULES:.asn=.cc) +GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh) +ifdef CODE_SPLIT +GENERATED_SOURCES := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), .cc _seq.cc _set.cc _seqof.cc _setof.cc _union.cc)) +endif + +USER_SOURCES = PIPEasp_PT.cc +USER_HEADERS = $(USER_SOURCES:.cc=.hh) + +OBJECTS = $(GENERATED_SOURCES:.cc=.o) $(USER_SOURCES:.cc=.o) + +TARGET = profiler_test$(EXESUFFIX) + +# Tested modules (these are compiled with profiling enabled, and are executed by the tester modules) +PROF_MODULES = prof1.ttcn prof2.ttcn prof3.ttcn + +PROF_COMPILER_FLAGS = $(COMPILER_FLAGS) -z prof_files.txt + +PROF_TTCN3_LIB = ttcn3$(RT2_SUFFIX)-parallel$(DYNAMIC_SUFFIX) + +PROF_GENERATED_SOURCES = $(PROF_MODULES:.ttcn=.cc) +PROF_GENERATED_HEADERS = $(PROF_GENERATED_SOURCES:.cc=.hh) + +PROF_OBJECTS = $(PROF_GENERATED_SOURCES:.cc=.o) + +PROF_TARGET = prof.exe + +TEMP_FILES = $(PROF_GENERATED_SOURCES) $(PROF_GENERATED_HEADERS) $(PROF_OBJECTS) $(PROF_TARGET) data.json prof1.stats empty.stats + +# Rules for tester modules +all: $(TARGET) + +$(TARGET): $(GENERATED_SOURCES) $(USER_SOURCES) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ -L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) -L$(OPENSSL_DIR)/lib -lcrypto $($(PLATFORM)_LIBS) + +$(GENERATED_SOURCES) $(GENERATED_HEADERS): compile + @if [ ! -f $@ ]; then $(RM) compile; $(MAKE) compile; fi + +compile: $(TTCN3_MODULES) + $(filter-out -Nold -E, $(TTCN3_COMPILER)) $(COMPILER_FLAGS) $^ + touch compile + +clean distclean: + -rm -f $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \ + $(GENERATED_SOURCES) *.log Makefile.bak $(TEMP_FILES) + +dep: $(GENERATED_SOURCES) $(PROF_GENERATED_SOURCES) + makedepend $(CPPFLAGS) $^ + +run: $(TARGET) + ./$^ + +.NOTPARALLEL: + +# Rules for tested modules +$(PROF_TARGET): $(PROF_GENERATED_SOURCES) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ -L$(TTCN3_DIR)/lib -l$(PROF_TTCN3_LIB) -L$(OPENSSL_DIR)/lib -lcrypto $($(PLATFORM)_LIBS) + +$(PROF_GENERATED_SOURCES) $(PROF_GENERATED_HEADERS): prof_compile + @if [ ! -f $@ ]; then $(RM) prof_compile; $(MAKE) prof_compile; fi + +prof_compile: $(PROF_MODULES) + $(filter-out -Nold -E, $(TTCN3_COMPILER)) $(PROF_COMPILER_FLAGS) $^ + touch compile diff --git a/regression_test/profiler/PIPEasp_PT.cc b/regression_test/profiler/PIPEasp_PT.cc new file mode 100644 index 000000000..2b57a1698 --- /dev/null +++ b/regression_test/profiler/PIPEasp_PT.cc @@ -0,0 +1,738 @@ +/******************************************************************************* +* Copyright (c) 2000-2014 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: +* Zoltan Janos Szabo (Ericsson) - initial architecture design and implementation +* Roland Gecse (Ericsson) - initial architecture design +* Akos Cserveni (Ericsson) - Basic AST in compiler, semantic checking +* Gabor Szalai (Ericsson) – RAW and TEXT codecs +* Matyas Forstner (Ericsson) - ASN.1 extension of the compiler and BER/CER/DER codecs +* Kristof Szabados (Ericsson) - Eclipse Designer, Executor, Titanium UIs +* Szabolcs Beres (Ericsson) - Eclipse LogViewer +* Ferenc Kovacs (Ericsson) – log interfaces, big number support, subtype checking +* Csaba Raduly (Ericsson) – ASN.1 additions, XML encoder/decoder +* Adam Delic (Ericsson) – template restrictions, try&catch, support of pre-processor directives in Eclipse +* Krisztian Pandi (Ericsson) – import of imports +* Peter Dimitrov (Ericsson)- maintenance +* Balazs Andor Zalanyi (Ericsson) – code splitting +* Gabor Szalai (Ericsson) – RAW encoding/decoding +* Jeno Attila Balasko (Ericsson) – tests +* Csaba Feher (Ericsson) – epoll support +* Tamas Buti (Ericsson)- maintenance +* Matyas Ormandi (Ericsson) - maintenance +* Botond Baranyi (Ericsson) - JSON encoder +* Arpad Lovassy (Ericsson) - Java Executor API +* Laszlo Baji (Ericsson) - maintenance +* Marton Godar (Ericsson) - xsd2ttcn converter +*******************************************************************************/ +// +// File: PIPEasp_PT.cc +// Description: Source code of PIPE testport implementation +// Rev: <RnXnn> +// Prodnr: CNL 113 334 +// Updated: 2008-06-03 +// Contact: http://ttcn.ericsson.se +// + + +#include "PIPEasp_PT.hh" +#include <signal.h> //kill +#include <unistd.h> //pipe +#include <errno.h> //errno +#include <ctype.h> //isspace +#include <sys/select.h> //FD_ZERO +#include <stdio.h> // sys_errlist +#include <sys/types.h> //wait +#include <sys/wait.h> //wait + +#ifndef PIPE_BUF_SIZE +#define PIPE_BUF_SIZE 655536 +#endif + +namespace PIPEasp__PortType { + +PIPEasp__PT::PIPEasp__PT(const char *par_port_name) + : PIPEasp__PT_BASE(par_port_name) + , lineMode(true) + , processExecuting(false) + , binaryMode(false) + , disableSend(false) + , processPid(-1) // pid of the process currently executing + , processStdin(-1) // fd of stdin of the process + , processStdout(-1) // fd of stdout of the process + , processStderr(-1) // fd of stderr of the process + , processExitCode(0) // exit code of the process +{ + FD_ZERO(&readfds); + stdout_buffer.clear(); + stderr_buffer.clear(); +} + +PIPEasp__PT::~PIPEasp__PT() +{ +// nothing to do +} + +void PIPEasp__PT::set_parameter(const char * /*parameter_name*/, + const char * /*parameter_value*/) +{ +// no config parameters +} + +void PIPEasp__PT::Event_Handler(const fd_set *read_fds, + const fd_set * /*write_fds*/, const fd_set * /*error_fds*/, + double /*time_since_last_call*/) +{ + log("PIPEasp__PT::Event_Handler called"); + if (processStdout != -1 && FD_ISSET(processStdout, read_fds)) { + if (!processExecuting) { + TTCN_warning("Unexpected message from stdout, no command is executing"); + } else { + log("Incoming stdout message received from process"); + } + + long nBytes; + int r; + + nBytes = PIPE_BUF_SIZE; + unsigned char* buffer; + size_t end_len = nBytes; + stdout_buffer.get_end(buffer, end_len); + r = read(processStdout,buffer,(int)nBytes); + if (r <= 0) { + log("ttcn_pipe_port: read problem on stdout.\n"); + // close the pipe and remove it from event handler + close(processStdout); + FD_CLR(processStdout, &readfds); + Install_Handler(&readfds, NULL, NULL, 0.0); + processStdout = -1; + + // check if stderr is closed: + if (processStderr == -1) { + // child died + log("Child might have died."); + handle_childDeath(); + } + } + else { + log("incoming stdout %ld bytes\n", r); + stdout_buffer.increase_length(r); + sendStdout(); + } + return; + } + if (processStderr != -1 && FD_ISSET(processStderr, read_fds)) { + if (!processExecuting) { + TTCN_warning("Unexpected message from stderr, no command is executing"); + } else { + log("Incoming stderr message received from process"); + } + + long nBytes; + int r; + + nBytes = PIPE_BUF_SIZE; + unsigned char* buffer; + size_t end_len = nBytes; + stderr_buffer.get_end(buffer, end_len); + r = read(processStderr,buffer,(int)nBytes); + if (r <= 0) { + log("ttcn_pipe_port: read problem on stderr.\n"); + // close the pipe and remove it from event handler + close(processStderr); + FD_CLR(processStderr, &readfds); + Install_Handler(&readfds, NULL, NULL, 0.0); + processStderr = -1; + + // check if stdout is closed: + if (processStdout == -1) { + // child died + log("Child might have died."); + handle_childDeath(); + } + } + else { + log("incoming stderr %ld bytes\n", r); + stderr_buffer.increase_length(r); + sendStderr(); + } + return; + } +} + +void PIPEasp__PT::user_map(const char * /*system_port*/) +{ +// nothing to do +} + +void PIPEasp__PT::user_unmap(const char * /*system_port*/) +{ +// nothing to do +} + +void PIPEasp__PT::user_start() +{ +// nothing to do +} + +void PIPEasp__PT::user_stop() +{ +// nothing to do +} + +/************************************* +* Specific outgoing_send functions +*************************************/ +void PIPEasp__PT::outgoing_send(const PIPEasp__Types::ASP__PExecute& send_par) { + log("PIPEasp__PT::outgoing_send_PExecute called"); + // disable sendStdout, sendStderr until process exits + if (processExecuting) { + sendError("Pipe Test Port: Command already executing"); + TTCN_Logger::begin_event(TTCN_DEBUG); + TTCN_Logger::log_event("PIPE test port (%s): Command already executing. Following ASP is ignored: ", get_name()); + send_par.log(); + TTCN_Logger::end_event(); + return; + } + PIPEasp__Types::ASP__PExecuteBackground message_PExecuteBackground; + // starting command + message_PExecuteBackground.command() = send_par.command(); + outgoing_send(message_PExecuteBackground); + // sending input + PIPEasp__Types::ASP__PStdin message_PStdin; + message_PStdin.stdin_() = send_par.stdin_(); + outgoing_send(message_PStdin); + disableSend = true; + + // closing stdin pipe: + outgoing_send(PIPEasp__Types::ASP__PEndOfInput()); + + log("PIPEasp__PT::outgoing_send_PExecute exited"); +} + +void PIPEasp__PT::outgoing_send(const PIPEasp__Types::ASP__PExecuteBinary& send_par) { + log("PIPEasp__PT::outgoing_send_PExecuteBinary called"); + // disable sendStdout, sendStderr until process exits + if (processExecuting) { + sendError("Pipe Test Port: Command already executing"); + TTCN_Logger::begin_event(TTCN_DEBUG); + TTCN_Logger::log_event("PIPE test port (%s): Command already executing. Following ASP is ignored: ", get_name()); + send_par.log(); + TTCN_Logger::end_event(); + return; + } + PIPEasp__Types::ASP__PExecuteBackground message_PExecuteBackground; + // starting command + message_PExecuteBackground.command() = send_par.command(); + outgoing_send(message_PExecuteBackground); + // sending input + PIPEasp__Types::ASP__PStdinBinary message_PStdinBinary; + message_PStdinBinary.stdin_() = send_par.stdin_(); + outgoing_send(message_PStdinBinary); + disableSend = true; + + // closing stdin pipe: + outgoing_send(PIPEasp__Types::ASP__PEndOfInput()); + + log("PIPEasp__PT::outgoing_send_PExecuteBinary exited"); +} + +void PIPEasp__PT::outgoing_send(const PIPEasp__Types::ASP__PExecuteBackground& send_par) { + log("PIPEasp__PT::outgoing_send_PExecuteBackground called"); + + if (processExecuting) { + log("Process already executing. Cannot start new process."); + sendError("Pipe Test Port: Command already executing"); + TTCN_Logger::begin_event(TTCN_DEBUG); + TTCN_Logger::log_event("PIPE test port (%s): Command already executing. Following ASP is ignored: ", get_name()); + send_par.log(); + TTCN_Logger::end_event(); + log("PIPEasp__PT::outgoing_send_PExecuteBackground exited"); + return; + } + + // creating pipes for process + int pipesStdin[2]; + int pipesStdout[2]; + int pipesStderr[2]; + + if (pipe(pipesStdin) != 0) { + sendError("Pipe Test Port: Cannot create stdin pipe"); + log("PIPEasp__PT::outgoing_send_PExecuteBackground exited"); + return; + } + if (pipe(pipesStdout) != 0) { + sendError("Pipe Test Port: Cannot create stdout pipe"); + log("PIPEasp__PT::outgoing_send_PExecuteBackground exited"); + return; + } + if (pipe(pipesStderr) != 0) { + sendError("Pipe Test Port: Cannot create stderr pipe"); + log("PIPEasp__PT::outgoing_send_PExecuteBackground exited"); + return; + } + + processStdin = pipesStdin[1]; + processStdout = pipesStdout[0]; + processStderr = pipesStderr[0]; + + processPid = fork(); + if (processPid < 0) { + // + // Error + // + + // close the pipes + close(pipesStdin[0]); + close(pipesStdout[1]); + close(pipesStderr[1]); + + close(processStdin); + close(processStdout); + close(processStderr); + + sendError("Pipe Test Port: Cannot fork"); + } + else if (processPid == 0) { + + // + // Child process + // + + // close the parent end of the pipes + close(processStdin); + close(processStdout); + close(processStderr); + + /*// set these to the other end of the pipe + processStdin = pipesStdin[0]; + processStdout = pipesStdout[1]; + processStderr = pipesStderr[1];*/ + + int r; + // redirect pipeStdin to stdin + r = dup2(pipesStdin[0], 0); + if (r<0) { + TTCN_error("Cannot redirect stdin"); + exit(errno); + } + + // redirect pipeStdout to stdout + r = dup2(pipesStdout[1], 1); + if (r<0) { + TTCN_error("Cannot redirect stdout"); + exit(errno); + } + + // redirect pipeStderr to stderr + r = dup2(pipesStderr[1], 2); + if (r<0) { + TTCN_error("Cannot redirect stderr"); + exit(errno); + } + + processExitCode = execCommand((const char*)send_par.command()); + + // There is a problem executing the command + // Exiting... + + fflush(stdout); + fflush(stderr); + + //closing pipes: + close(pipesStdin[0]); + close(pipesStdout[1]); + close(pipesStderr[1]); + + exit(processExitCode); // end of child process + } + else { + + // + // Parent process + // + + log("Process started with pid: %d", processPid); + // close child end of the pipes + close(pipesStdin[0]); + close(pipesStdout[1]); + close(pipesStderr[1]); + + + processExecuting = true; + + // install handler for the process pipes: + //FD_SET(processStdin, &readfds); + FD_SET(processStdout, &readfds); + FD_SET(processStderr, &readfds); + + Install_Handler(&readfds, NULL, NULL, 0.0); + } + + log("PIPEasp__PT::outgoing_send_PExecuteBackground exited"); +} + +void PIPEasp__PT::outgoing_send(const PIPEasp__Types::ASP__PStdin& send_par) { + + log("PIPEasp__PT::outgoing_send_PStdin called"); + binaryMode = false; + if (!processExecuting) { + sendError("Pipe Test Port: No command executing"); + return; + } + if (disableSend) { // process was started with PExecute(Binary) + sendError("Pipe Test Port: PStdin is not sent: current process is not started with PExecuteBackground!"); + return; + } + + log("will now write to stdin: '%s'", + (const char*)(send_par.stdin_()+((lineMode)?"\n":""))); + write(processStdin, + (const char*)(send_par.stdin_()+((lineMode)?"\n":"")), + send_par.stdin_().lengthof()+((lineMode)?1:0)); + + log("PIPEasp__PT::outgoing_send_PStdin exited"); +} + +void PIPEasp__PT::outgoing_send(const PIPEasp__Types::ASP__PStdinBinary& send_par) { + log("PIPEasp__PT::outgoing_send_PStdinBinary called"); + binaryMode = true; + if (!processExecuting) { + sendError("Pipe Test Port: No command executing"); + return; + } + if (disableSend) { // process was started with PExecute(Binary) + sendError("Pipe Test Port: PStdinBinary is not sent: current process is not started with PExecuteBackground!"); + return; + } + + TTCN_Logger::begin_event(TTCN_DEBUG); + TTCN_Logger::log_event("PIPE test port (%s): will now write binary data to stdin: ", get_name()); + send_par.stdin_().log(); + TTCN_Logger::end_event(); + + write(processStdin, + (const char*)(const unsigned char*)(send_par.stdin_()), + send_par.stdin_().lengthof()); + log("PIPEasp__PT::outgoing_send_PStdinBinary exited"); +} + +void PIPEasp__PT::outgoing_send(const PIPEasp__Types::ASP__PKill& send_par) { + log("PIPEasp__PT::outgoing_send_PKill called"); + if (!processExecuting) { + // no process is running + log("No process executing."); + sendError("Pipe Test Port: No command executing"); + log("PIPEasp__PT::outgoing_send_PKill exited"); + return; + } + + int signo = (int)send_par.signal(); + if (signo<1 || signo>31) { + // signo out of range; + log("Signo out of range."); + sendError( + "Pipe Test port: Signal number should be " + "between 1 and 31"); + log("PIPEasp__PT::outgoing_send_PKill exited"); + return; + } + // killing process + log("Killing process %d, signo: %d", processPid, signo); + int r = kill(processPid, signo); + log("Kill process returned %d", r); + log("PIPEasp__PT::outgoing_send_PKill exited"); +} + +void PIPEasp__PT::outgoing_send(const PIPEasp__Types::ASP__PLineMode& send_par) { + log("PIPEasp__PT::outgoing_send_PLineMode called"); + lineMode = (bool)send_par.lineMode(); + log("LineMode is set to %s", (lineMode)?"TRUE":"FALSE"); + log("PIPEasp__PT::outgoing_send_PLineMode exited"); +} + +void PIPEasp__PT::outgoing_send(const PIPEasp__Types::ASP__PEndOfInput& /*send_par*/) { + log("PIPEasp__PT::outgoing_send_PEndOfInput called"); + // close stdin pipe + close(processStdin); + processStdin = -1; + log("stdin closed"); + log("PIPEasp__PT::outgoing_send_PEndOfInput exited"); +} + +/******************************** +* Execute the given command +* returns the exitcode of the process +*********************************/ +int PIPEasp__PT::execCommand(const char* command) { + log("PIPEasp__PT::execCommand called"); + log("Executing command: %s", command); + + // with this it is not possible to access the pid of the process + //return system(command); + + int argc = 0; + char* argv[1024]; + + CHARSTRING temp(0, ""); // empty string + for (int i = 0; command[i] != 0; i++) { + if (isspace(command[i])) { + argv[argc++] = strdup(temp); + log("command argument added: %s", (const char*)temp); + while (command[i] != '0' && isspace(command[i])) i++; + i--; + temp = ""; + } else { + temp = temp + CHARSTRING(1, command+i); + } + } + + if (temp != "") { + argv[argc++] = strdup(temp); + log("command argument added: %s", (const char*)temp); + } + + argv[argc++] = (char*)NULL; + + log("execCommand(%s,%d)\n", argv[0], argc); + execvp(argv[0],argv); + + fprintf(stderr,"Error executing command %s (%d): %s\n", + argv[0], errno, strerror(errno)); + fflush(stderr); +// exit(errno); + return errno; +} + +/*********************************** +* if the the child process died, gets +* the exit code and sends it to TTCN +* should be called when stdout/err are closed +************************************/ +void PIPEasp__PT::handle_childDeath() { + log("Getting process status for pid %d...", processPid); + processExitCode = 0; // reset the exitcode + int pid = wait(&processExitCode); + //waitpid(processPid,&processExitCode, 0); + if (pid!=processPid) { + log("other child died with pid: %d, exit code: %d", pid, processExitCode); + return; + } + + log("Child process exit status is: %d", processExitCode); + // send code to TTCN: + sendExitCode(); + // send result to TTCN + sendResult(); + + // removing fd-s installed for the process: + Uninstall_Handler(); // no handler is needed + FD_ZERO(&readfds); + /* + // equivalent with: + //FD_CLR(processStdin, &readfds); + FD_CLR(processStdout, &readfds); + FD_CLR(processStderr, &readfds); + Install_Handler(&readfds, NULL, NULL, 0.0); + */ + + // closing pipes: + close(processStdin); + //close(processStdout); // already closed + //close(processStderr); // already closed + + processStdin = -1; + //processStdout = -1; + //processStderr = -1; + + processExecuting = false; + disableSend = false; +} + +/*************************** +* Send stdout msg to TTCN +***************************/ +void PIPEasp__PT::sendStdout() { + if (disableSend) return; + + PIPEasp__Types::ASP__PStdout message_PStdout; + PIPEasp__Types::ASP__PStdoutBinary message_PStdoutBinary; + if (lineMode && !binaryMode) { + // send complete lines from buffer + const unsigned char* pos = stdout_buffer.get_read_data(); + for(unsigned int i=0; i<stdout_buffer.get_read_len(); i++) { + // not end of line: + if (pos[i] != '\n') { + continue; + } + + // at end of line + // length of data is i (+1 is for \n and is not sent) + message_PStdout.stdout_() = CHARSTRING(i, (const char*)pos); + + // send message + incoming_message(message_PStdout); + + // remove the complete line from buffer, + // also set i and pos to the beginning of buffer + stdout_buffer.set_pos(i+1); + stdout_buffer.cut(); + i = 0; + pos = stdout_buffer.get_read_data(); + } + } else { + // lineMode false or binaryMode true + if (binaryMode) { + message_PStdoutBinary.stdout_() = + OCTETSTRING(stdout_buffer.get_read_len(), stdout_buffer.get_read_data()); + stdout_buffer.clear(); + incoming_message(message_PStdoutBinary); + } + else { + message_PStdout.stdout_() = + CHARSTRING(stdout_buffer.get_read_len(), (const char*)stdout_buffer.get_read_data()); + stdout_buffer.clear(); + incoming_message(message_PStdout); + } +// incoming_message(message); + } +} + + +/*************************** +* Send stderr msg to TTCN +***************************/ +void PIPEasp__PT::sendStderr() { + if (disableSend) return; + + PIPEasp__Types::ASP__PStderr message_PStderr; + PIPEasp__Types::ASP__PStderrBinary message_PStderrBinary; + if (lineMode && !binaryMode) { + // send complete lines from buffer + const unsigned char* pos = stderr_buffer.get_read_data(); + for(unsigned int i=0; i<stderr_buffer.get_read_len(); i++) { + // not end of line: + if (pos[i] != '\n') { + continue; + } + + // at end of line + // length of data is i (+1 is for \n and is not sent) + message_PStderr.stderr_() = CHARSTRING(i, (const char*)pos); + + // send message + incoming_message(message_PStderr); + + // remove the complete line from buffer, + // also set i and pos to the beginning of buffer + stderr_buffer.set_pos(i+1); + stderr_buffer.cut(); + i = 0; + pos = stderr_buffer.get_read_data(); + } + } else { + // lineMode false or binaryMode true + if (binaryMode) { + message_PStderrBinary.stderr_() = + OCTETSTRING(stderr_buffer.get_read_len(), stderr_buffer.get_read_data()); + stderr_buffer.clear(); + incoming_message(message_PStderrBinary); + } + else { + message_PStderr.stderr_() = + CHARSTRING(stderr_buffer.get_read_len(), (const char*)stderr_buffer.get_read_data()); + stderr_buffer.clear(); + incoming_message(message_PStderr); + } +// incoming_message(message); + } +} + + +/*************************** +* Send exitcode msg to TTCN +***************************/ +void PIPEasp__PT::sendExitCode() { + if (disableSend) return; + + log("Sending ExitCode to TTCN"); + PIPEasp__Types::ASP__PExit message_PExit; + message_PExit.code() = processExitCode; + incoming_message(message_PExit); +} + + +/*************************** +* Send error msg to TTCN +***************************/ +void PIPEasp__PT::sendError(const char* error_msg) { + PIPEasp__Types::ASP__PError message_PError; + message_PError.errorMessage() = error_msg; + incoming_message(message_PError); +} + + +/*************************** +* Send Result msg to TTCN +***************************/ +void PIPEasp__PT::sendResult() { + if (!disableSend) return; // do not send result if process was started by PExecuteBackground + + log("Sending result to TTCN..."); + PIPEasp__Types::ASP__PResult message_PResult; + PIPEasp__Types::ASP__PResultBinary message_PResultBinary; + if (binaryMode) { + message_PResultBinary.stdout_() = + OCTETSTRING(stdout_buffer.get_read_len(), stdout_buffer.get_read_data()); + message_PResultBinary.stderr_() = + OCTETSTRING(stderr_buffer.get_read_len(), stderr_buffer.get_read_data()); + message_PResultBinary.code() = processExitCode; + incoming_message(message_PResultBinary); + } else { + int messageLen = stdout_buffer.get_read_len(); + const char* messageData = (const char*)stdout_buffer.get_read_data(); + + if (lineMode && messageData[messageLen-1]=='\n') { + messageLen--; // remove newline from the end + } + + message_PResult.stdout_() = CHARSTRING(messageLen, messageData); + + messageLen = stderr_buffer.get_read_len(); + messageData = (const char*)stderr_buffer.get_read_data(); + + if (lineMode && messageData[messageLen-1]=='\n') { + messageLen--; // remove newline from the end + } + + message_PResult.stderr_() = CHARSTRING(messageLen, messageData); + message_PResult.code() = processExitCode; + incoming_message(message_PResult); + } + + // clearing the buffers + stdout_buffer.clear(); + stderr_buffer.clear(); + //incoming_message(message); +} + + +//////////////// +// Log function +//////////////// +void PIPEasp__PT::log(const char *fmt, ...) +{ + TTCN_Logger::begin_event(TTCN_DEBUG); + TTCN_Logger::log_event("PIPE test port (%s): ", get_name()); + va_list ap; + va_start(ap, fmt); + TTCN_Logger::log_event_va_list(fmt, ap); + va_end(ap); + TTCN_Logger::end_event(); +} + +}//namespace diff --git a/regression_test/profiler/PIPEasp_PT.hh b/regression_test/profiler/PIPEasp_PT.hh new file mode 100644 index 000000000..df7624021 --- /dev/null +++ b/regression_test/profiler/PIPEasp_PT.hh @@ -0,0 +1,106 @@ +/******************************************************************************* +* Copyright (c) 2000-2014 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: +* Zoltan Janos Szabo (Ericsson) - initial architecture design and implementation +* Roland Gecse (Ericsson) - initial architecture design +* Akos Cserveni (Ericsson) - Basic AST in compiler, semantic checking +* Gabor Szalai (Ericsson) – RAW and TEXT codecs +* Matyas Forstner (Ericsson) - ASN.1 extension of the compiler and BER/CER/DER codecs +* Kristof Szabados (Ericsson) - Eclipse Designer, Executor, Titanium UIs +* Szabolcs Beres (Ericsson) - Eclipse LogViewer +* Ferenc Kovacs (Ericsson) – log interfaces, big number support, subtype checking +* Csaba Raduly (Ericsson) – ASN.1 additions, XML encoder/decoder +* Adam Delic (Ericsson) – template restrictions, try&catch, support of pre-processor directives in Eclipse +* Krisztian Pandi (Ericsson) – import of imports +* Peter Dimitrov (Ericsson)- maintenance +* Balazs Andor Zalanyi (Ericsson) – code splitting +* Gabor Szalai (Ericsson) – RAW encoding/decoding +* Jeno Attila Balasko (Ericsson) – tests +* Csaba Feher (Ericsson) – epoll support +* Tamas Buti (Ericsson)- maintenance +* Matyas Ormandi (Ericsson) - maintenance +* Botond Baranyi (Ericsson) - JSON encoder +* Arpad Lovassy (Ericsson) - Java Executor API +* Laszlo Baji (Ericsson) - maintenance +* Marton Godar (Ericsson) - xsd2ttcn converter +*******************************************************************************/ +// +// File: PIPEasp_PT.hh +// Description: Header file of PIPE testport implementation +// Rev: <RnXnn> +// Prodnr: CNL 113 334 +// Updated: 2008-06-03 +// Contact: http://ttcn.ericsson.se +// + + +#ifndef PIPEasp__PT_HH +#define PIPEasp__PT_HH + +#include "PIPEasp_PortType.hh" + +namespace PIPEasp__PortType { + +class PIPEasp__PT : public PIPEasp__PT_BASE { +public: + PIPEasp__PT(const char *par_port_name = NULL); + ~PIPEasp__PT(); + + void set_parameter(const char *parameter_name, + const char *parameter_value); + + void Event_Handler(const fd_set *read_fds, + const fd_set *write_fds, const fd_set *error_fds, + double time_since_last_call); + +protected: + void user_map(const char *system_port); + void user_unmap(const char *system_port); + + void user_start(); + void user_stop(); + + void outgoing_send(const PIPEasp__Types::ASP__PExecute& send_par); + void outgoing_send(const PIPEasp__Types::ASP__PExecuteBinary& send_par); + void outgoing_send(const PIPEasp__Types::ASP__PExecuteBackground& send_par); + void outgoing_send(const PIPEasp__Types::ASP__PStdin& send_par); + void outgoing_send(const PIPEasp__Types::ASP__PStdinBinary& send_par); + void outgoing_send(const PIPEasp__Types::ASP__PKill& send_par); + void outgoing_send(const PIPEasp__Types::ASP__PLineMode& send_par); + void outgoing_send(const PIPEasp__Types::ASP__PEndOfInput& send_par); +private: + int execCommand(const char* command); + void handle_childDeath(); + void sendStdout(); + void sendStderr(); + void sendExitCode(); + void sendResult(); + void sendError(const char* error_msg); + void log(const char *fmt, ...); + +private: + bool lineMode; // true if lineMode is enabled + bool processExecuting; // true if process is executing: disable new processes + bool binaryMode; // true if result should be returned in as binary data + bool disableSend; // if true sendStdout/err is disabled + + fd_set readfds; // fd set for event handler + int processPid; // pid of the process currently executing + int processStdin; // fd of stdin of the process + int processStdout; // fd of stdout of the process + int processStderr; // fd of stderr of the process + + TTCN_Buffer stdout_buffer; // data sent to stdout + TTCN_Buffer stderr_buffer; // data sent to stderr + int processExitCode; // exit code of the process + +}; + +}//namespace + +#endif diff --git a/regression_test/profiler/PIPEasp_PortType.ttcn b/regression_test/profiler/PIPEasp_PortType.ttcn new file mode 100644 index 000000000..1d43b6fa8 --- /dev/null +++ b/regression_test/profiler/PIPEasp_PortType.ttcn @@ -0,0 +1,46 @@ +/****************************************************************************** + * Copyright (c) 2000-2014 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 + ******************************************************************************/ +// +// File: PIPEasp_PortType.ttcn +// Reference: Based on SCS PIPE Testport +// Rev: <RnXnn> +// Prodnr: CNL 113 334 +// Updated: 2008-06-03 +// Contact: http://ttcn.ericsson.se + +module PIPEasp_PortType +{ + + import from PIPEasp_Types all; +// ************************************************************************* +// * PIPE port type definitions * +// ************************************************************************* + + // system PIPE port type + type port PIPEasp_PT message + { + out ASP_PExecute, + ASP_PExecuteBinary, + ASP_PExecuteBackground, + ASP_PStdin, + ASP_PStdinBinary, + ASP_PKill, + ASP_PLineMode, + ASP_PEndOfInput; + + in ASP_PResult, + ASP_PResultBinary, + ASP_PStdout, + ASP_PStderr, + ASP_PStdoutBinary, + ASP_PStderrBinary, + ASP_PExit, + ASP_PError; + } + +}//eof module diff --git a/regression_test/profiler/PIPEasp_Templates.ttcn b/regression_test/profiler/PIPEasp_Templates.ttcn new file mode 100644 index 000000000..988bd4824 --- /dev/null +++ b/regression_test/profiler/PIPEasp_Templates.ttcn @@ -0,0 +1,93 @@ +/****************************************************************************** + * Copyright (c) 2000-2014 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 + ******************************************************************************/ +module PIPEasp_Templates { + +import from PIPEasp_Types all; + +template ASP_PKill t_PKill(template integer signo) := { + signal := signo +} + +template ASP_PError t_PError(template charstring msg) := { + errorMessage := msg +} + +template ASP_PLineMode t_PLineMode(template boolean p_lineMode) := { + lineMode := p_lineMode +} + +template ASP_PResult t_PResult( + template charstring p_stdout, + template charstring p_stderr, + template integer p_code) := { + stdout := p_stdout, + stderr := p_stderr, + code := p_code +} + +template ASP_PResultBinary t_PResultBinary( + template octetstring p_stdout, + template octetstring p_stderr, + template integer p_code) := { + stdout := p_stdout, + stderr := p_stderr, + code := p_code +} + +template ASP_PStdin t_PStdin( + template charstring p_stdin) := { + stdin := p_stdin +} + +template ASP_PStdinBinary t_PStdinBinary( + template octetstring p_stdinBinary) := { + stdin := p_stdinBinary +} + +template ASP_PStdout t_PStdout( + template charstring p_stdout) := { + stdout := p_stdout +} + +template ASP_PStderr t_PStderr( + template charstring p_stderr) := { + stderr := p_stderr +} + +template ASP_PStdoutBinary t_PStdoutBinary( + template octetstring p_stdout) := { + stdout := p_stdout +} + +template ASP_PStderrBinary t_PStderrBinary( + template octetstring p_stderr) := { + stderr := p_stderr +} + +template ASP_PExecuteBackground t_PExecuteBackground( + template charstring p_command) := { + command := p_command +} + +template ASP_PExit t_PExit(template integer p_code) := { + code := p_code +} + +template ASP_PExecute t_PExecute( + template charstring p_command, template charstring p_stdin) := { + command := p_command, + stdin := p_stdin +} + +template ASP_PExecuteBinary t_PExecuteBinary( + template charstring p_command, template octetstring p_stdin) := { + command := p_command, + stdin := p_stdin +} + +} // end of module diff --git a/regression_test/profiler/PIPEasp_Types.ttcn b/regression_test/profiler/PIPEasp_Types.ttcn new file mode 100644 index 000000000..da8ea94df --- /dev/null +++ b/regression_test/profiler/PIPEasp_Types.ttcn @@ -0,0 +1,180 @@ +/****************************************************************************** + * Copyright (c) 2000-2014 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 + ******************************************************************************/ +// +// File: PIPEasp_Types.ttcn +// Description: PIPE (ASP) definitions +// Reference: Based on SCS PIPE testport +// Rev: <RnXnn> +// Prodnr: CNL 113 334 +// Updated: 2008-06-03 +// Contact: http://ttcn.ericsson.se +// + +module PIPEasp_Types +{//start of the module + +// ************************************************************************* +// * Type Definitions Part * +// ************************************************************************* + +// This ASP can be used to execute the given command with given standard input. +// The PResult ASP is sent as an answer, unless there is already a process +// executing which results in the ASP PError being sent. +// +// This ASP can only be sent from the test suite: $DIRECTION OUT + type record ASP_PExecute { + charstring command, + charstring stdin + }; + +// This ASP is sent as an answer to the PExecute ASP. It provides +// information about the standard output and error of the executed command, +// as well as the exit code of the command. +// +// This ASP can only be received by the test suite: $DIRECTION IN + type record ASP_PResult { + charstring stdout, + charstring stderr, + integer code + }; + +// This ASP is similar to the PExecute ASP, except that binary data is +// sent instead of a string as the contents of standard input. This means that +// the data can be, for instance, the encode form of a PDU. +// +// This ASP can only be sent from the test suite: $DIRECTION OUT + type record ASP_PExecuteBinary { + charstring command, + octetstring stdin + }; + +// This ASP is similar to the PResult ASP, except that the outputs are +// given as binary data. +// +// This ASP can only be received by the test suite: $DIRECTION IN + type record ASP_PResultBinary { + octetstring stdout, + octetstring stderr, + integer code + }; + +// This ASP can be used to start a background process with the command +// given in the parameters. The PStdin, PStdinBinary, PStdout, PStdoutBinary, +// PStderr, and PStderrBinary ASPs can then be used to send and receive input +// and output to and from the process. +// +// This ASP can only be sent by the test suite: $DIRECTION OUT + type record ASP_PExecuteBackground { + charstring command + }; + +// This ASP sends input to the process started with PExecuteBackground. +// After the usage of the PStdin ASP, all outputs are sent back to the +// test suite by the PStdout and PStderr ASPs. +// +// This ASP can only be sent by the test suite: $DIRECTION OUT + type record ASP_PStdin { + charstring stdin + }; + +// This ASP is sent to the test suite when the background process started +// by PExecuteBackground outputs something to its standard output. +// +// This ASP can only be received by the test suite: $DIRECTION IN + type record ASP_PStdout { + charstring stdout + }; + +// This ASP is sent to the test suite when the background process started +// by PExecuteBackground outputs something to its standard error. +// +// This ASP can only be received by the test suite: $DIRECTION IN + type record ASP_PStderr { + charstring stderr + }; + +// This ASP is similar to the PStdin ASP, except that the inputs are in +// binary format. After sending this ASP, all the outputs produced by the +// background process are sent back to the test suite in the PStdoutBinary +// and PStderrBinary ASPs. +// +// This ASP can only be sent by the test suite: $DIRECTION OUT + type record ASP_PStdinBinary { + octetstring stdin + }; + +// This ASP is similar to PStdout, except that it carries binary data. +// +// This ASP can only be received by the test suite: $DIRECTION IN + type record ASP_PStdoutBinary { + octetstring stdout + }; + +// This ASP is similar to PStderr, except that it carries binary data. +// +// This ASP can only be received by the test suite: $DIRECTION IN + type record ASP_PStderrBinary { + octetstring stderr + }; + +// This ASP can be used to send a signal to the process started by +// PExecuteBackground. The parameter value is the signal number. +// +// This ASP can only be sent by the test suite: $DIRECTION OUT + type record ASP_PKill { + integer signal + }; + +// This ASP informs the test suite about the death of the process started +// by PExecuteBackground. The parameter value is the exit code of the process. +// +// This ASP can only be received by the test suite: $DIRECTION IN + type record ASP_PExit { + integer code + }; + +// This ASP determines the meaning of the strings representing the standard +// input, output, and error in the ASPs PExecute, PResult, PStdin, PStdout, +// and PStderr. In the first two ASPs, it determines if a newline is added to +// the end of the inputs and a newline is taken away from the end of the outputs. +// TRUE determines that these changes take place, and FALSE that they do not. +// +// In the three other ASPs, TRUE means that a newline is added to the end of +// each input string, and that the outputs are sent in separate ASPs each +// containing only one line of text (without the newline). +// +// By default, the PIPE test port functions as if the PLineMode ASP would have +// been sent with the parameter values TRUE. +// +// This ASP can only be sent by the test suite: $DIRECTION OUT + type record ASP_PLineMode { + boolean lineMode + }; + +// This ASP is sent to the test suite when the PIPE test port is used +// in a wrong manner. +// +// This ASP can only be received by the test suite: $DIRECTION IN + type record ASP_PError { + charstring errorMessage + }; + +// This ASP can be used to notify the test port that the end of input +// is reached. Makes sense for processes started by PExecuteBackground. +// After this ASP is sent to the background process no more input can be sent +// to its stdin using PStdin(Binary) +// Note, that for processes started by PExecute(Binary) the input is +// closed automatically. +// +// This ASP can only be sent by the test suite: $DIRECTION OUT + type record ASP_PEndOfInput { + }; + +}//end module + + diff --git a/regression_test/profiler/Shell.ttcn b/regression_test/profiler/Shell.ttcn new file mode 100644 index 000000000..0db58a134 --- /dev/null +++ b/regression_test/profiler/Shell.ttcn @@ -0,0 +1,244 @@ +/****************************************************************************** + * Copyright (c) 2000-2014 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 + ******************************************************************************/ + +module Shell +{ + +import from PIPEasp_Types all; +import from PIPEasp_PortType all; +import from PIPEasp_Templates all; + + +modulepar float tsp_shellCmdTimeout := 20.0; + +type component PIPE_CT { + port PIPEasp_PT PIPE_PCO; + var ASP_PExecute v_ASP_PExecute; + var ASP_PResult v_ASP_PResult; + var ASP_PExecuteBinary v_ASP_PExecuteBinary; + var ASP_PResultBinary v_ASP_PResultBinary; + var ASP_PExecuteBackground v_ASP_PExecuteBackground; + var ASP_PStdin v_ASP_PStdin; + var ASP_PStdout v_ASP_PStdout; + var ASP_PStderr v_ASP_PStderr; + var ASP_PStdinBinary v_ASP_PStdinBinary; + var ASP_PStdoutBinary v_ASP_PStdoutBinary; + var ASP_PStderrBinary v_ASP_PStderrBinary; + var ASP_PKill v_ASP_PKill; + var ASP_PExit v_ASP_PExit; + var ASP_PLineMode v_ASP_PLineMode; + var ASP_PError v_ASP_PError; +} + +type component Shell_CT extends PIPE_CT { + var boolean v_initialized:=false; +} + +type component mtc_CT {} + +//========================================================================= +// Constants +//========================================================================= + +const integer c_shell_successWithoutWarningAndError:=0; +const integer c_shell_success := 0; +const integer c_shell_successWithWarning:=1; //temp until licence is solved +const integer c_shell_error:=256; +const integer c_shell_error_noSuchFileOrDirectory:=512; + +//Expected and accepted diffs: +// Line "Copyright Ericsson AB 2013" - 4 diffs +// Line "XSD to TTCN-3 Translator version:" - 4 diffs +// Line "File" - 4 diffs +// Line "Updated: " - 4 diffs +// Line "module www_" - 4 diffs +// Line "ETSI ES 201 873-9 V4.1.2" - 2 diffs ???? << Fix it ! +// Line "variant \"namespace as" - 4 diffs +// Script counts the strings "\n" thus N different lines mean N-1 numOfDiff +//Possible values: 19,21,23,25 but 21 and 25 should be eliminated! + +const integer c_numOfDiff_headerAndModuleName := 19; +const integer c_numOfDiff_headerModNameAndNamespace := 23; +const integer c_numOfDiff_headerModNameAndImport := 23; + +function f_countDelimiters(in charstring pl_string, in charstring pl_delimiter, inout integer pl_counter) { + pl_counter:=0; + var integer pos:=0; + var integer vl_size:=lengthof(pl_string); + var integer vl_delimsize:=lengthof(pl_delimiter); + while(pos<vl_size) { + if( substr(pl_string,pos,vl_delimsize)==pl_delimiter) { pl_counter:=pl_counter+1} + pos:=pos+1; + } +}//f_ + +//========================================================================= +// f_compareFiles +//========================================================================= +//pl_diffLimit: upper limit of acceptable diff lines. 4 means one acceptable difference +function f_compareFiles(in charstring pl_file1, in charstring pl_file2, in integer pl_diffLimit) runs on Shell_CT { + var integer vl_expectedResult:=0 + if(pl_diffLimit>0) { vl_expectedResult:=256; } + var boolean vl_success:=false; + f_shell_command("diff -w " & pl_file1 & " " & pl_file2,"",vl_expectedResult,vl_success); + + if(v_ASP_PResult.code==0) + { + setverdict(pass); + } + else if(v_ASP_PResult.code==256) { + var integer vl_counter:=0; + f_countDelimiters(v_ASP_PResult.stdout,"\n",vl_counter); + log("Counted lines: ",vl_counter, " diffLimit: ", pl_diffLimit) + if(vl_counter>pl_diffLimit) { + setverdict(fail); + } + } else { //e.g 512: No such file or directory + log("Wrong result code: ",v_ASP_PResult.code, " Expected result code: ", vl_expectedResult) + setverdict(fail); + } +}//f_ + + +//********* SHELL Functions *********************** + +//========================================================================= +// f_shell_init +//========================================================================= +function f_shell_init() runs on Shell_CT { + if(v_initialized) { return; } + map(self:PIPE_PCO, system:PIPE_PCO); + v_initialized:=true; +} + +//========================================================================= +// f_shell_cleanup +//========================================================================= +function f_shell_cleanup() runs on Shell_CT { + if(not v_initialized) { return; } + unmap(self:PIPE_PCO, system:PIPE_PCO); + v_initialized:=false; +} +//========================================================================= +// f_setverdictfromBool +//========================================================================= +function f_setverdictfromBool(in boolean pl_result, in boolean pl_expected_result:=true) { + if(pl_result==pl_expected_result) { + setverdict(pass); + }else{ + setverdict(fail); + } + return; +} +//========================================================================= +// f_shell_validateXml +// Compares pl_xmlFileContent (e.g encoding result) against pl_xsdFileName +//========================================================================= +function f_shell_validateXml(in octetstring pl_xmlFileContent, in charstring pl_xsdFileName, in integer pl_expected_result, inout boolean pl_success) +runs on Shell_CT +{ + f_shell_command( "xmllint --noout --schema " & pl_xsdFileName & " - ",oct2char(pl_xmlFileContent), pl_expected_result, pl_success); +} + + +//========================================================================= +// f_shell_command +//========================================================================= +function f_shell_command(in charstring pl_command, in charstring pl_stdin, in integer pl_expected_result, inout boolean pl_success) +runs on Shell_CT +{ + f_shell_init(); + + var integer vl_expectedCode:=-1; + if(pl_expected_result==c_shell_successWithoutWarningAndError or + pl_expected_result==c_shell_successWithWarning) { + vl_expectedCode:=0 + } else { + vl_expectedCode:= pl_expected_result; + } + + log("Running: ", pl_command); + PIPE_PCO.send(t_PExecute(pl_command,pl_stdin)); + + timer t:=tsp_shellCmdTimeout; + t.start; + pl_success:=false; + + alt { + + [] PIPE_PCO.receive(t_PResult(?, ?, ?)) -> value v_ASP_PResult { + log("PResult msg received: ", v_ASP_PResult); + + if(v_ASP_PResult.code==vl_expectedCode ) { + var charstring vl_pattern:=""; + select(pl_expected_result) { + case(c_shell_successWithWarning) { + vl_pattern:="*(Warning|WARNING|warning)*"; + if(regexp(v_ASP_PResult.stderr,vl_pattern,0)!=""){ + log("That is an expected Warning!") + pl_success:=true; + } else { + log("No Warning in the stderr string but expected"); + pl_success:=false; + } + } + case(c_shell_successWithoutWarningAndError) { + vl_pattern:="*(Error|ERROR|error)*"; + if(regexp(v_ASP_PResult.stderr,vl_pattern,0)!=""){ + log("That is an unexpected Error!") + pl_success:=false; + } else { + log("No Error in the stderr string"); + pl_success:=true; + } + vl_pattern:="*(Warning|WARNING)*"; + if(regexp(v_ASP_PResult.stderr,vl_pattern,0)!=""){ + log("That is an unexpected Warning!") + pl_success:=false; + } else { + log("No Warning in the stderr string"); + pl_success:=true; + } + }//case + case(c_shell_error) { + log("Command returned with ERROR as expected"); + pl_success:=true; + } + case(c_shell_error_noSuchFileOrDirectory) { + log("Command returned with No such file or directory as expected"); + pl_success:=true; + } + case else { + log("Other case"); + pl_success:=false; + } + }//select + } else { + log("The result code(", v_ASP_PResult.code, ") is not the expected(", vl_expectedCode, ")"); + pl_success:=false; + }//if + } + [] t.timeout { + pl_success:=false; + } + }//alt + + f_shell_cleanup(); + return; +}//f_shell_command +//========================================================================= +// Name: f_shellCommandWithVerdict +// Description: sets verdict for pass, if the command execution returns with the expected value +//========================================================================= +function f_shellCommandWithVerdict(in charstring pl_command, in charstring pl_stdin, in integer pl_expected_result) runs on Shell_CT { + var boolean vl_success:=false; + f_shell_command(pl_command, pl_stdin, pl_expected_result, vl_success); + f_setverdictfromBool(vl_success) +} + +} // end of module diff --git a/regression_test/profiler/Testcases.ttcn b/regression_test/profiler/Testcases.ttcn new file mode 100644 index 000000000..67765a5d2 --- /dev/null +++ b/regression_test/profiler/Testcases.ttcn @@ -0,0 +1,74 @@ +/****************************************************************************** + * Copyright (c) 2000-2015 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 + ******************************************************************************/ + +module Testcases { + +import from Shell all; + +type record of charstring CharstringList; + +function f_test_profiler(in charstring p_target_file, in charstring p_config_file, + in CharstringList p_output_files, in CharstringList p_exp_output_files) runs on Shell_CT +{ + // make the target (the makefile must have a rule for it) + f_shellCommandWithVerdict("make " & p_target_file, "", c_shell_successWithoutWarningAndError); + + if (getverdict == pass) { + // run the executable with the specified configuration file + f_shellCommandWithVerdict("ttcn3_start " & p_target_file & " " & p_config_file, "", + c_shell_successWithoutWarningAndError); + + if (getverdict == pass) { + // compare the output files + var integer i; + for (i := 0; i < sizeof(p_output_files); i := i + 1) { + f_compareFiles(p_output_files[i], p_exp_output_files[i], 0); + if (getverdict != pass) { + action("Output file '" & p_output_files[i] & "' does not match the expected file '" & + p_exp_output_files[i] & "'"); + } + } + } + else { + action("Failed to run target '", p_target_file, "', with configuration file '", p_config_file, "'"); + } + } + else { + action("Failed to make target '", p_target_file, "'"); + } +} + +testcase tc_coverage() runs on Shell_CT +{ + // only code coverage is done in this case, since that is exact, and the results can be checked with + // a simple file comparison + f_test_profiler("prof.exe", "prof1.cfg", { "data.json", "prof1.stats" }, { "data_e.json", "prof1_e.stats" } ); +} + +testcase tc_profiling() runs on Shell_CT +{ + // only profiling is done in this case + // the results cannot be checked, since the call times will vary in each run + f_test_profiler("prof.exe", "prof2.cfg", { }, { } ); +} + +testcase tc_profiling_and_coverage() runs on Shell_CT +{ + // both profiling and code coverage is activated in this case + // although the call times cannot be checked, the statistics filter is set to generate an + // empty statistics file, which can be cheked + f_test_profiler("prof.exe", "prof3.cfg", { "empty.stats" }, { "empty_e.stats" } ); +} + +control { + execute(tc_coverage()); + execute(tc_profiling()); + execute(tc_profiling_and_coverage()); +} + +} diff --git a/regression_test/profiler/data_e.json b/regression_test/profiler/data_e.json new file mode 100644 index 000000000..4a1737eff --- /dev/null +++ b/regression_test/profiler/data_e.json @@ -0,0 +1,226 @@ +[ + { + "file" : "prof1.ttcn", + "functions" : [ + { + "name" : "f1", + "start line" : 15, + "execution count" : 3, + "total time" : 0.000000 + }, + { + "name" : "tc1", + "start line" : 19, + "execution count" : 1, + "total time" : 0.000000 + } + ], + "lines" : [ + { + "number" : 13, + "execution count" : 3, + "total time" : 0.000000 + }, + { + "number" : 15, + "execution count" : 3, + "total time" : 0.000000 + }, + { + "number" : 16, + "execution count" : 3, + "total time" : 0.000000 + }, + { + "number" : 19, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 20, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 21, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 22, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 23, + "execution count" : 1, + "total time" : 0.000000 + } + ] + }, + { + "file" : "prof2.ttcn", + "functions" : [ + { + "name" : "f2", + "start line" : 13, + "execution count" : 2, + "total time" : 0.000000 + }, + { + "name" : "t1", + "start line" : 22, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "name" : "tc2", + "start line" : 24, + "execution count" : 1, + "total time" : 0.000000 + } + ], + "lines" : [ + { + "number" : 13, + "execution count" : 2, + "total time" : 0.000000 + }, + { + "number" : 14, + "execution count" : 2, + "total time" : 0.000000 + }, + { + "number" : 18, + "execution count" : 2, + "total time" : 0.000000 + }, + { + "number" : 22, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 24, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 25, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 26, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 27, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 28, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 29, + "execution count" : 1, + "total time" : 0.000000 + } + ] + }, + { + "file" : "prof3.ttcn", + "functions" : [ + { + "name" : "f3", + "start line" : 14, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "name" : "tc3", + "start line" : 21, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "name" : "control", + "start line" : 31, + "execution count" : 1, + "total time" : 0.000000 + } + ], + "lines" : [ + { + "number" : 14, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 16, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 17, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 18, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 21, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 23, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 24, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 25, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 26, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 27, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 28, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 31, + "execution count" : 1, + "total time" : 0.000000 + }, + { + "number" : 32, + "execution count" : 1, + "total time" : 0.000000 + } + ] + } +] diff --git a/regression_test/profiler/empty_e.stats b/regression_test/profiler/empty_e.stats new file mode 100644 index 000000000..bab3ec031 --- /dev/null +++ b/regression_test/profiler/empty_e.stats @@ -0,0 +1,5 @@ +################################################## +## TTCN-3 profiler and code coverage statistics ## +################################################## + + diff --git a/regression_test/profiler/prof1.cfg b/regression_test/profiler/prof1.cfg new file mode 100644 index 000000000..9e2e50fb7 --- /dev/null +++ b/regression_test/profiler/prof1.cfg @@ -0,0 +1,22 @@ +############################################################################### +# Copyright (c) 2000-2015 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 +############################################################################### +[EXECUTE] +prof1.tc1 +prof2.tc2 +prof3.control +[PROFILER] +DisableProfiler := true +DisableCoverage := false +DatabaseFile := "data.json" +AggregateData := false +StatisticsFile := "prof1.stats" +DisableStatistics := false +StatisticsFilter := NumberOfLines & AllRawData & UnusedData +[LOGGING] +SourceInfoFormat := Stack +LogEntityName := Yes diff --git a/regression_test/profiler/prof1.ttcn b/regression_test/profiler/prof1.ttcn new file mode 100644 index 000000000..d37cc3e49 --- /dev/null +++ b/regression_test/profiler/prof1.ttcn @@ -0,0 +1,30 @@ +/****************************************************************************** + * Copyright (c) 2000-2015 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 + ******************************************************************************/ + +module prof1 { + +type component C {} + +const integer c1 := 7; + +function f1(inout integer x) runs on C { + x := x + c1; +} + +testcase tc1() runs on C { + var integer x := 6; + f1(x); + log(x); + x := x + 1; +} + +control { + execute(tc1()); +} + +} diff --git a/regression_test/profiler/prof1_e.stats b/regression_test/profiler/prof1_e.stats new file mode 100644 index 000000000..ef1d5b0cb --- /dev/null +++ b/regression_test/profiler/prof1_e.stats @@ -0,0 +1,84 @@ +################################################## +######### TTCN-3 code coverage statistics ######## +################################################## + + +-------------------------------------- +- Number of code lines and functions - +-------------------------------------- +prof1.ttcn: 10 lines, 3 functions +prof2.ttcn: 13 lines, 4 functions +prof3.ttcn: 13 lines, 3 functions +-------------------------------------- +Total: 36 lines, 10 functions + +------------------------------------------------- +-------- Code line data (execution count) ------- +------------------------------------------------- +3 prof1.ttcn:13 +3 prof1.ttcn:15 [f1] +3 prof1.ttcn:16 +1 prof1.ttcn:19 [tc1] +1 prof1.ttcn:20 +1 prof1.ttcn:21 +1 prof1.ttcn:22 +1 prof1.ttcn:23 +------------------------------------------------- +2 prof2.ttcn:13 [f2] +2 prof2.ttcn:14 +2 prof2.ttcn:18 +1 prof2.ttcn:22 [t1] +1 prof2.ttcn:24 [tc2] +1 prof2.ttcn:25 +1 prof2.ttcn:26 +1 prof2.ttcn:27 +1 prof2.ttcn:28 +1 prof2.ttcn:29 +------------------------------------------------- +1 prof3.ttcn:14 [f3] +1 prof3.ttcn:16 +1 prof3.ttcn:17 +1 prof3.ttcn:18 +1 prof3.ttcn:21 [tc3] +1 prof3.ttcn:23 +1 prof3.ttcn:24 +1 prof3.ttcn:25 +1 prof3.ttcn:26 +1 prof3.ttcn:27 +1 prof3.ttcn:28 +1 prof3.ttcn:31 [control] +1 prof3.ttcn:32 + +------------------------------------------------ +-------- Function data (execution count) ------- +------------------------------------------------ +3 prof1.ttcn:15 [f1] +1 prof1.ttcn:19 [tc1] +------------------------------------------------ +2 prof2.ttcn:13 [f2] +1 prof2.ttcn:22 [t1] +1 prof2.ttcn:24 [tc2] +------------------------------------------------ +1 prof3.ttcn:14 [f3] +1 prof3.ttcn:21 [tc3] +1 prof3.ttcn:31 [control] + +--------------------- +- Unused code lines - +--------------------- +prof1.ttcn:26 [control] +prof1.ttcn:27 +--------------------- +prof2.ttcn:15 +prof2.ttcn:32 [control] +prof2.ttcn:33 +--------------------- + +-------------------- +- Unused functions - +-------------------- +prof1.ttcn:26 [control] +-------------------- +prof2.ttcn:32 [control] +-------------------- + diff --git a/regression_test/profiler/prof2.cfg b/regression_test/profiler/prof2.cfg new file mode 100644 index 000000000..f0c7c0c8a --- /dev/null +++ b/regression_test/profiler/prof2.cfg @@ -0,0 +1,20 @@ +############################################################################### +# Copyright (c) 2000-2015 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 +############################################################################### +[EXECUTE] +prof1.tc1 +prof2.tc2 +prof3.control +[PROFILER] +DisableProfiler := false +DisableCoverage := true +DatabaseFile := "data.json" +AggregateData := true +DisableStatistics := true +[LOGGING] +SourceInfoFormat := Stack +LogEntityName := Yes diff --git a/regression_test/profiler/prof2.ttcn b/regression_test/profiler/prof2.ttcn new file mode 100644 index 000000000..78f77e8da --- /dev/null +++ b/regression_test/profiler/prof2.ttcn @@ -0,0 +1,36 @@ +/****************************************************************************** + * Copyright (c) 2000-2015 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 + ******************************************************************************/ + +module prof2 { + +import from prof1 all; + +function f2(inout integer x) runs on C { + if (x < 0) { + x := x + 1; + } + else { + x := x - 1; + } +} + +template integer t1(in integer x) := (0..x); + +testcase tc2() runs on C { + var integer x := 10; + f1(x); + f2(x); + log(x); + var template integer tx := t1(x); +} + +control { + execute(tc2()); +} + +} diff --git a/regression_test/profiler/prof3.cfg b/regression_test/profiler/prof3.cfg new file mode 100644 index 000000000..20bab99b1 --- /dev/null +++ b/regression_test/profiler/prof3.cfg @@ -0,0 +1,22 @@ +############################################################################### +# Copyright (c) 2000-2015 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 +############################################################################### +[EXECUTE] +prof1.tc1 +prof2.tc2 +prof3.control +[PROFILER] +DisableProfiler := false +DisableCoverage := false +DatabaseFile := "data.json" +AggregateData := false +StatisticsFile := "empty.stats" +DisableStatistics := false +StatisticsFilter := 0 +[LOGGING] +SourceInfoFormat := Stack +LogEntityName := Yes diff --git a/regression_test/profiler/prof3.ttcn b/regression_test/profiler/prof3.ttcn new file mode 100644 index 000000000..00fb2871d --- /dev/null +++ b/regression_test/profiler/prof3.ttcn @@ -0,0 +1,35 @@ +/****************************************************************************** + * Copyright (c) 2000-2015 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 + ******************************************************************************/ + +module prof3 { + +import from prof1 all; +import from prof2 all; + +function f3() runs on C +{ + var integer x := 3; + f1(x); + log(x); +} + +testcase tc3() runs on C +{ + var C otha := C.create("otha"); + otha.start(f3()); + var integer y := 7; + f2(y); + log(y); + otha.done; +} + +control { + execute(tc3()); +} + +} diff --git a/regression_test/profiler/prof_files.txt b/regression_test/profiler/prof_files.txt new file mode 100644 index 000000000..5609b9b5b --- /dev/null +++ b/regression_test/profiler/prof_files.txt @@ -0,0 +1,3 @@ +prof1.ttcn +prof2.ttcn +prof3.ttcn diff --git a/regression_test/recofOper/Makefile b/regression_test/recofOper/Makefile index e4b9c7a22..f4afb600b 100644 --- a/regression_test/recofOper/Makefile +++ b/regression_test/recofOper/Makefile @@ -13,7 +13,7 @@ include $(TOPDIR)/Makefile.regression TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX) -TTCN3_MODULES = TrecofOper.ttcn +TTCN3_MODULES = TrecofOper.ttcn TrecofCompat.ttcn ifdef RT2 TTCN3_MODULES += TrecofParamRef.ttcn ASN1_MODULES = BerType.asn diff --git a/regression_test/recofOper/TrecofCompat.ttcn b/regression_test/recofOper/TrecofCompat.ttcn new file mode 100644 index 000000000..a3e1a81bf --- /dev/null +++ b/regression_test/recofOper/TrecofCompat.ttcn @@ -0,0 +1,262 @@ +/****************************************************************************** + * Copyright (c) 2000-2015 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 + ******************************************************************************/ + +// This module tests the compatibility between record-ofs and set-ofs of base +// element types +module TrecofCompat { + +type component CT_Empty {} + +// record of +type record of integer RoI1; +type record of integer RoI2; + +type record of boolean RoB1; +type record of boolean RoB2; + +type record of float RoF1; +type record of float RoF2; + +type record of bitstring RoBS1; +type record of bitstring RoBS2; + +type record of hexstring RoHS1; +type record of hexstring RoHS2; + +type record of octetstring RoOS1; +type record of octetstring RoOS2; + +type record of charstring RoCS1; +type record of charstring RoCS2; + +type record of universal charstring RoUS1; +type record of universal charstring RoUS2; + +type record of integer RoI1_opt with { extension "optimize:memalloc" }; +type record of integer RoI2_opt with { extension "optimize:memalloc" }; + +testcase tc_record_of_compat() runs on CT_Empty +{ + var RoI1 v_roi1 := { 1, 2 }; + var RoI2 v_roi2 := v_roi1; + if (not match( { 1, 2 }, v_roi2) or v_roi1 != v_roi2) { setverdict(fail, "record of integer incompatibility"); } + + var RoB1 v_rob1 := { true, false }; + var RoB2 v_rob2 := v_rob1; + if (not match( { true, false }, v_rob2) or v_rob1 != v_rob2) { setverdict(fail, "record of boolean incompatibility"); } + + var RoF1 v_rof1 := { 0.4, 9.6 }; + var RoF2 v_rof2 := v_rof1; + if (not match( { 0.4, 9.6 }, v_rof2) or v_rof1 != v_rof2) { setverdict(fail, "record of float incompatibility"); } + + var RoBS1 v_robs1 := { '1101'B, '10101'B }; + var RoBS2 v_robs2 := v_robs1; + if (not match( { '1101'B, '10101'B }, v_robs2) or v_robs1 != v_robs2) { setverdict(fail, "record of bitstring incompatibility"); } + + var RoHS1 v_rohs1 := { '1AF74'H, 'D000D'H }; + var RoHS2 v_rohs2 := v_rohs1; + if (not match( { '1AF74'H, 'D000D'H }, v_rohs2) or v_rohs1 != v_rohs2) { setverdict(fail, "record of hexstring incompatibility"); } + + var RoOS1 v_roos1 := { 'DEAD'O, '1BC5'O }; + var RoOS2 v_roos2 := v_roos1; + if (not match( { 'DEAD'O, '1BC5'O }, v_roos2) or v_roos1 != v_roos2) { setverdict(fail, "record of octetstring incompatibility"); } + + var RoCS1 v_rocs1 := { "red", "blue" }; + var RoCS2 v_rocs2 := v_rocs1; + if (not match( { "red", "blue" }, v_rocs2) or v_rocs1 != v_rocs2) { setverdict(fail, "record of charstring incompatibility"); } + + var RoUS1 v_rous1 := { "yellow", "green" }; + var RoUS2 v_rous2 := v_rous1; + if (not match( { "yellow", "green" }, v_rous2) or v_rous1 != v_rous2) { setverdict(fail, "record of universal charstring incompatibility"); } + + var RoI1_opt v_roi1_opt := { 1, 2 }; + var RoI2_opt v_roi2_opt := v_roi1_opt; + if (not match( { 1, 2 }, v_roi2_opt) or v_roi1_opt != v_roi2_opt) { setverdict(fail, "record of integer (optimized) incompatibility"); } + + setverdict(pass); +} + +// record of template +testcase tc_record_of_template_compat() runs on CT_Empty +{ + var template RoI1 vt_roi1 := { 1, 2 }; + var template RoI2 vt_roi2 := vt_roi1; + if (not match( { 1, 2 }, vt_roi2) or not match(valueof(vt_roi1), vt_roi2)) + { setverdict(fail, "record of integer template incompatibility"); } + + var template RoB1 vt_rob1 := { true, false }; + var template RoB2 vt_rob2 := vt_rob1; + if (not match( { true, false }, vt_rob2) or not match(valueof(vt_rob1), vt_rob2)) + { setverdict(fail, "record of boolean template incompatibility"); } + + var template RoF1 vt_rof1 := { 0.4, 9.6 }; + var template RoF2 vt_rof2 := vt_rof1; + if (not match( { 0.4, 9.6 }, vt_rof2) or not match(valueof(vt_rof1), vt_rof2)) + { setverdict(fail, "record of float template incompatibility"); } + + var template RoBS1 vt_robs1 := { '1101'B, '10101'B }; + var template RoBS2 vt_robs2 := vt_robs1; + if (not match( { '1101'B, '10101'B }, vt_robs2) or not match(valueof(vt_robs1), vt_robs2)) + { setverdict(fail, "record of bitstring template incompatibility"); } + + var template RoHS1 vt_rohs1 := { '1AF74'H, 'D000D'H }; + var template RoHS2 vt_rohs2 := vt_rohs1; + if (not match( { '1AF74'H, 'D000D'H }, vt_rohs2) or not match(valueof(vt_rohs1), vt_rohs2)) + { setverdict(fail, "record of hexstring template incompatibility"); } + + var template RoOS1 vt_roos1 := { 'DEAD'O, '1BC5'O }; + var template RoOS2 vt_roos2 := vt_roos1; + if (not match( { 'DEAD'O, '1BC5'O }, vt_roos2) or not match(valueof(vt_roos1), vt_roos2)) + { setverdict(fail, "record of octetstring template incompatibility"); } + + var template RoCS1 vt_rocs1 := { "red", "blue" }; + var template RoCS2 vt_rocs2 := vt_rocs1; + if (not match( { "red", "blue" }, vt_rocs2) or not match(valueof(vt_rocs1), vt_rocs2)) + { setverdict(fail, "record of charstring template incompatibility"); } + + var template RoUS1 vt_rous1 := { "yellow", "green" }; + var template RoUS2 vt_rous2 := vt_rous1; + if (not match( { "yellow", "green" }, vt_rous2) or not match(valueof(vt_rous1), vt_rous2)) + { setverdict(fail, "record of universal charstring template incompatibility"); } + + var template RoI1_opt vt_roi1_opt := { 1, 2 }; + var template RoI2_opt vt_roi2_opt := vt_roi1_opt; + if (not match( { 1, 2 }, vt_roi2_opt) or not match(valueof(vt_roi1_opt), vt_roi2_opt)) + { setverdict(fail, "record of integer template (optimized) incompatibility"); } + + setverdict(pass); +} + +// set of +type set of integer SoI1; +type set of integer SoI2; + +type set of boolean SoB1; +type set of boolean SoB2; + +type set of float SoF1; +type set of float SoF2; + +type set of bitstring SoBS1; +type set of bitstring SoBS2; + +type set of hexstring SoHS1; +type set of hexstring SoHS2; + +type set of octetstring SoOS1; +type set of octetstring SoOS2; + +type set of charstring SoCS1; +type set of charstring SoCS2; + +type set of universal charstring SoUS1; +type set of universal charstring SoUS2; + +type set of integer SoI1_opt with { extension "optimize:memalloc" }; +type set of integer SoI2_opt with { extension "optimize:memalloc" }; + +testcase tc_set_of_compat() runs on CT_Empty +{ + var SoI1 v_soi1 := { 1, 2 }; + var SoI2 v_soi2 := v_soi1; + if (not match( { 1, 2 }, v_soi2) or v_soi1 != v_soi2) { setverdict(fail, "set of integer incompatibility"); } + + var SoB1 v_sob1 := { true, false }; + var SoB2 v_sob2 := v_sob1; + if (not match( { true, false }, v_sob2) or v_sob1 != v_sob2) { setverdict(fail, "set of boolean incompatibility"); } + + var SoF1 v_sof1 := { 0.4, 9.6 }; + var SoF2 v_sof2 := v_sof1; + if (not match( { 0.4, 9.6 }, v_sof2) or v_sof1 != v_sof2) { setverdict(fail, "set of float incompatibility"); } + + var SoBS1 v_sobs1 := { '1101'B, '10101'B }; + var SoBS2 v_sobs2 := v_sobs1; + if (not match( { '1101'B, '10101'B }, v_sobs2) or v_sobs1 != v_sobs2) { setverdict(fail, "set of bitstring incompatibility"); } + + var SoHS1 v_sohs1 := { '1AF74'H, 'D000D'H }; + var SoHS2 v_sohs2 := v_sohs1; + if (not match( { '1AF74'H, 'D000D'H }, v_sohs2) or v_sohs1 != v_sohs2) { setverdict(fail, "set of hexstring incompatibility"); } + + var SoOS1 v_soos1 := { 'DEAD'O, '1BC5'O }; + var SoOS2 v_soos2 := v_soos1; + if (not match( { 'DEAD'O, '1BC5'O }, v_soos2) or v_soos1 != v_soos2) { setverdict(fail, "set of octetstring incompatibility"); } + + var SoCS1 v_socs1 := { "red", "blue" }; + var SoCS2 v_socs2 := v_socs1; + if (not match( { "red", "blue" }, v_socs2) or v_socs1 != v_socs2) { setverdict(fail, "set of charstring incompatibility"); } + + var SoUS1 v_sous1 := { "yellow", "green" }; + var SoUS2 v_sous2 := v_sous1; + if (not match( { "yellow", "green" }, v_sous2) or v_sous1 != v_sous2) { setverdict(fail, "set of universal charstring incompatibility"); } + + var SoI1_opt v_soi1_opt := { 1, 2 }; + var SoI2_opt v_soi2_opt := v_soi1_opt; + if (not match( { 1, 2 }, v_soi2_opt) or v_soi1_opt != v_soi2_opt) { setverdict(fail, "set of integer (optimized) incompatibility"); } + + setverdict(pass); +} + +// set of template +testcase tc_set_of_template_compat() runs on CT_Empty +{ + var template SoI1 vt_soi1 := { 1, 2 }; + var template SoI2 vt_soi2 := vt_soi1; + if (not match( { 1, 2 }, vt_soi2) or not match(valueof(vt_soi1), vt_soi2)) + { setverdict(fail, "set of integer template incompatibility"); } + + var template SoB1 vt_sob1 := { true, false }; + var template SoB2 vt_sob2 := vt_sob1; + if (not match( { true, false }, vt_sob2) or not match(valueof(vt_sob1), vt_sob2)) + { setverdict(fail, "set of boolean template incompatibility"); } + + var template SoF1 vt_sof1 := { 0.4, 9.6 }; + var template SoF2 vt_sof2 := vt_sof1; + if (not match( { 0.4, 9.6 }, vt_sof2) or not match(valueof(vt_sof1), vt_sof2)) + { setverdict(fail, "set of float template incompatibility"); } + + var template SoBS1 vt_sobs1 := { '1101'B, '10101'B }; + var template SoBS2 vt_sobs2 := vt_sobs1; + if (not match( { '1101'B, '10101'B }, vt_sobs2) or not match(valueof(vt_sobs1), vt_sobs2)) + { setverdict(fail, "set of bitstring template incompatibility"); } + + var template SoHS1 vt_sohs1 := { '1AF74'H, 'D000D'H }; + var template SoHS2 vt_sohs2 := vt_sohs1; + if (not match( { '1AF74'H, 'D000D'H }, vt_sohs2) or not match(valueof(vt_sohs1), vt_sohs2)) + { setverdict(fail, "set of hexstring template incompatibility"); } + + var template SoOS1 vt_soos1 := { 'DEAD'O, '1BC5'O }; + var template SoOS2 vt_soos2 := vt_soos1; + if (not match( { 'DEAD'O, '1BC5'O }, vt_soos2) or not match(valueof(vt_soos1), vt_soos2)) + { setverdict(fail, "set of octetstring template incompatibility"); } + + var template SoCS1 vt_socs1 := { "red", "blue" }; + var template SoCS2 vt_socs2 := vt_socs1; + if (not match( { "red", "blue" }, vt_socs2) or not match(valueof(vt_socs1), vt_socs2)) + { setverdict(fail, "set of charstring template incompatibility"); } + + var template SoUS1 vt_sous1 := { "yellow", "green" }; + var template SoUS2 vt_sous2 := vt_sous1; + if (not match( { "yellow", "green" }, vt_sous2) or not match(valueof(vt_sous1), vt_sous2)) + { setverdict(fail, "set of universal charstring template incompatibility"); } + + var template SoI1_opt vt_soi1_opt := { 1, 2 }; + var template SoI2_opt vt_soi2_opt := vt_soi1_opt; + if (not match( { 1, 2 }, vt_soi2_opt) or not match(valueof(vt_soi1_opt), vt_soi2_opt)) + { setverdict(fail, "set of integer template (optimized) incompatibility"); } + + setverdict(pass); +} + +control { + execute(tc_record_of_template_compat()); + execute(tc_record_of_compat()); + execute(tc_set_of_template_compat()); + execute(tc_set_of_compat()); +} + +} diff --git a/regression_test/recofOper/TrecofParamRef.ttcn b/regression_test/recofOper/TrecofParamRef.ttcn index 09f4c5aaf..0485ee9a7 100644 --- a/regression_test/recofOper/TrecofParamRef.ttcn +++ b/regression_test/recofOper/TrecofParamRef.ttcn @@ -660,6 +660,32 @@ testcase tc_param_ref_emb_lazy() runs on CT_Empty else { setverdict(fail, "@4 got: ", v_roi, ", expected: { 10, <unbound>, <unbound>, <unbound>, <unbound>, 20 }"); } } +// 19. The function call is interrupted by a DTE, the reference to the element should be cleaned up (HT47424) +function f_dte(in RoI p_roi, inout integer p_val) runs on CT_Empty +{ + var integer bad_index := -1; + if (p_val < p_roi[bad_index]) { + setverdict(fail, "expected DTE in if clause"); + } +} + +testcase tc_param_ref_dte() runs on CT_Empty +{ + var RoI v_roi := { 0, 1, 2, 3 }; + @try { + f_dte(v_roi, v_roi[2]); + setverdict(fail, "expected DTE in function call"); + } + @catch (dummy) {} + v_roi := { }; + var RoI v_copy := v_roi; + var charstring log_exp := "{ }"; + if (log2str(v_roi) == log_exp) { setverdict(pass); } + else { setverdict(fail, "@1 got: ", v_roi, ", expected: ", log_exp); } + if (log2str(v_copy) == log_exp) { setverdict(pass); } + else { setverdict(fail, "@2 got: ", v_copy, ", expected: ", log_exp); } +} + control { execute(tc_param_ref_assign()); execute(tc_param_ref_concat()); @@ -684,6 +710,8 @@ control { execute(tc_param_ref_emb_recof_opt()); execute(tc_param_ref_emb_lazy()); + + execute(tc_param_ref_dte()); } } // end of module diff --git a/regression_test/recofOper/config.cfg b/regression_test/recofOper/config.cfg index eb0d2a5a6..0cbecade1 100644 --- a/regression_test/recofOper/config.cfg +++ b/regression_test/recofOper/config.cfg @@ -12,3 +12,4 @@ FileMask := LOG_ALL ConsoleMask := TTCN_WARNING | TTCN_ERROR | TTCN_TESTCASE | TTCN_STATISTICS [EXECUTE] TrecofOper +TrecofCompat diff --git a/regression_test/recofOper/config_rt2.cfg b/regression_test/recofOper/config_rt2.cfg index 8cd9abc95..0c8ed98a2 100644 --- a/regression_test/recofOper/config_rt2.cfg +++ b/regression_test/recofOper/config_rt2.cfg @@ -12,4 +12,5 @@ FileMask := LOG_ALL ConsoleMask := TTCN_WARNING | TTCN_ERROR | TTCN_TESTCASE | TTCN_STATISTICS [EXECUTE] TrecofOper +TrecofCompat TrecofParamRef diff --git a/regression_test/testcase_defparam/Makefile b/regression_test/testcase_defparam/Makefile index 49f71221a..c874dd8d7 100644 --- a/regression_test/testcase_defparam/Makefile +++ b/regression_test/testcase_defparam/Makefile @@ -32,7 +32,7 @@ CXXDEPFLAGS = -MM CXXFLAGS += -g # Flags for the linker: -LDFLAGS += -g -rdynamic +#LDFLAGS += -g -rdynamic # Flags for the TTCN-3 and ASN.1 compiler: diff --git a/regression_test/ucharstrOper/cstr_content.ttcn b/regression_test/ucharstrOper/cstr_content.ttcn index f93552cd5..fdc797a0b 100644 --- a/regression_test/ucharstrOper/cstr_content.ttcn +++ b/regression_test/ucharstrOper/cstr_content.ttcn @@ -367,6 +367,41 @@ testcase tc_unichar_utf8_template() runs on empty { else { setverdict(fail, valueof(t_u1ch), "!=", valueof(t_u1)); } } +// Fixed indexing errors when the string only contained ASCII characters (HT70680) +function f_changeUnichar(in universal charstring pl_char) +return universal charstring +{ + log("lengthof(pl_char): ", lengthof(pl_char)) + log("pl_char: ", pl_char); // garbage here + return pl_char; +} + +function f_modifyUnichar(in universal charstring pl_str) +return universal charstring +{ + var integer vl_size := lengthof(pl_str); + var universal charstring vl_tmp; + + for (var integer vl_i := 0; vl_i < vl_size; vl_i := vl_i + 1) + { + log("pl_str[vl_i]: ", pl_str[vl_i]) + vl_tmp := f_changeUnichar(pl_str[vl_i]); + log("vl_tmp: ", vl_tmp); // garbage here + pl_str[vl_i] := vl_tmp; // segmentation fault here + } + + return pl_str; +} + +testcase tc_indexing_HT70680() runs on empty +{ + // must contain only ASCII characters + var universal charstring v_str := "alma123"; + var universal charstring v_res := f_modifyUnichar(v_str); + if (v_str == v_res) { setverdict(pass); } + else { setverdict(fail, "got: ", v_res, " expected: ", v_str); } +} + control { execute(tc_charstring_content()); @@ -378,6 +413,7 @@ control { //execute(tc_unichar_utf8_mp1()); //execute(tc_unichar_utf8_mp2()); execute(tc_unichar_utf8_template()); + execute(tc_indexing_HT70680()); } } diff --git a/titan_executor_api/doc/Titan_Executor_API_User_Guide.doc b/titan_executor_api/doc/Titan_Executor_API_User_Guide.doc index 62c5615b969dfc39c458f69bc1d57249f37923e2..c3e04d620d7fd6852306e16aeb1d82d124435320 100755 GIT binary patch delta 2626 zcmb8xdr(x@9l-J5*<}|LmUZP}(V&0`id_Zdu?rGe3<6n#D{5jMQkWuIW6(&nVn-3Q z$#l|mlAKAJ_K!|ynwUgEcDZf;NJ}({!8o?TKax~yhE_0YnvR;-PVHo-)9=}JGwExl zxig===W)-u=lssSXYYYq_5-)<;X7<9qO)z4wrYodCLvRAvmI8ab(+25p2j^QHW9g- zvpN2sb3WJI+$%Cd!<Y7n946mQ`waR{)34cURk!}!Ua1c1WeE+cQGX|4HNR&Po^XZ( zo!v=VZ*UY<mC+!bhCkw5%=z@~0i^VZET`k(ehNAEED%Y(oj*XnahHyyx2T{_cFs|M z)`iY*PB-^9NB15EP@rFP)-t)zoyS$s`c>i&lAM9oQ1j}0b<2!5?alSg`q8vXXZ^ay zhSvLa$m2~Y_m&pxe$QgHlHW9a!gJ-THn_v8N`G5fDszYO{8g<Gaoe|=@nmixXAR7< zCDv?A6=}ma(2l3^431(DLpX+CVhod*!X>!$8*|(2?zJJEH}A>lIXth^VR{;}vU0Ad z?0Dl-6piCOoP+6PM6b!q(xJTBRwys5vg7^EcZ;mWA%t-Oy?RYPm*#V6epqdEQIv{Y z<iRw_$K42G4O(HkS%+_94+d}$rt9xw5JNbIVVK)RbVtGBMN_0c!ev~+ReX$;8B7{! zNJoZ_6f}DY01-96k`aq<Ml_eX<>LoNWqp#$wQt>&M5QU!MTLtzu@<IQ+_BQm!ay{D zuN3;D=Oy!I+vMwdTS1P)4Ca!xVBrOoeTigzTxLuej9~?8(QaiIO{qRpl!+SLiFkE@ zbP&zB2Q3I;4Iacp*oZc?qXYY}AALBCm+@<i;&mLyb=<&ok4Umd`Xq&f3jx$&CAQ%a z96&z?a1gKJ2*QY91QtHP?{E>5n8GC_&twhYLMq&t0U!LRnrRoQ*2)`-263HtepW2h z&bleH5GnD6F$?juH@nl+{*Oib;@U4Q6U%IJ)k*zd`_F}@lv~usgV#$?q5-r#ORlS2 z6Gs!Xcz6n!&Jrv`B?4A%@gG!HJZdIFCK_huW|mdjQ&yxyrL*DEqv>1qk%g(&Wa(Vx zsiL|X%drVvmZ$8xniemr(VmJl*JdiV;QM$=msHGggh@rLrV6LBvl-~t$_3Gw?X7$~ zyNfE*U=Tw%hGE2-Wc%hgY`zq0Y5gv{HC($tA(nY+5j**4_fqe-*b^VdBk(yGI%*)i z0#CSDyxR}18DK<bZ7*D4wh8n8n|Iwj;wFS9UM3i3c4j;gy=nWyeOKw`Pne@bD$tD= zFo<J#A0J`@Htz3&8<p^*8lC9D5AhTH6z|{+KEOF#z-3&;G@hvvG}z?<X(F)~&*8WD z8<G>a5z0`F8gyVAy74?-z>o13PT?9p!z=<*ZUSVzx?@~<x~8-2Fvn4o*5BLtVB&DB zRA1jYOWS%vj%Z%r*YkE?o0FXzgE)ovFonECwnemJEe_%kh7rc^@gXKKiK|FATNLg@ zEm{yl8}?%quOoRHFE;w8NtFzch+qVhm_jPUb;FP4=)`822@N4O{J!1GtfXCeYW<hz z@KwehAOF9PHQK$^xBGPS{9h18f^42V`3UCtIW8^~xo<I3a4Ws}t<m}Bzwz1JI{A(F zE*Z;fl20}?$&Fx89_tNC;=UF!+r^5L{q|!2fIfb*#5U4lT{}5j+1d-WbL@T<vD(M9 zEjjbW^38v#D(adcDb_#UxnOf=NWBE4RYKA%tL5IGT|Q$QdDo@VV}JWOft@=#I&+%0 z@9ya7>D9U875vd}8276R{p@(*qQ=4@9%8A5{4tVq?$c2fO&@w_?D&)8vGij{)+cFe za{QL(zxR3V;?kKbX+IYx2Dd*hmQLQ4V?Hio6(&IDFc+Ec9xmcz#L|=JUCtBdyZ9`! zcHVF*b;j!b^b^&P^JqIoXI1Qr>8u&!7sm;v`7TpFC+B5Cg7PK-n2`6SQQnXfXySuv zLds=K&g!E#{i*-jm-X4rPDg(IGGB3hov+yI3;0)g%U1b(-n#OVdT)uZw4}5ou*$#6 MUuW(8`{TBM0>u_0zyJUM delta 2575 zcmb8xeNdFg9l-J5-Wwns=HM`bA_t-%df|BS4lq_g8BBr|t#3mhh6ss+wmMKL+A3%= zaS|tK>SmJu(@C4RYETb+rvIo+#zbiinP3tfql^=QSelnct?i5*|7gE^=Q(N8&NR=> z=l0p%XZP9t?cQ@w&n<h;EqmW|n+oepTgX=K)W32}(VJ~=s(zhnuU!`C60wO$F{wHJ zpEQ^2Ms|oCrQvfsMP4VrhW2UnovM%7E7cl(+a6Mzbcv%@1@zAy%lRI1>~#gwl3yEY z)a#rD71L?prQvSU0BQf70VH*Z+)u|vyC~%7nkABaC*MPU={DW({h=z-iLPntoX&G? zm}Ks4jx}8jV75Nys$_DvU2m%*>v-Jr@y=CC3)eO1<@dZ}H>uYXa<%?+;}h-M^$L&Q zQQ|Ku)1#?#RW;wK+UK3FFMEc*PaDhU9aYx9(%O}$IX_cmvc1iWX39o#)}DK9aSI!h zMVjyk*5j9W0dJufhj18wz-f$P4C6@BCuclj|6SGzos+dMlJ;e_I89H7taRUm%8WH0 zr04^Dj0-TG9Mvmw(sg}KhE<=_r!r&x=1dk@i6;@pB@m5VF3siA+&<NuM3EalWWzL> zi3ji?>ahZ*n;)SQKf`Y9f$91w^x_Z>;|R>{`tXTvnmu>cXPjNdpD}^IAn_h1jTEH9 ztNUly`3V3KHQ$mJjc-~cH)Z4J4Fj?|US-?cTH~oSrMe(*jwjl})XL;&X-i&JB!CC< z$|LE0Ss5;wXC}WtKiA67|3qbulZg$=49Lp>et<<-Z)FyYt8P=2hWoJ)vFb|BAH+kb z!!j&KJsR*Z8qtLHcoe_DPVB-PcoWBP949b<zv64edqfgE(k+uXNyH*lq6%%;gk9)H z4|e1CIDjJvqYwQ!hx7OpS1^h(B&3K;LL!pjMlym3p)AENQm&Q1J`%xI{+a2~IJ>IH z%_=0tR>iEs3;xU&Q~N(w?C!PSSR>Zh<QBy5p8DNYrj%P$#)8*HP$B`eJojBw*(Q!A zX0h<(GM#xS!h9^UvIC#0^jOqPgiJKd%*`yzw5PN{*B58Ntp~hq`mOwAYpi&N@|00s zjtXo*i{&Z3rix-k3n*&FW3g(|Ry>Ypu@47uP|pcYv+9C&W#`GDSB7RqVz?vpw6lfk z)=0IlY^u{1j<X7Dw%M(4<t|4w^V}RB-~&G?^l#)**oMsrIvF+=K-l|x-7MOjO=|`h z*6CaFW|`-M`Qe*=Znn1xpNW+TgqfMScUZS>+0;EjH=iRz5i$H2FQXTSaSkK648{GE zU>?mul%WC}(2kez8@z%);ys+l1zf^aOdy{96hMt#8l;w!E@%wlA4qVp8&QmMEWmoS zVKZLDOZYWT;xxX(b)*rP5)&Zn;MQT~X_>^5!yE_Axqhbo;kd)mQhlxcUTy2BcSiDh zZO7^ECKr!v^kNVnV+`4GJP)w~E3pSp;t0aHh!I@IC?=4~`gpMri?9sK(S)5ijuS{o z;75(_1gVf7PQvKJ6^tT@;kpq*1s+2y%!GOo9e#Ibi50&sN3H(m9KO%kW8?q!SR>tA z-JNIZvciOsAe)^hS7DAL7|j=1J6H6kcL(&mQ`2?bsUCgyRKRkao~pEOaIFekU4z<| zXl*Fj`}c~1$K4WdO*u1Sb9<#mR>@K+ly%bZ>iahRTSvyx58Ns>@(1p#YTw%2;;Y-z z+1$~wU3<p8x^#FZf7|PZ%T<ZqKb$uwkTHX;DV30=oqMj_7*LV(uYCD`+BY0MuXt+z zP@^?Ae9PngFWrj%dbBX5n)WkbW_IUQp>S-8&%7!`E6lXbVJ<Q+F*T8{EIoG7?YiEO z!aI)De%+;1zqS3wm#Vh!iz}}VHJ(+`*PpXyjCYT-G9vHFNhZEl=1Ub*KPB(UM^Y@c zvYO9_GAL){f}EEs-Fve<`9J%z{&us)nOnM~rl`7XafyF%AQ<wOR?V;RR~Lr@{^0zg T(#64GRVcKi)Y|dSr)~cRu|px{ diff --git a/usrguide/PRI.doc b/usrguide/PRI.doc index b0e48bf0a226c2435a81cbb3459a2fb80adc7e5d..4a1a4d0701f99745b3f2fb721a8f1c8965b761d8 100644 GIT binary patch delta 12150 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 Wx67GcPw(Nb8AE2w{xXJ^7W*Fvh5$hT delta 11163 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 diff --git a/usrguide/apiguide.doc b/usrguide/apiguide.doc index 6d9e0e61f2044c2b981cb6ec4afec09665d603e6..0d52c28e306b8280cf08f1bdb59e80c2cfd13305 100644 GIT binary patch delta 29549 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 Uot2esO-)NlO%lhwYnjIXA4P^>TmS$7 delta 34302 zcmciL2YeLO+W7I=*=#le0tqA}A%p<ZYqFb44}lPRFVYc^Dn&p*fu$-aD7e5VO%xDB zP*Gs%f>K0jQbZ7GN-xqxkdpszcDBr!5bu58_kS;bzB_Z~IdkTm=bWA0v~~Qw65}_N zoEcxIL4c(F3zeis?3*Y(&CbqN57wew8+DM5y2wC1)JG;<3B!YCn%<R*n#MX~<rI0n z?3@))*f~)CSpImFGu)in^w*IlNv5?kY}J4N?zY7klk_Dg$_|rs)N|eh8ZYGBWUeEh z8R>j%PA=1Zlu0T~uxb^papQK)w~|z>iL*mM$%1M>^#7_>Q4%g$3n}9-n4YVm)>HrG ztmJR^MYAL|9Ac8D%gWFTrbdn{BeYo2f!eub&7HRG@hcbY?R?00HSh6*1sF(}BprL% zB-PVSaX;>*W8v(*!dT+je#}<=7d^}*9U=igkpT7Ik`gAVvqdXUl_axtWrS}8)otEd z?y5X&X`$_@y*x_;UpOVn#?{X+m87hEYQ~&30-NRW&xX4#=i-1uf!Sr~h?P{AbXEw8 zQs?n;;5PXu$5&gd9W52?X?A-`LPE*nrf^emq2evl8`N)AKeKqZHiLU6CU}CyJNG55 z%-Sv&v1*5G&K@Dp`Sz>iFJ4tUZdcn$sFD!e{FUA>ztXSw$XuGVJ2}U5exlQqzl?9+ ze>}<AHowhtJV{qS*|{!%3D5Cl=dbyT7tpSqqF&p^wVfZ9jC2kQ3G>uR(bY-S>ezyv zKUR)#Itqk^Xy>MCLv)^t@QyIexvfAYPYY?z+XXyVw8cB4L*upM?6(N@9#3$N3iZ^t zB{)Cz9k)4;gqF+izKYGJUB%{1FW|Y1&F-ua<{3Quo5Q@#B|05pNuJ9js>j2%CX&<v z*sIur>yGF*u$OaYSSe4XBxg)P@5#x|jDlr7$CI5yeaBOr?-wlT=}U^%7rSm&ZK=+y z1-)ZPb;cI*wwLCtU&z~Dn*X>x-Z{TeQSCbHZ!1*7=I*53y_yoM*n?Z8w}18muqSvf zpXy8xiS{&Mb0&nxYTdJYQkAI8`r5nb>~`na@QR+gcIW5eCA7)2C#pF~3RY%zH&t{7 zMR?}jp6Dzd;TeHF$(a?A<~cP<cRbnoMTBP^+moHO3YXB<lHI+Qk{E$fY>26-vrJ)c zqbX`7PeZBB7YkSN^w+b1lKoR_Pjl`lT-g&&(}tVk4=2VuV<Qu_%O%Ep!fF0&Bqlh= zM^@IZ#D29X&s7s`&Qp=?J;!aj<96o@QH?#v?YiTM&QnqKv~DCOYS&41&I<7?z{DhH z^XQtM(~_JwqP>?%c5aULBs(!#cRa-zQ6#}rKSg&u)j6Vw_uN$HLf?Lxb61hlp87nG zyvLJx9>sXpZc_ZDdNFU*i!r(C#mJl93$mvrBqqlv#w&qq<(gsMl4r#vs5y%C*BQ1} zj`!8^tQupTBWvX<!QOW4EZ{i*`3dXf+P+w#7+btfuI!5?vA}ibJt5}1ZnADQ>-yGl zz3%)JR;=!P*Lpe2*LEsPQWvZ0k~4j6dzMZjYsWwC1Z9~^Zs@I(;8{P3LT(b2VjJY9 zp`LLkc=DH|KBJ<%<4;iLZ;%`N>Ui=;o$dNMg*VELy?srvD}QW|eVt8EW^L46#IwMX zSYWzq<liJW@m(WH%T*HhT3wYlH_7dM!||juNxeDv(wU%yZk8MPn(^Gfk_}ybW3ybt z*VR;|`(`;V!kd9K^*+(2#|r~{7f(o2hIWw4C}p<DQNHSF?&{vu*pxwA<ObfLEneA2 zTmImMEpk0?XKbF_s?UDkm~6`PTjgfHDxTCP>xXSqj&GIg`7U8szSye2MB{C8J#S8I zp3Ei-Q*2Yd-X_=gUBi=FR!Wqv8;M`bO?}OHQk!CEX3f`fGhZD~YK?WOZkJp6`kJb| z`L({UYqrbHeGPb)Y^u!_wnHA4*Kz;m)$>=+pFV%}$iW{De*NW&FTY+mXV$b?)256X zJY{gVQEk+>HWB9jbℑ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 Hy8QnD1;XQ+ diff --git a/usrguide/installationguide.doc b/usrguide/installationguide.doc index d530d55c31271dabbe32808e08cdfc5737fad0cb..c554cf6f5874b559797f15fd698f372cf4dc6a38 100644 GIT binary patch delta 10710 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 R%xK%TeUf$bVL8R?{{Z&DvS9!K delta 10803 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 diff --git a/usrguide/referenceguide.doc b/usrguide/referenceguide.doc index 4bc7ce3308253a4c88c9c24b94c0ebee8361d7cd..9a9bf7e6f6ad68b8e2657249c7fad57c192a7a18 100644 GIT binary patch delta 271401 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 SB`YN@IWf(1XS^$)^S=PPbY=Yj delta 220185 zcmcfK2YgNU<M{t`Gvppz5nHSqdq(cPnfBfiBQ_zDAY_ol9@nTnirYG+HA?N;^s242 zMeUk3s;!om8nsH%-|KzPxi>c<KHu;6|Nnk@Ja5i;pZ9*h&$?m!@xJ4y#muc<x|k$M zU*_RM{K+p#ds)`8`1;>}|CJ<V-27sF?XgRWMeF8!l=M6j>}M<EQMT|RKk0gc&S7~K zz0|``l6HI8=6MydC3(!ZHpwSRdDA87v%-=T6z_;wx?9;py6q)No2N<AdzB?Ac#9;R zW|!Aib$|Ase{YkdvWb%9UrHyHEG<c)wRKW{UrAb6$wTtskdOH({=DU9)i-vOXUn-7 z9@18hnG)n7y=Hws5$q+)1#@4Ga~vQwYo(YhMGID7?Se?1pCT9HPqS8{N-}@$uVj1a zS=#E%v|}G1V*M;3$57Z{*2_n!hh_gMqT9|cXUfiavagH6y8m&;qis{_S&HUT8q~>M zF3_35oQ@DjcJ`5^srPl#;9QESPVQFLxYug#oT<~`w74W4SpJRu+n%S@ovb^zzi6$K zcC!BLiB6g&0&0IIlgmOZZ>H3B_$iuN{F(GrC*2^;_e|>g);2n+G_i{HVmirFihJ#- za8UwFE0G%y&&<${DEM&JNrKKpGFHrN0%wVxb>dvtTG6)5t6;gzZE9hh>!R(&AAZsU zDtMo6tCOM~dEv19wVc7S|8y2C`}WLrTS=cKW@mXbH)l=#&F!vgs8-<3o!jc@Klk#n zL|7~#rcm4cyj5Jw2MtDTIn36~Z8>v$xa|W&MJ-IYEpvN>?Y6<JZI8&@ZVs}w$QO~% zk(N2g*mHnUS18mL>swq6YBt$6<*TFZHmSQ!wlkIdwcTc$zi+s<+x+Hki*15$&0K2a zwukx3YDWdze)O&9TAr0ZKwA#6waFjhT4uYidT3}_a%Bk&k!__@%G++__tV0J+A@y~ zvl;y=Y1_kWk$%oN!)?R-DroV9YdH*dD`14}m|t^ke}uL_By+zd$kw1hU3I@js~?m5 zev|F<0wy(Gi^*2Epq8%1Y|C4)s<z$iw%uY&C|E;_&!VLl;g(*o?O?(3+Ht|QyRP^` zY=sJiYTH9>?F%{63AK$Z6sBztb=w|h`>{}<mQI+Oj@jatPPna3;Xv)UaNCf=&iEp1 z3k%oOwnx}bIkyJ~*`5`yp>AinS`jULu*uf3NHw(w1Zy3{Y#UNR>mb2q+lC^++HS3b zxbL>u@)y-|8LZWY*{wE$gKf!0wI0FphN8|?Lu}`ZHqdetVtY``xjod@q*x1Wd#Ky? zFx&28T4{sB+_s0?iWRqL+0%N5#Vz*{wo%0!tCbk6bq<SL_CkVecZ)Yt_lIbmBg=l1 zt(U*nDML)Qnf?L!9UVHvEIM>>pxGoV<A&-=+AjHPT{^^Ud*H7XCd6VZR>Gpiu2l}1 zca6=EVB4q?CN=XR!D<tSW{%B}5ZezW%vypWT2Bjd>-r&~wmK!Xt{W1n>>s1o#%D;F zZE;Dnmax`$OcuA8!)^bTbjIu)Qyi3;GwP^RRV@PNpbAyajMQu0A~eXhyOfqR%Q2<3 zltWFnlBH{_?Z<NFcC&42X^XbqY&+-*Z?XMRI#x|6)H#~MG8-^7*mk2#Lv6oSMW*n~ zl7upnj1k&?XB~yRXEfBd%UE3t5UN#TmH=V4A^~mHS`KxNvmjGuU4(|)YylBk0Ijmj zL2e^4G{W{WprsZ-t1NSnV-7YrdP`W4=q+Kgvf&%=GPXr!{nYG)X&sIk+%??7Otvd! ztE+K^IY(oVTaOJh+rr9~)dD!jBW>$yx-g4vdO2;RgjtlxiOx<D7Hqp!PV1Rr!OC}; zJ3?&X<(*M#b!c|)r(vPC8Re^LX=-(-1<*<o<|tqwMVyz%r=acM^3EbUD>T@xh~c&d z6}0XW7H;z`?_7?s&97k6QgK!zgU(g5@F3fx3ZZI>;m*1XQ8GJaxXIS7Vr?~saA)N) z2#G;E$}w!i0!?O{u~IE9ptBMgjhRVVY%?l_YXO|on)?6=54QbPse;;{Sw7}0P<V)~ zdFATb_7J!2p|%y3wX;chs4b|XR_O3B+pEgj1jF*juI=Hr=qk>5!rit<*fv*jhL6bH z9uZ{osj7`HmXB7_;*T)d23FOoB*IxGbP-ocBh0q*RRh(MMmVd22G0y&v018>*8(`J zB1?c^+tg}Rv;f)=HD?JBV!KgID@#O(^3N1!kBngcs$O4hnh0mVavS^+VYc<vD`+u0 zdlHSDnYZxyHMCP_M7UCCnk(W6TmKr`wNgYx=8n)Hs-}i|dJ)SFtE$x$%6M-WSj*9D zj%C+&vu%B#+RULrW@YSjErrk^%lw+^AY;+?xhs6IEvBa0JfY0gncG8bJ8HIeTt_im zuCH27ONyQl)XY)9&>&|8&<!Y{w$U-LOs2qKS;=2ZU*C2wNF7<BL9Y66jjYh1a9d52 zIvKL8T{3WKpq<M@nMXb{HPm8uj<AT#ZXaq2vdLz3CSX~MfL3x=c&N!_>tQbAXfc+Z z0WwoyV68J()b=}jQ-s@o%Y2JgZOmD-YHHPQqS`F#HE$@(sV3+45ZiW(+5tjM+RS7L zGH?6ca-fYaecRgcU9Clpwdxw{8w`e;HPaJEC8YMNoRQYsRK+N6mzM1a(w))Olu{%k zQl;Vi>?<Yk8O!=eehy<PNlKLBS&n8;vNTw-7xU1)K5TFKtuCX8{oFO(PMxy-N8K>H z<%aHLloAu*QAk-F=%H8g7(MEiu31wK3Ni)p$7D2{$b_t|nT){}12-xq><@xG{B+7v zlSdwFl+>7H3}hrx%8&+-=x9e4(pVQ+%3w=bsfE;3>MBJ^9i%2Kb&x6(GEwT!XBGC2 z<#>Y>M{!c5bjJ~DtVXu=CQK?nGuUI4YDsnZEN(POX34_6ZE+7{l+xPdQM^@xqriO~ zx#-7d0+kR?c%u}=UlV`Dr&w0EIM>8BgH)5hM(wY1u&hTlC8DT@dFpwy2R!ZP&0e2P zx3XW9FxHVnu_UTJp3i=48%lbjtZm3`tgG_X(xkCh)I=hUp&paU&vdpGH;Q8_6Mm>; zPX<RD9c56PHIXp=*^){lTGa>=rBMVGt=o^yY5W|_dYZPD?5OlOwp5V<*%w6wBFR+t ztJxO`i!J^56h#@zv0__wwu!L)9a|G=L=h^(u}`F&Vs+%inP>umMT?2@r)h@|=TOl~ zq63OZMLmcv8PDPAgdWPLNL*xIl+5T@6K$JFOk%wtI?zL!@v}EeqHcp}H__Hs(TL$v z1Wj+0dXj+n6dg{-ZGS#vFy%F~zc4=y+MyzAYDS$EDb_`{(;S&lYejSwF-}BCwVR2? zO(WD$M;8@!MFaAnK(Y_t>(x<j`>jk>`;vQJf9O2I%=Q@%y!LqMj7qa7Uc2+A#wVuq z_wkAB)TWJ(c&ejJeCAc!9{$wpsAqAhrPPrI38gHdEM<^{nk~EGg;$_w`5wj^t&RN> zlM;-*Sd28LCdH3QNf_=}OEtzPrWt$Xv8TN9nqQg610}zx=-txWUZ}eFpGB?B8#k_E zOiVWpO;3n7W~3VXC!{2##bzWJ;}Zraq{Jtr#Emp2ru0iqOODM*Oif|g7%M*G(h`yr zQZizbjQwKM2e2p57(IY^(uXHz#0@Z}B@9bQ%Sab7W(-I$4o*vrOGr;Q5|5ffVw^EK zc2I)Rl98I4lwRF9d_W>ckqHhVyx6B^fEZGf0u41%jddtSJ>wW-9V(}o(yyua$5uzJ ziw>c79nlREq!EsFN56A)JJE&Iwi81njcz6St8)<cceI^oZPBCE4%U|CK`e{OK(w#X zF-0Y@?3^(Nvm7f~#b9yvNOk;Wj`BB?RR@)taGE1Z(W6CX#Qc|84AIkvIy#kzTa8zp zsGXTkA#pmLm{#0Jr;+lCp7`$4h-@^{23OVz$QgZRxwV8u2Wd-_h#pqmI5;Ubj?R*p zV*jq0_qToMzkA2(E82Ii_KqHBuWiaTV4kj-eZ^O~8tIf<hjPU!tq<oaZeM>mS1V8D z!*6pnve!G3t5K>gpi*UfU{{}|C3GS7lj%N#WnHMf{#c(PULIkEl@?R<7W<3|K3{ly zn8WRjruyi-J<Sn?m7uA5e|w)<K40i{LH42_`fSdxGue-<^eO43Gb=-;>5D2a*ZKr_ zm<y{bq3e9^Dc`R2@wHpl`*ibGO0DzpRoYJ17gHW@^C_&9$?!2K8z=bqtiHP0$3qvQ zT-)k%g=~De&1a;Ca&@auer3}PeIBLl7d}UPEa8QH+WPn?L%cjod04{jwe3Epow_h3 zIaOb@b%Y@<H6<fqM22iK8=4s66XH_i6Xf7<LwsU-Tx?prV{vF~QjLC&svDe|mLUg+ z8sbN$#3nNoG7^%h)Qkk#9A;1&7St8B%BG;|Mza~A2(NCmn8124Lf98#VY?;5(A2=O z86%BxsmX&=Qy7sVUPi5!enMJWYFgif0kOjpQ`1B)63EZs1Y>%_kfDT1kWGXhk&%#+ z&JY&+n;H5IO^K^2#=2N-Zs<Q$<lk&Dv@|4=1Q|D342cvrEhRQd4h~c14%Qd0YBnS@ zzGM3*82iSGnZ#MbNJC_5Mkls(9GToVHAyy`l~aTD#k|ahb_ScVc1ce;#9({aqmWX1 zh(3=s!oWl^EHOTTtcDpn7&<iUVvNnmNK5QHG$SG1(6CL*=8<w(h@nx-=%@}&ns$&w zGnZRNHf!0mO%plP?AqNjGOBTO(`Y%uVrbMYx~X<ZsG)IG+jb&c;|@_BJ4QEbE=L3z zns$wDYK`pJGAgn+vCCm5#}?Oy-pxBib!sPvSqzR;+BA)99^FC?)mF8bslBKUZ5u|* zp}~e0O}naF!-5QI=$4U9ns$}LL$uZCC^?*3XxOAl!!~W?uy7WwO`5cfY%U5YHnZ5f zUBl?;rX47An4w)%%Se{RVeIeFR0|@9o5Whjrjd=C%HhNk-65)3vyPNHJk&s_rVXPT zHfqyUjxZTSNy8%y(NXQ%H0|89ji{DRk(4z&%#fClPVZ4xr|C<01Q~1rdkR@)F5o&E z(i4&r;xZD4B^b5F4>6=C_D_k;7@C$~jEhZ5qN5tphxV<JF>)}cFS=n$dPZ6-{ey;$ zHaI(Wjif{-dwOSL#z@&5ZiuG3-CMR%)8;KBiOOPV8rg)O!3JwbO4y+x?aV4saX|0J zQI7gC1%(<&F2NX^lo*>%s`N;8pah5TlQwef6(fRkR^P-Vk!XmalY!F<9g6`)=jv=2 z7MnCQffE&{6^baEL)0x=R`t%jD%aEXu~sn(gAK8wDjeg~Vu+28r`FPCl4PeN2POkK z8pbFNWg$ssbA-s3SXq`iJ|kGCb~uJ%%<y9^JtJYT*dhkJg~4v7?zPS7VuZ$8Q%1^K zTqz?(=_pU^;K4~FWf7cdppl_(VuqQjmn|l-$dag-h+sos&YuafDPpm)!O>zOyK2&L zv7D<##57{ufY>zcD3d5H^NpD-sdJ8%35UEzgb*wtZjdbIJLh~8D(1cvQH9JrVj4_i zoCli?Tp>8BN<_r5W}02hjP7-)&66Q!$BdagSY}F0=odSb`f*gK*q)ZqFCopEPC*@$ zsg@K0Q^lkd&zvWkj%iSx^N1@UWoWYF8YW(j&}O%Ij;ENx!ETeC+GJ#m(uM?!i7zQN zHbWK#<}k;KTA^k`KP!_bsr5@sO%~%qOp%Tml1wo}CS*A3Rjo(X(h@|=Xsf9isj?}| z(84evVT3b27PYE&q!ykzw}xtyEPXqPHcm{T_mf4dnZ?whREt;>D;Wv>>C6!k>Qqb% z)9*x|5>00@v@s;5GAzVOFm1^2;QotE&J46QB*zY>By1O9Xc{i>=nB+iq#-4Bcx<9b z%8)YDk&7sUHMQ@+#CXx837Q(0k>KoLqE~RkXK>3~JHz1EwAf^={Eia=(K4}Tq^dpF z%*@V^OAteaN)o+H9h4#`Cb27(Gma>X=r;6kQ;^lUd0A>d<`1z+Y@ug3ItCR^UlT2q zHZ&#O$f-+<SBwrCUE9i8FR7pCNMc?~QHvu^s|40&h4ch<WV#Y&a!bfqmTJvRRlTnk zlURC2EN4RoUwTF=m1*H;nwhaDhM-uamFZ1}^pOm2x(!EUPKdNEXEgc^8Hr6!kS$DF ziS%000(2OvfdSm#(ZpinDwD$Hacr7de26%Qrik;iRz)VB#r!lvU(|7_Aevk37wsGB zoaGp=T?|}eCoxtm2CmQtaGgTknv`lI_3iaRrm#>;P-w97-bj5t*BURQjCr(OAw1Ev z^_Ur;6d9$@pWnGrdwwil9~I+H-w{b@S=+eTHM4|sK4*4>b4DMgd^1X4H*+m;l-}rE z3s)?o^;KMJyl8Okicn^a)`vKApgpzW)c`rr!iNPZ4@c{p`l|VHK2<i^h6MOKLztBQ zWAyEuA+!fKSwfhV+hg>>&hTdOG9jRd7NbQx-Hndz%gvT4NH!|n$LcFM<8nT;w@s+* z?+hR87T!d7E|x=`;hoR$ZGP2UxeHOskJGo)iWug60xjNB7I$VSR9QJrU*Av5kn>R) z&x+itAxtT3)wggS5oXI*F2K1GuFSFO+ql-;cSR_9#_L-<V|G3j<E?FG%;7=G)XXrh zN6%`QLTaAEO>Tt_S3XV4Ra2=qL7!hMx9f4V;x}6FEO@wCu};vpb_Q`iFUu0dqWt3) z#QFR+OORk?_(Xjht@^^9Phe@?3dNn76TMk$L9R#1TqUK_B)z}$n9M47JI3+OR&8~& zMLlNaBz;k>5_yQ-$5p@KValJAT=mNXOm;bw4tGmBL^+l2Q(KucS)X64@Nnm2%3w#2 zb{-Vrc2KC&V62Z(`N!=bXDbCeT1h)7!ts_x%W#;up=zup65)K5>3FH(95xXq<<w+- z3FYDxeMzk%Tu;cw>k4P(ML1p>Xz@mf8?vfe9q{aYpR1q|ZllB!q!jzmCqUUbRiED( z*20?(XQf2AjS!1TIl9uPj3cZwzs@#vyt^poET3B=S{(O&m7L+7?dN!f;R^58fEJ5V zalKDzo1D*C@vi6XS&wl%Z&u4{304|R*M~Us&r|8l{JS-(B}BQt)u)7VV!EqQBb<%O z3ra?jGyiUlY6(^RXXslw^Y3g=_wbx!GdqDLO!;(%zKR;2J=&A!tl`~8poO;qcAsiW zf-6%d9?&|z8(|I!vv-`Szu_mI5U1L8%k=wno~f0S?O%PWZ|-gVAn~+RWB}_@P^)@U zC%vw)hkk<R!2W#sB$r;N?qO>g$JRe|j;)0U<Zx87y5Dt_ujfGV6&BZe$-)D|<9^iE zqgr`N?PK_eX(dUqt%^vJn#co=AnCUxl0W-4skoXz_U&Ximm^X8Z>#k+byiV4S0OI( z4X?MyuNJ+By5E&)HCNa9+RxjM`p>!Qo4s~p)yP~)WUnVR^OE#teYsaxA-7`NpRUz= z>tt8EDC4*23$^%$Z#KO>(`r#$s{38}P>XszSN5ZnKI`>Gt7*0PU&*X8_iKHLx~|+f z`<5F2S?}!eJNLU+rTxWvePLZeEzx3bWp$J-WtW^&ENa>6s{6B*?SMX~qukSW<R?q* zI|@|$jRH9vDtn!%S!k>#=E#Em#Rk2vu2YttxF&B-nNg3grtZ&HgpGXpF>9kLF`NFI z&9iKizHq~=rFq9#Qk!ji?(FH>pKj9oxp%t!Tl7V{Whvq(e9bazW}R)V7O{-F-&Mry z6`8%=OSR9MYu8BUd!cS!L~X#FX9xFzWxuyYUn$!hF@rCQzAM`Xb-ydyY7NchtEq24 z>Obf0jX9#A8ksAJ>^0-;dhSJ$9CK<;bA<AAoBml&6aGI19eH;pr<Q1(x;1;vQtN8- z>9QU5j!bIpX4U4xs8-%myH>fR_WaB;(%xMLN5hKa{$qE2ufSUy!<W3fw}$d!hyHoi z6GRfHqPI7rTIl<HWtjchswz$0`j)D4Pwvf`MU+?h;A?%+*f)B%n%on<x9Xl;PIc^l zI>@Xhqg#gTf7tZ_t|^s{<4RE}{iQx2r>^l!(X1JGdqQf5>8FNui`tQucMel$5B3t5 zA&!Z*lq+M-qumRwy!cX|=6$M^B!%0D?9zAADT9CKrNNEe`YO7d%5cU%YZ=tsMyp%j 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 XVoaq95iu1bi<Br95%+GH?zH|N+Yye6 diff --git a/usrguide/releasenotes.doc b/usrguide/releasenotes.doc index b9c5b49bcaf02c1f4c612b5cadf5d8d2506adab0..e100f7a651d4265693a911833f0ff970b1daf5cb 100644 GIT binary patch delta 114745 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 ack7+~wBmZt4TP0vQdvV{-)(T(<NZJTDO}$G delta 110527 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'HDTt~v9003I+a~*=s`ts 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 diff --git a/usrguide/userguide.doc b/usrguide/userguide.doc index da7dd72a28d15a2719d0a32bc9680a8633b60cb2..7588f021d967fb79e5b08c9c0784c5ceeea05f95 100644 GIT binary patch delta 13333 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 delta 14561 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 HEt38R{-<|` -- GitLab