From 51fa56b97ff178aa82497de54a5945698517e55d Mon Sep 17 00:00:00 2001 From: erititan Date: Sat, 5 Dec 2015 08:22:39 +0100 Subject: [PATCH] Sync with 5.4.1 --- common/version.h | 4 +- compiler2/Type_chk.cc | 23 +- compiler2/Type_codegen.cc | 7 +- compiler2/Value.cc | 38 +- compiler2/XerAttributes.cc | 12 +- compiler2/XerAttributes.hh | 2 + compiler2/record.c | 6 +- compiler2/record_of.c | 5 +- compiler2/ttcn3/AST_ttcn3.cc | 123 +++-- compiler2/ttcn3/AST_ttcn3.hh | 32 +- compiler2/ttcn3/TtcnTemplate.cc | 85 +-- compiler2/ttcn3/TtcnTemplate.hh | 18 +- compiler2/ttcn3/compiler.y | 4 + compiler2/ttcn3/rawAST.l | 4 + compiler2/ttcn3/rawAST.y | 26 +- compiler2/union.c | 81 ++- core/Boolean.cc | 4 + core/Integer.cc | 1 + core/Makefile | 2 + core/Runtime.cc | 9 +- core/XER.cc | 13 + core/XER.hh | 14 +- core2/Basetype2.cc | 4 + .../Semantic_Analyser/Makefile.semantic | 2 +- .../Semantic_Analyser/TTCN3_SA_6_TD.script | 16 +- .../.gitignore | 0 .../Makefile | 0 .../template/TempOmit_SE.ttcn | 16 + .../TempRes_SE.ttcn | 0 .../{template_restrictions => template}/t | 0 .../RAW/Annex_E_variants/Annex_E_variants.cfg | 14 + .../Annex_E_variants/Annex_E_variants.ttcn | 514 ++++++++++++++++++ regression_test/RAW/Annex_E_variants/Makefile | 54 ++ .../XML/AbstractBlock/AbstractBlock.ttcn | 240 ++++++++ regression_test/XML/AbstractBlock/Makefile | 138 +++++ .../EXER-whitepaper/AnyElementOptional.ttcnpp | 17 +- .../XML/EXER-whitepaper/Untagged.ttcnpp | 36 ++ .../XML/EXER-whitepaper/UseType.ttcnpp | 50 ++ regression_test/XML/Makefile | 2 +- ...mespace.ttcn => NoTargetNamespace2_e.ttcn} | 8 +- .../www_example_org_attrib_order_a_e.ttcn | 2 +- ...e_org_generate_element_substitution_e.ttcn | 3 +- .../www_example_org_no_ns_connector_e.ttcn | 1 + ...ample_org_only_element_substitution_e.ttcn | 98 ++++ ..._substitutiongroup_abstract_block_1_e.ttcn | 5 +- ..._substitutiongroup_abstract_block_2_e.ttcn | 5 +- ...tutiongroup_complex_without_element_e.ttcn | 9 +- ...substitutiongroup_complextype_block_e.ttcn | 95 ++++ .../www_example_org_substitutiongroup_e.ttcn | 3 +- ...rg_substitutiongroup_long_extension_e.ttcn | 6 +- ..._example_org_substitutiongroup_main_e.ttcn | 3 +- ...ample_org_substitutiongroup_name_as_e.ttcn | 131 +++++ ...xample_org_substitutiongroup_rename_e.ttcn | 101 ++++ ...xample_org_type_subs_with_elem_subs_e.ttcn | 152 ++++++ ...rg_type_substitution_abstract_block_e.ttcn | 210 +++++++ ...e_org_type_substitution_builtintype_e.ttcn | 104 ++++ ...example_org_type_substitution_chain_e.ttcn | 161 ++++++ .../www_example_org_type_substitution_e.ttcn | 113 ++++ ...g_type_substitution_elem_in_ct_mod1_e.ttcn | 150 +++++ ...g_type_substitution_elem_in_ct_mod2_e.ttcn | 61 +++ ..._example_org_type_substitution_mod1_e.ttcn | 168 ++++++ ..._example_org_type_substitution_mod2_e.ttcn | 110 ++++ ...xample_org_type_substitution_rename_e.ttcn | 103 ++++ ...le_org_type_substitution_simpletype_e.ttcn | 190 +++++++ .../XML/XmlWorkflow/src/xmlTest.prj | 33 +- .../src/xmlTest_Functions_element.ttcn | 182 +++++++ .../XmlWorkflow/src/xmlTest_Testcases.ttcn | 218 +++++++- .../xsd/only_element_substitution.xsd | 42 ++ .../XML/XmlWorkflow/xsd/substitutiongroup.xsd | 10 +- .../substitutiongroup_complextype_block.xsd | 32 ++ .../xsd/substitutiongroup_name_as.xsd | 44 ++ .../substitutiongroup_notargetnamespace.xsd | 26 + .../xsd/substitutiongroup_rename.xsd | 30 + .../xsd/type_subs_with_elem_subs.xsd | 62 +++ .../XML/XmlWorkflow/xsd/type_substitution.xsd | 41 ++ .../xsd/type_substitution_abstract_block.xsd | 91 ++++ .../xsd/type_substitution_builtintype.xsd | 31 ++ .../xsd/type_substitution_chain.xsd | 68 +++ .../xsd/type_substitution_elem_in_ct_mod1.xsd | 56 ++ .../xsd/type_substitution_elem_in_ct_mod2.xsd | 19 + .../xsd/type_substitution_mod1.xsd | 69 +++ .../xsd/type_substitution_mod2.xsd | 35 ++ .../xsd/type_substitution_rename.xsd | 38 ++ .../xsd/type_substitution_simpletype.xsd | 63 +++ .../openTypeNames/IO_based_message.asn | 14 +- .../openTypeNames/Open_type_use.ttcn | 68 ++- regression_test/logFiles/logfilter.sh | 2 +- .../negativeTest/NegTest_RAW_Testcases.ttcn | 10 +- .../templateInt/ImportedTemplates.ttcn | 12 + regression_test/templateInt/Makefile | 6 +- regression_test/templateInt/TtemplateInt.ttcn | 52 ++ usrguide/referenceguide.doc | Bin 1682432 -> 1684480 bytes xsdconvert/ComplexType.cc | 128 ++++- xsdconvert/ComplexType.hh | 7 +- xsdconvert/Makefile | 4 + xsdconvert/RootType.cc | 8 + xsdconvert/RootType.hh | 9 + xsdconvert/SimpleType.cc | 185 ++++++- xsdconvert/SimpleType.hh | 27 +- xsdconvert/TTCN3Module.cc | 2 + xsdconvert/TTCN3Module.hh | 47 ++ xsdconvert/TTCN3ModuleInventory.cc | 4 + xsdconvert/XMLParser.cc | 9 - xsdconvert/converter.cc | 7 +- 104 files changed, 5113 insertions(+), 286 deletions(-) rename function_test/Semantic_Analyser/{template_restrictions => template}/.gitignore (100%) rename function_test/Semantic_Analyser/{template_restrictions => template}/Makefile (100%) create mode 100644 function_test/Semantic_Analyser/template/TempOmit_SE.ttcn rename function_test/Semantic_Analyser/{template_restrictions => template}/TempRes_SE.ttcn (100%) rename function_test/Semantic_Analyser/{template_restrictions => template}/t (100%) create mode 100644 regression_test/RAW/Annex_E_variants/Annex_E_variants.cfg create mode 100644 regression_test/RAW/Annex_E_variants/Annex_E_variants.ttcn create mode 100644 regression_test/RAW/Annex_E_variants/Makefile create mode 100644 regression_test/XML/AbstractBlock/AbstractBlock.ttcn create mode 100644 regression_test/XML/AbstractBlock/Makefile rename regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/{NoTargetNamespace.ttcn => NoTargetNamespace2_e.ttcn} (89%) create mode 100644 regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_only_element_substitution_e.ttcn create mode 100644 regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_complextype_block_e.ttcn create mode 100644 regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_name_as_e.ttcn create mode 100644 regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_rename_e.ttcn create mode 100644 regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_subs_with_elem_subs_e.ttcn create mode 100644 regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_abstract_block_e.ttcn create mode 100644 regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_builtintype_e.ttcn create mode 100644 regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_chain_e.ttcn create mode 100644 regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_e.ttcn create mode 100644 regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_elem_in_ct_mod1_e.ttcn create mode 100644 regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_elem_in_ct_mod2_e.ttcn create mode 100644 regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_mod1_e.ttcn create mode 100644 regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_mod2_e.ttcn create mode 100644 regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_rename_e.ttcn create mode 100644 regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_simpletype_e.ttcn create mode 100644 regression_test/XML/XmlWorkflow/xsd/only_element_substitution.xsd create mode 100644 regression_test/XML/XmlWorkflow/xsd/substitutiongroup_complextype_block.xsd create mode 100644 regression_test/XML/XmlWorkflow/xsd/substitutiongroup_name_as.xsd create mode 100644 regression_test/XML/XmlWorkflow/xsd/substitutiongroup_notargetnamespace.xsd create mode 100644 regression_test/XML/XmlWorkflow/xsd/substitutiongroup_rename.xsd create mode 100644 regression_test/XML/XmlWorkflow/xsd/type_subs_with_elem_subs.xsd create mode 100644 regression_test/XML/XmlWorkflow/xsd/type_substitution.xsd create mode 100644 regression_test/XML/XmlWorkflow/xsd/type_substitution_abstract_block.xsd create mode 100644 regression_test/XML/XmlWorkflow/xsd/type_substitution_builtintype.xsd create mode 100644 regression_test/XML/XmlWorkflow/xsd/type_substitution_chain.xsd create mode 100644 regression_test/XML/XmlWorkflow/xsd/type_substitution_elem_in_ct_mod1.xsd create mode 100644 regression_test/XML/XmlWorkflow/xsd/type_substitution_elem_in_ct_mod2.xsd create mode 100644 regression_test/XML/XmlWorkflow/xsd/type_substitution_mod1.xsd create mode 100644 regression_test/XML/XmlWorkflow/xsd/type_substitution_mod2.xsd create mode 100644 regression_test/XML/XmlWorkflow/xsd/type_substitution_rename.xsd create mode 100644 regression_test/XML/XmlWorkflow/xsd/type_substitution_simpletype.xsd create mode 100644 regression_test/templateInt/ImportedTemplates.ttcn diff --git a/common/version.h b/common/version.h index 8f25a76..a6d33ae 100644 --- a/common/version.h +++ b/common/version.h @@ -11,7 +11,7 @@ /* Version numbers */ #define TTCN3_MAJOR 5 #define TTCN3_MINOR 4 -#define TTCN3_PATCHLEVEL 0 +#define TTCN3_PATCHLEVEL 1 //#define TTCN3_BUILDNUMBER 0 /* The aggregated version number must be set manually since some stupid @@ -22,7 +22,7 @@ * TTCN3_VERSION = TTCN3_MAJOR * 1000000 + TTCN3_MINOR * 10000 + * TTCN3_PATCHLEVEL * 100 + TTCN3_BUILDNUMBER */ -#define TTCN3_VERSION 50400 +#define TTCN3_VERSION 50401 /* A monotonically increasing version number. * An official release is deemed to have the highest possible build number (99) diff --git a/compiler2/Type_chk.cc b/compiler2/Type_chk.cc index d3bf10e..31df571 100644 --- a/compiler2/Type_chk.cc +++ b/compiler2/Type_chk.cc @@ -2301,6 +2301,27 @@ void Type::chk_xer() { // XERSTUFF semantic check } empties.clear(); } // if secho + + if (xerattrib->abstract_ || xerattrib->block_) { + switch (ownertype) { + case OT_COMP_FIELD: + if (parent_type->typetype == T_CHOICE_A || + parent_type->typetype == T_CHOICE_T) { + if (parent_type->xerattrib != NULL && parent_type->xerattrib->useUnion_) { + error("ABSTRACT and BLOCK cannot be used on fields of a union with " + "attribute USE-UNION."); + } + break; + } + // else fall through + case OT_RECORD_OF: + case OT_TYPE_DEF: + warning("ABSTRACT and BLOCK only affects union fields."); + break; + default: + break; + } + } } @@ -3215,7 +3236,7 @@ bool Type::chk_this_refd_value(Value *value, Common::Assignment *lhs, expected_v #endif case Assignment::A_EXT_CONST: if (expected_value == EXPECTED_CONSTANT) { - value->error("Reference to an (evaluatable) constant value was " + value->error("Reference to an (evaluable) constant value was " "expected instead of %s", ass->get_description().c_str()); error_flag = true; diff --git a/compiler2/Type_codegen.cc b/compiler2/Type_codegen.cc index cfddb7a..af6de36 100644 --- a/compiler2/Type_codegen.cc +++ b/compiler2/Type_codegen.cc @@ -490,7 +490,7 @@ void Type::generate_code_xerdescriptor(output_struct* target) int atrib=0, any_atr=0, any_elem=0, base64=0, decimal=0, embed=0, list=0, text=0, untagged=0, use_nil=0, use_number=0, use_order=0, use_qname=0, use_type_attr=0, ws=0, has_1untag=0, form_qualified=0, any_from=0, - any_except=0, nof_ns_uris=0; + any_except=0, nof_ns_uris=0, blocked=0; const char* dfe_str = 0; char** ns_uris = 0; char* oftype_descr_name = 0; @@ -507,6 +507,7 @@ void Type::generate_code_xerdescriptor(output_struct* target) any_elem= has_ae(xerattrib); atrib = xerattrib->attribute_; base64 = xerattrib->base64_; + blocked = xerattrib->abstract_ || xerattrib->block_; decimal = xerattrib->decimal_; embed = xerattrib->embedValues_; form_qualified = (xerattrib->form_ & XerAttributes::QUALIFIED) @@ -607,7 +608,7 @@ void Type::generate_code_xerdescriptor(output_struct* target) // Generate the XER descriptor itself 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, " + " {%lu, %lu}, %s%s%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, %s };\n", gennameown_str, bxer_name.c_str(), last_s.c_str(), // names @@ -616,6 +617,7 @@ void Type::generate_code_xerdescriptor(output_struct* target) (any_elem ? " |ANY_ELEMENT" : ""), (atrib ? " |XER_ATTRIBUTE" : ""), (base64 ? " |BASE_64" : ""), + (blocked ? " |BLOCKED" : ""), (decimal ? " |XER_DECIMAL" : ""), (embed ? " |EMBED_VALUES" : ""), (list ? " |XER_LIST" : ""), @@ -630,6 +632,7 @@ void Type::generate_code_xerdescriptor(output_struct* target) (form_qualified ? "" : " |FORM_UNQUALIFIED"), (any_from ? " |ANY_FROM" : ""), (any_except ? " |ANY_EXCEPT" : ""), + (is_optional_field() ? " |XER_OPTIONAL" : ""), whitespace_action[ws], (dfe_str ? '&' : ' '), (dfe_str ? dfe_str : "NULL"), "module_object", diff --git a/compiler2/Value.cc b/compiler2/Value.cc index 1ea0cb0..d7c4e8e 100644 --- a/compiler2/Value.cc +++ b/compiler2/Value.cc @@ -4376,7 +4376,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, } switch (exp_val) { case Type::EXPECTED_CONSTANT: - error("An evaluatable constant value was expected instead of operation " + error("An evaluable constant value was expected instead of operation " "`apply()'"); set_valuetype(V_ERROR); break; @@ -5637,7 +5637,7 @@ error: case Assignment::A_MODULEPAR: case Assignment::A_MODULEPAR_TEMP: if(exp_val==Type::EXPECTED_CONSTANT) { - u.expr.ti1->error("Reference to an (evaluatable) constant value was " + u.expr.ti1->error("Reference to an (evaluable) constant value was " "expected instead of %s", t_ass->get_description().c_str()); goto error; } @@ -5980,7 +5980,7 @@ error: Ttcn::StatementBlock *my_sb; switch (exp_val) { case Type::EXPECTED_CONSTANT: - error("An evaluatable constant value was expected instead of operation " + error("An evaluable constant value was expected instead of operation " "`%s'", get_opname()); goto error; case Type::EXPECTED_STATIC_VALUE: @@ -11113,15 +11113,13 @@ error: Ttcn::ActualParList *parlist = u.ref.ref->get_parlist(); if (parlist) { str = parlist->rearrange_init_code(str, - u.ref.ref->get_refd_assignment()->get_my_scope()->get_scope_mod_gen() - == my_scope->get_scope_mod_gen()); + u.ref.ref->get_refd_assignment()->get_my_scope()->get_scope_mod_gen()); } break; } case V_INVOKE: { str = u.invoke.v->rearrange_init_code(str); - bool type_is_local = u.invoke.v->get_expr_governor_last()->get_my_scope() - ->get_scope_mod_gen() == my_scope->get_scope_mod_gen(); - str = u.invoke.ap_list->rearrange_init_code(str, type_is_local); + str = u.invoke.ap_list->rearrange_init_code(str, + u.invoke.v->get_expr_governor_last()->get_my_scope()->get_scope_mod_gen()); break; } case V_EXPR: switch (u.expr.v_optype) { @@ -11167,15 +11165,11 @@ error: case OPTYPE_DECODE: { Ttcn::ActualParList *parlist = u.expr.r1->get_parlist(); Common::Assignment *ass = u.expr.r1->get_refd_assignment(); - bool rearrange = (ass->get_my_scope()->get_scope_mod_gen() == - my_scope->get_scope_mod_gen()); - if (parlist) str = parlist->rearrange_init_code(str, rearrange); + if (parlist) str = parlist->rearrange_init_code(str, ass->get_my_scope()->get_scope_mod_gen()); parlist = u.expr.r2->get_parlist(); ass = u.expr.r2->get_refd_assignment(); - rearrange = (ass->get_my_scope()->get_scope_mod_gen() == - my_scope->get_scope_mod_gen()); - if (parlist) str = parlist->rearrange_init_code(str, rearrange); + if (parlist) str = parlist->rearrange_init_code(str, ass->get_my_scope()->get_scope_mod_gen()); break; } case OPTYPE_ADD: case OPTYPE_SUBTRACT: @@ -11214,13 +11208,13 @@ error: if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str); break; case OPTYPE_SUBSTR: - str = u.expr.ti1->rearrange_init_code(str); + str = u.expr.ti1->rearrange_init_code(str, my_scope->get_scope_mod_gen()); str = u.expr.v2->rearrange_init_code(str); str = u.expr.v3->rearrange_init_code(str); break; case OPTYPE_REGEXP: - str = u.expr.ti1->rearrange_init_code(str); - str = u.expr.t2->rearrange_init_code(str); + str = u.expr.ti1->rearrange_init_code(str, my_scope->get_scope_mod_gen()); + str = u.expr.t2->rearrange_init_code(str, my_scope->get_scope_mod_gen()); str = u.expr.v3->rearrange_init_code(str); break; case OPTYPE_DECOMP: @@ -11229,10 +11223,10 @@ error: str = u.expr.v3->rearrange_init_code(str); break; case OPTYPE_REPLACE: - str = u.expr.ti1->rearrange_init_code(str); + str = u.expr.ti1->rearrange_init_code(str, my_scope->get_scope_mod_gen()); str = u.expr.v2->rearrange_init_code(str); str = u.expr.v3->rearrange_init_code(str); - str = u.expr.ti4->rearrange_init_code(str); + str = u.expr.ti4->rearrange_init_code(str, my_scope->get_scope_mod_gen()); break; case OPTYPE_LENGTHOF: case OPTYPE_SIZEOF: @@ -11240,14 +11234,14 @@ error: case OPTYPE_ENCODE: case OPTYPE_ISPRESENT: case OPTYPE_TTCN2STRING: - str = u.expr.ti1->rearrange_init_code(str); + str = u.expr.ti1->rearrange_init_code(str, my_scope->get_scope_mod_gen()); break; case OPTYPE_ISCHOSEN_T: - str = u.expr.t1->rearrange_init_code(str); + str = u.expr.t1->rearrange_init_code(str, my_scope->get_scope_mod_gen()); break; case OPTYPE_MATCH: str = u.expr.v1->rearrange_init_code(str); - str = u.expr.t2->rearrange_init_code(str); + str = u.expr.t2->rearrange_init_code(str, my_scope->get_scope_mod_gen()); break; default: // other kinds of expressions cannot appear within templates diff --git a/compiler2/XerAttributes.cc b/compiler2/XerAttributes.cc index 62dd84b..c4a9f57 100644 --- a/compiler2/XerAttributes.cc +++ b/compiler2/XerAttributes.cc @@ -25,10 +25,12 @@ static const NamespaceRestriction empty_nsr = { static const XerAttributes::NameChange nochange= { NamespaceSpecification::NO_MANGLING }; XerAttributes::XerAttributes() -: attribute_(false) +: abstract_(false) +, attribute_(false) , anyAttributes_(empty_nsr) , anyElement_(empty_nsr) , base64_(false) +, block_(false) , decimal_(false) , defaultForEmpty_(0) , defaultValue_(0) @@ -127,6 +129,7 @@ void XerAttributes::print(const char *type_name) const { fprintf(stderr, "XER attributes(%p) for %s:\n", (const void*)this, type_name); if (empty()) fputs("...Empty...\n", stderr); else { + fputs(abstract_ ? "ABSTRACT\n" : "", stderr); fputs(attribute_ ? "ATTRIBUTE\n" : "", stderr); if (has_aa(this)) { @@ -153,6 +156,7 @@ void XerAttributes::print(const char *type_name) const { } } fputs(base64_ ? "BASE64\n" : "", stderr); + fputs(block_ ? "BLOCK\n" : "", stderr); fputs(decimal_ ? "DECIMAL\n" : "", stderr); if (defaultForEmpty_) fprintf(stderr, "DEFAULT-FOR-EMPTY '%s'\n", defaultForEmpty_); @@ -238,6 +242,7 @@ fprintf(stderr, "@@@ replacing:\n"); print("orig."); other.print("other"); */ + abstract_ |= other.abstract_; attribute_ |= other.attribute_; if (has_aa(&other)) { FreeNamespaceRestriction(anyAttributes_); @@ -260,6 +265,7 @@ other.print("other"); } } base64_ |= other.base64_; + block_ |= other.block_; decimal_ |= other.decimal_; if (other.defaultForEmpty_ != 0) { @@ -362,10 +368,12 @@ other.print("other"); bool XerAttributes::empty() const { - return !attribute_ + return !abstract_ + && !attribute_ && !has_aa(this) && !has_ae(this) && !base64_ + && !block_ && !decimal_ && defaultForEmpty_ == 0 && !element_ diff --git a/compiler2/XerAttributes.hh b/compiler2/XerAttributes.hh index 82e6028..06ea432 100644 --- a/compiler2/XerAttributes.hh +++ b/compiler2/XerAttributes.hh @@ -136,11 +136,13 @@ public: /// If the NamespaceSpecification contains a string, free it. static void FreeNamespace(NamespaceSpecification& ns); public: + bool abstract_; bool attribute_; NamespaceRestriction anyAttributes_; NamespaceRestriction anyElement_; /// Base64 encoding for string-like types (XSD:base64Binary) bool base64_; + bool block_; /// No scientific notation for float bool decimal_; /// String parsed out from the encoding attribute diff --git a/compiler2/record.c b/compiler2/record.c index 097ffe7..3199d1f 100644 --- a/compiler2/record.c +++ b/compiler2/record.c @@ -1942,7 +1942,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) " && *p_td.my_module->get_ns(p_td.ns_index)->px == '\\0';\n" ); - src = mputstr(src, " const boolean delay_close = e_xer"); + src = mputstr(src, " boolean delay_close = e_xer"); if (!(num_attributes | sdef->xerUseQName)) { src = mputprintf(src, " && (need_control_ns%s || empty_ns_hack)", (start_at < sdef->nElements) ? " || num_collected" : ""); @@ -1973,9 +1973,11 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc) " if (chopped_chars) {\n" " p_buf.increase_length(-chopped_chars);\n" " }\n" + "%s" " }\n" , (want_namespaces ? "-(delay_close || (e_xer && (p_td.xer_bits & HAS_1UNTAGGED)))" : "") - , (want_namespaces ? " || delay_close" : "")); + , (want_namespaces ? " || delay_close" : "") + , (want_namespaces ? " delay_close = TRUE;\n" : "")); } src = mputprintf(src, diff --git a/compiler2/record_of.c b/compiler2/record_of.c index 875a06c..e72d8d9 100644 --- a/compiler2/record_of.c +++ b/compiler2/record_of.c @@ -1390,7 +1390,7 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " if ((XML_READER_TYPE_ELEMENT == type && p_reader.MoveToFirstAttribute() == 1)\n" " || XML_READER_TYPE_ATTRIBUTE == type) {\n" " verify_name(p_reader, p_td, e_xer);\n" - " break;" + " break;\n" " }\n" " }\n" " if (e_xer && (p_td.xer_bits & XER_LIST)) {\n" @@ -1545,6 +1545,9 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output) " }\n" /* next read */ " }\n" /* if not empty element */ " }\n" /* if not LIST */ + " if (!own_tag && e_xer && (p_td.xer_bits & XER_OPTIONAL) && val_ptr->n_elements == 0) {\n" + " clean_up();\n" /* set it to unbound, so the OPTIONAL class sets it to omit */ + " }\n" " return 1;\n" "}\n\n" ); diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc index efe3c18..cb936e8 100644 --- a/compiler2/ttcn3/AST_ttcn3.cc +++ b/compiler2/ttcn3/AST_ttcn3.cc @@ -7382,7 +7382,7 @@ namespace Ttcn { TemplateInstance *p_defval, bool p_lazy_eval) : Definition(p_asstype, p_name), type(p_type), my_parlist(0), used_as_lvalue(false), template_restriction(TR_NONE), - lazy_eval(p_lazy_eval) + lazy_eval(p_lazy_eval), defval_generated(false) { switch (p_asstype) { case A_PAR_VAL: @@ -7408,7 +7408,7 @@ namespace Ttcn { Identifier* p_name, TemplateInstance *p_defval, bool p_lazy_eval) : Definition(p_asstype, p_name), type(p_type), my_parlist(0), used_as_lvalue(false), template_restriction(p_template_restriction), - lazy_eval(p_lazy_eval) + lazy_eval(p_lazy_eval), defval_generated(false) { switch (p_asstype) { case A_PAR_TEMPL_IN: @@ -7427,7 +7427,8 @@ namespace Ttcn { FormalPar::FormalPar(asstype_t p_asstype, Identifier* p_name, TemplateInstance *p_defval) : Definition(p_asstype, p_name), type(0), my_parlist(0), - used_as_lvalue(false), template_restriction(TR_NONE), lazy_eval(false) + used_as_lvalue(false), template_restriction(TR_NONE), lazy_eval(false), + defval_generated(false) { if (p_asstype != A_PAR_TIMER) FATAL_ERROR("Ttcn::FormalPar::FormalPar(): invalid parameter type"); @@ -8100,34 +8101,23 @@ namespace Ttcn { } } } - - void FormalPar::generate_code_defval(output_struct *target, bool) + + char* FormalPar::generate_code_defval(char* str) { - if (!defval.ap) return; + if (!defval.ap || defval_generated) return str; + defval_generated = true; switch (defval.ap->get_selection()) { case ActualPar::AP_VALUE: { Value *val = defval.ap->get_Value(); - const_def cdef; - Code::init_cdef(&cdef); - type->generate_code_object(&cdef, val); - Code::merge_cdef(target, &cdef); - Code::free_cdef(&cdef); if (use_runtime_2 && TypeConv::needs_conv_refd(val)) { - target->functions.post_init = TypeConv::gen_conv_code_refd(target-> - functions.post_init, val->get_lhs_name().c_str(), val); + str = TypeConv::gen_conv_code_refd(str, val->get_lhs_name().c_str(), val); } else { - target->functions.post_init = val->generate_code_init( - target->functions.post_init, val->get_lhs_name().c_str()); + str = val->generate_code_init(str, val->get_lhs_name().c_str()); } break; } case ActualPar::AP_TEMPLATE: { TemplateInstance *ti = defval.ap->get_TemplateInstance(); Template *temp = ti->get_Template(); - const_def cdef; - Code::init_cdef(&cdef); - type->generate_code_object(&cdef, temp); - Code::merge_cdef(target, &cdef); - Code::free_cdef(&cdef); Ref_base *dref = ti->get_DerivedRef(); if (dref) { expression_struct expr; @@ -8135,22 +8125,16 @@ namespace Ttcn { expr.expr = mputprintf(expr.expr, "%s = ", temp->get_lhs_name().c_str()); dref->generate_code(&expr); - target->functions.post_init = - Code::merge_free_expr(target->functions.post_init, &expr, false); + str = Code::merge_free_expr(str, &expr, false); } if (use_runtime_2 && TypeConv::needs_conv_refd(temp)) { - target->functions.post_init = TypeConv::gen_conv_code_refd(target-> - functions.post_init, temp->get_lhs_name().c_str(), temp); + str = TypeConv::gen_conv_code_refd(str, temp->get_lhs_name().c_str(), temp); } else { - target->functions.post_init = - temp->generate_code_init(target->functions.post_init, - temp->get_lhs_name().c_str()); + str = temp->generate_code_init(str, temp->get_lhs_name().c_str()); } if (defval.ap->get_gen_restriction_check() != TR_NONE) { - target->functions.post_init = - Template::generate_restriction_check_code( - target->functions.post_init, temp->get_lhs_name().c_str(), - defval.ap->get_gen_restriction_check()); + str = Template::generate_restriction_check_code(str, + temp->get_lhs_name().c_str(), defval.ap->get_gen_restriction_check()); } break; } case ActualPar::AP_REF: @@ -8158,6 +8142,36 @@ namespace Ttcn { default: FATAL_ERROR("FormalPar::generate_code()"); } + return str; + } + + void FormalPar::generate_code_defval(output_struct *target, bool) + { + if (!defval.ap) return; + switch (defval.ap->get_selection()) { + case ActualPar::AP_VALUE: { + Value *val = defval.ap->get_Value(); + const_def cdef; + Code::init_cdef(&cdef); + type->generate_code_object(&cdef, val); + Code::merge_cdef(target, &cdef); + Code::free_cdef(&cdef); + break; } + case ActualPar::AP_TEMPLATE: { + TemplateInstance *ti = defval.ap->get_TemplateInstance(); + Template *temp = ti->get_Template(); + const_def cdef; + Code::init_cdef(&cdef); + type->generate_code_object(&cdef, temp); + Code::merge_cdef(target, &cdef); + Code::free_cdef(&cdef); + break; } + case ActualPar::AP_REF: + break; + default: + FATAL_ERROR("FormalPar::generate_code()"); + } + target->functions.post_init = generate_code_defval(target->functions.post_init); } char *FormalPar::generate_code_fpar(char *str) @@ -8900,11 +8914,20 @@ namespace Ttcn { } return str; } + + char* FormalParList::generate_code_defval(char* str) + { + for (size_t i = 0; i < pars_v.size(); i++) { + str = pars_v[i]->generate_code_defval(str); + } + return str; + } void FormalParList::generate_code_defval(output_struct *target) { - for (size_t i = 0; i < pars_v.size(); i++) + for (size_t i = 0; i < pars_v.size(); i++) { pars_v[i]->generate_code_defval(target); + } } char *FormalParList::generate_code_actual_parlist(char *str, @@ -9288,18 +9311,18 @@ namespace Ttcn { } } - char *ActualPar::rearrange_init_code(char *str, bool is_local) + char *ActualPar::rearrange_init_code(char *str, Common::Module* usage_mod) { switch (selection) { case AP_VALUE: str = val->rearrange_init_code(str); break; case AP_TEMPLATE: - str = temp->rearrange_init_code(str); + str = temp->rearrange_init_code(str, usage_mod); case AP_REF: break; case AP_DEFAULT: - if (is_local) str = act->rearrange_init_code_defval(str); + str = act->rearrange_init_code_defval(str, usage_mod); break; default: FATAL_ERROR("ActualPar::rearrange_init_code()"); @@ -9307,24 +9330,28 @@ namespace Ttcn { return str; } - char *ActualPar::rearrange_init_code_defval(char *str) + char *ActualPar::rearrange_init_code_defval(char *str, Common::Module* usage_mod) { switch (selection) { case AP_VALUE: - str = val->generate_code_init(str, val->get_lhs_name().c_str()); + if (val->get_my_scope()->get_scope_mod_gen() == usage_mod) { + str = val->generate_code_init(str, val->get_lhs_name().c_str()); + } break; case AP_TEMPLATE: { - str = temp->rearrange_init_code(str); - Ref_base *dref = temp->get_DerivedRef(); + str = temp->rearrange_init_code(str, usage_mod); Template *t = temp->get_Template(); - if (dref) { - expression_struct expr; - Code::init_expr(&expr); - expr.expr = mputprintf(expr.expr, "%s = ", t->get_lhs_name().c_str()); - dref->generate_code(&expr); - str = Code::merge_free_expr(str, &expr, false); + if (t->get_my_scope()->get_scope_mod_gen() == usage_mod) { + Ref_base *dref = temp->get_DerivedRef(); + if (dref) { + expression_struct expr; + Code::init_expr(&expr); + expr.expr = mputprintf(expr.expr, "%s = ", t->get_lhs_name().c_str()); + dref->generate_code(&expr); + str = Code::merge_free_expr(str, &expr, false); + } + str = t->generate_code_init(str, t->get_lhs_name().c_str()); } - str = t->generate_code_init(str, t->get_lhs_name().c_str()); break; } default: FATAL_ERROR("ActualPar::rearrange_init_code_defval()"); @@ -9602,10 +9629,10 @@ namespace Ttcn { template_refs.clear(); } - char *ActualParList::rearrange_init_code(char *str, bool is_local) + char *ActualParList::rearrange_init_code(char *str, Common::Module* usage_mod) { for (size_t i = 0; i < params.size(); i++) - str = params[i]->rearrange_init_code(str, is_local); + str = params[i]->rearrange_init_code(str, usage_mod); return str; } diff --git a/compiler2/ttcn3/AST_ttcn3.hh b/compiler2/ttcn3/AST_ttcn3.hh index 119f4a3..30912fe 100644 --- a/compiler2/ttcn3/AST_ttcn3.hh +++ b/compiler2/ttcn3/AST_ttcn3.hh @@ -119,12 +119,11 @@ namespace Ttcn { * aliasing problems with other out/inout parameters. */ void generate_code(expression_struct *expr, bool copy_needed, bool lazy_param=false, bool used_as_lvalue=false) const; /** Appends the initialization sequence of all (directly or indirectly) - * referred non-parameterized templates to \a str and returns the resulting - * string. Flag \a is_local indicates whether the respective formal - * parameter is in the same module as \a this. It is considered only if - * \a selection is AP_DEFAULT. */ - char *rearrange_init_code(char *str, bool is_local); - char *rearrange_init_code_defval(char *str); + * referred non-parameterized templates and the default values of all + * parameterized templates to \a str and returns the resulting string. + * Only objects belonging to module \a usage_mod are initialized. */ + char *rearrange_init_code(char *str, Common::Module* usage_mod); + char *rearrange_init_code_defval(char *str, Common::Module* usage_mod); /** Appends the string representation of the actual parameter to \a str. */ void append_stringRepr(string& str) const; virtual void dump(unsigned level) const; @@ -171,10 +170,10 @@ namespace Ttcn { Type *p_comptype, bool p_compself); /** Walks through the parameter list and appends the initialization * sequence of all (directly or indirectly) referred non-parameterized - * templates to \a str and returns the resulting string. Flag \a is_local - * indicates whether the respective formal parameter list is in the same - * module as \a this. */ - char *rearrange_init_code(char *str, bool is_local); + * templates and the default values of all parameterized templates to + * \a str and returns the resulting string. + * Only objects belonging to module \a usage_mod are initialized. */ + char *rearrange_init_code(char *str, Common::Module* usage_mod); virtual void dump(unsigned level) const; }; @@ -1588,6 +1587,9 @@ namespace Ttcn { template_restriction_t template_restriction; /** normal or lazy evaluation parametrization should be used */ bool lazy_eval; + /** Flag that indicates whether the C++ code for the parameter's default + * value has been generated or not. */ + bool defval_generated; /// Copy constructor disabled FormalPar(const FormalPar& p); @@ -1642,7 +1644,11 @@ namespace Ttcn { * reporting. */ virtual void use_as_lvalue(const Location& p_loc); bool get_used_as_lvalue() const { return used_as_lvalue; } - /** Generates the C++ objects that represent the default value for the + /** Partially generates the C++ object that represents the default value for + * the parameter (if present). The object's declaration is not generated, + * only its value assignment. */ + char* generate_code_defval(char* str); + /** Generates the C++ object that represents the default value for the * parameter (if present). */ virtual void generate_code_defval(output_struct *target, bool clean_up = false); /** Generates the C++ equivalent of the formal parameter, appends it to @@ -1750,6 +1756,10 @@ namespace Ttcn { /** Generates the C++ equivalent of the formal parameter list, appends it * to \a str and returns the resulting string. */ char *generate_code(char *str); + /** Partially generates the C++ objects that represent the default value for + * the parameters (if present). The objects' declarations are not generated, + * only their value assignments. */ + char* generate_code_defval(char* str); /** Generates the C++ objects that represent the default values for the * parameters (if present). */ void generate_code_defval(output_struct *target); diff --git a/compiler2/ttcn3/TtcnTemplate.cc b/compiler2/ttcn3/TtcnTemplate.cc index 5342d34..2892efe 100644 --- a/compiler2/ttcn3/TtcnTemplate.cc +++ b/compiler2/ttcn3/TtcnTemplate.cc @@ -3002,7 +3002,7 @@ end: break; case TEMPLATE_INVOKE: if (get_code_section() == CS_POST_INIT) - str = rearrange_init_code_invoke(str); + str = rearrange_init_code_invoke(str, my_scope->get_scope_mod_gen()); str = generate_code_init_invoke(str, name); break; case TEMPLATE_LIST: @@ -3056,17 +3056,17 @@ end: return str; } - char *Template::rearrange_init_code(char *str) + char *Template::rearrange_init_code(char *str, Common::Module* usage_mod) { switch (templatetype) { case SPECIFIC_VALUE: str = u.specific_value->rearrange_init_code(str); break; case TEMPLATE_REFD: - str = rearrange_init_code_refd(str); + str = rearrange_init_code_refd(str, usage_mod); break; case TEMPLATE_INVOKE: - str = rearrange_init_code_invoke(str); + str = rearrange_init_code_invoke(str, usage_mod); break; case TEMPLATE_LIST: case VALUE_LIST: @@ -3075,17 +3075,17 @@ end: case SUBSET_MATCH: case PERMUTATION_MATCH: for (size_t i = 0; i < u.templates->get_nof_ts(); i++) - str = u.templates->get_t_byIndex(i)->rearrange_init_code(str); + str = u.templates->get_t_byIndex(i)->rearrange_init_code(str, usage_mod); break; case NAMED_TEMPLATE_LIST: for (size_t i = 0; i < u.named_templates->get_nof_nts(); i++) str = u.named_templates->get_nt_byIndex(i)->get_template() - ->rearrange_init_code(str); + ->rearrange_init_code(str, usage_mod); break; case INDEXED_TEMPLATE_LIST: for (size_t i = 0; i < u.indexed_templates->get_nof_its(); i++) str = u.indexed_templates->get_it_byIndex(i)->get_template() - ->rearrange_init_code(str); + ->rearrange_init_code(str, usage_mod); break; case VALUE_RANGE: str = u.value_range->rearrange_init_code(str); @@ -3147,17 +3147,15 @@ end: if (get_code_section() == CS_POST_INIT) { // the referencing template is a part of a non-parameterized template Common::Assignment *ass = u.ref.ref->get_refd_assignment(); - if (ass->get_asstype() == Common::Assignment::A_TEMPLATE && - ass->get_my_scope()->get_scope_mod_gen() == - my_scope->get_scope_mod_gen()) { + if (ass->get_asstype() == Common::Assignment::A_TEMPLATE) { // the reference points to (a field of) a template - // within the local module if (ass->get_FormalParList()) { // the referred template is parameterized // generate the initialization sequence first for all dependent // non-parameterized templates - str = rearrange_init_code_refd(str); - } else { + str = rearrange_init_code_refd(str, my_scope->get_scope_mod_gen()); + } else if (ass->get_my_scope()->get_scope_mod_gen() == + my_scope->get_scope_mod_gen()) { // the referred template is non-parameterized // use a different algorithm for code generation str = generate_rearrange_init_code_refd(str, &expr); @@ -4440,29 +4438,31 @@ compile_time: expr->expr = mputc(expr->expr, ')'); } - char *Template::rearrange_init_code_refd(char *str) + char *Template::rearrange_init_code_refd(char *str, Common::Module* usage_mod) { if (templatetype != TEMPLATE_REFD) FATAL_ERROR("Template::rearrange_init_code_refd()"); - ActualParList *parlist = u.ref.ref->get_parlist(); + ActualParList *actual_parlist = u.ref.ref->get_parlist(); // generate code for the templates that are used in the actual parameter // list of the reference Common::Assignment *ass = u.ref.ref->get_refd_assignment(); - bool rearrange = (ass->get_my_scope()->get_scope_mod_gen() == - my_scope->get_scope_mod_gen()); - if (parlist) str = parlist->rearrange_init_code(str, rearrange); + if (actual_parlist) str = actual_parlist->rearrange_init_code(str, usage_mod); // do nothing if the reference does not point to a template definition if (ass->get_asstype() != Common::Assignment::A_TEMPLATE) return str; - // do nothing if the referenced template is in another module - if (ass->get_my_scope()->get_scope_mod_gen() != - my_scope->get_scope_mod_gen()) return str; Template *t = ass->get_Template(); - if (parlist) { + FormalParList *formal_parlist = ass->get_FormalParList(); + if (formal_parlist) { // the reference points to a parameterized template // we must perform the rearrangement for all non-parameterized templates - // that are referred by the parameterized template regardless the + // that are referred by the parameterized template regardless of the // sub-references of u.ref.ref - str = t->rearrange_init_code(str); + str = t->rearrange_init_code(str, usage_mod); + // the parameterized template's default values must also be generated + // (this only generates their value assignments, their declarations will + // be generated when the template's definition is reached) + if (ass->get_my_scope()->get_scope_mod_gen() == usage_mod) { + str = formal_parlist->generate_code_defval(str); + } } else { // the reference points to a non-parameterized template FieldOrArrayRefs *subrefs = u.ref.ref->get_subrefs(); @@ -4494,17 +4494,17 @@ compile_time: } // otherwise if the reference points to a top-level template // we should initialize its entire body - str = t->generate_code_init(str, t->get_lhs_name().c_str()); + if (ass->get_my_scope()->get_scope_mod_gen() == usage_mod) { + str = t->generate_code_init(str, t->get_lhs_name().c_str()); + } } return str; } - char *Template::rearrange_init_code_invoke(char *str) + char *Template::rearrange_init_code_invoke(char *str, Common::Module* usage_mod) { str = u.invoke.v->rearrange_init_code(str); - bool type_is_local = u.invoke.v->get_expr_governor_last()->get_my_scope() - ->get_scope_mod_gen() == my_scope->get_scope_mod_gen(); - str = u.invoke.ap_list->rearrange_init_code(str, type_is_local); + str = u.invoke.ap_list->rearrange_init_code(str, usage_mod); return str; } @@ -5070,31 +5070,34 @@ compile_time: } else template_body->generate_code_expr(expr, template_restriction); } - char *TemplateInstance::rearrange_init_code(char *str) + char *TemplateInstance::rearrange_init_code(char *str, Common::Module* usage_mod) { if (derived_reference) { - ActualParList *parlist = derived_reference->get_parlist(); + ActualParList *actual_parlist = derived_reference->get_parlist(); Common::Assignment *ass = derived_reference->get_refd_assignment(); if (!ass) FATAL_ERROR("TemplateInstance::rearrange_init_code()"); - bool is_local = (ass->get_my_scope()->get_scope_mod_gen() == - derived_reference->get_my_scope()->get_scope_mod_gen()); - if (parlist) str = parlist->rearrange_init_code(str, is_local); - if (is_local && ass->get_asstype() == Common::Assignment::A_TEMPLATE) { - // the base template reference refers to a template within the local - // module + if (actual_parlist) str = actual_parlist->rearrange_init_code(str, usage_mod); + if (ass->get_asstype() == Common::Assignment::A_TEMPLATE) { Template *t = ass->get_Template(); - if (parlist) { + FormalParList *formal_parlist = ass->get_FormalParList(); + if (formal_parlist) { // the referred template is parameterized // the embedded referenced templates shall be visited - str = t->rearrange_init_code(str); + str = t->rearrange_init_code(str, usage_mod); + // the constants used for default values have to be initialized now + if (ass->get_my_scope()->get_scope_mod_gen() == usage_mod) { + str = formal_parlist->generate_code_defval(str); + } } else { // the referred template is not parameterized // its entire body has to be initialized now - str = t->generate_code_init(str, t->get_lhs_name().c_str()); + if (ass->get_my_scope()->get_scope_mod_gen() == usage_mod) { + str = t->generate_code_init(str, t->get_lhs_name().c_str()); + } } } } - str = template_body->rearrange_init_code(str); + str = template_body->rearrange_init_code(str, usage_mod); return str; } diff --git a/compiler2/ttcn3/TtcnTemplate.hh b/compiler2/ttcn3/TtcnTemplate.hh index 8925f8e..c3d3fa5 100644 --- a/compiler2/ttcn3/TtcnTemplate.hh +++ b/compiler2/ttcn3/TtcnTemplate.hh @@ -394,10 +394,10 @@ namespace Ttcn { char *generate_code_init(char *str, const char *name); /** Walks through the template recursively and appends the C++ * initialization sequence of all (directly or indirectly) - * referenced non-parameterized templates to \a str and returns - * the resulting string. Templates imported from other modules - * are not visited. */ - char *rearrange_init_code(char *str); + * referenced non-parameterized templates and the default values of all + * parameterized templates to \a str and returns the resulting string. + * Only objects belonging to module \a usage_mod are initialized. */ + char *rearrange_init_code(char *str, Common::Module* usage_mod); private: /** Private helper functions for code generation. */ @@ -461,8 +461,8 @@ namespace Ttcn { /** Helper function for \a rearrange_init_code(). It handles the * referenced templates (i.e. it does the real work). */ - char *rearrange_init_code_refd(char *str); - char *rearrange_init_code_invoke(char *str); + char *rearrange_init_code_refd(char *str, Common::Module* usage_mod); + char *rearrange_init_code_invoke(char *str, Common::Module* usage_mod); /** Returns whether the C++ initialization sequence requires a * temporary variable reference to be introduced for efficiency @@ -555,9 +555,9 @@ namespace Ttcn { void generate_code(expression_struct *expr, template_restriction_t template_restriction = TR_NONE); /** Appends the initialization sequence of the referred templates - * to \a str. Only those templates are considered that are in - * the same module as \a this. */ - char *rearrange_init_code(char *str); + * and their default values to \a str. Only templates from module + * \a usage_mod are considered. */ + char *rearrange_init_code(char *str, Common::Module* usage_mod); /** Appends the string representation of the template instance to * \a str. */ diff --git a/compiler2/ttcn3/compiler.y b/compiler2/ttcn3/compiler.y index e871992..65dca47 100644 --- a/compiler2/ttcn3/compiler.y +++ b/compiler2/ttcn3/compiler.y @@ -8670,6 +8670,10 @@ PredefOrIdentifier: $$ = new Identifier(Identifier::ID_TTCN, at_field); } +| NullValue + { + $$ = new Identifier(Identifier::ID_NAME, string("NULL")); + } IschosenArg: /* see also Reference... */ IDentifier '.' PredefOrIdentifier diff --git a/compiler2/ttcn3/rawAST.l b/compiler2/ttcn3/rawAST.l index e74a8f2..67bb5f5 100644 --- a/compiler2/ttcn3/rawAST.l +++ b/compiler2/ttcn3/rawAST.l @@ -285,6 +285,8 @@ BITORDERINOCTET { BEGIN(rawcodec); RETURN(XBitOrderInOctetKeyword); } HEXORDER { BEGIN(rawcodec); RETURN(XHexOrderKeyword); } TOPLEVEL { BEGIN(rawcodec); RETURN(XToplevelKeyword); } IntX { RETURN(XIntXKeyword); } +bit { RETURN(XBitKeyword); } +unsigned { RETURN(XUnsignedKeyword); } { yes { yylval.enumval = XDEFYES; RETURN(XYes); } @@ -331,10 +333,12 @@ TEXT_CODING { BEGIN(textcodec);RETURN(XCodingKeyword); } * when to return to INITIAL) */ /* First, the "starter" attributes */ +abstract RETURN(XKWabstract); anyAttributes RETURN(XKWanyAttributes); anyElement RETURN(XKWanyElement); attribute RETURN(XKWattribute); attributeFormQualified RETURN(XKWattributeFormQualified); +block RETURN(XKWblock); controlNamespace RETURN(XKWcontrolNamespace); defaultForEmpty RETURN(XKWdefaultForEmpty); element RETURN(XKWelement); diff --git a/compiler2/ttcn3/rawAST.y b/compiler2/ttcn3/rawAST.y index f210f48..dcc2c8b 100644 --- a/compiler2/ttcn3/rawAST.y +++ b/compiler2/ttcn3/rawAST.y @@ -152,6 +152,8 @@ static void yyprint(FILE *file, int type, const YYSTYPE& value); %token XToplevelKeyword %token XRepeatableKeyword %token XIntXKeyword +%token XBitKeyword +%token XUnsignedKeyword /* XER attributes */ %token XKWall "all" @@ -171,10 +173,12 @@ static void yyprint(FILE *file, int type, const YYSTYPE& value); %token XKWprefix "prefix" +%token XKWabstract "abstact" %token XKWanyAttributes "anyAttributes" %token XKWanyElement "anyElement" %token XKWattribute "attribute" %token XKWattributeFormQualified "attributeFormQualified" +%token XKWblock "block" %token XKWcontrolNamespace "controlNamespace" %token XKWdefaultForEmpty "defaultForEmpty" %token XKWelement "element" @@ -462,6 +466,8 @@ XSingleEncodingDef : XPaddingDef { rawstruct->topleveleind=1; raw_f=true;} | XIntXKeyword { rawstruct->intx = true; raw_f = true; } + | XBitDef + { raw_f = true; } /* TEXT encoder keywords */ | XBeginDef { text_f=true; } @@ -838,6 +844,22 @@ XRvalue: XIdentifier{ } ; +/* Alternative RAW attributes for types defined in annex E of the TTCN-3 standard */ +XBitDef: + XNumber XBitKeyword + { + rawstruct->fieldlength = $1; + rawstruct->comp = XDEFSIGNBIT; + rawstruct->byteorder = XDEFLAST; + } +| XUnsignedKeyword XNumber XBitKeyword + { + rawstruct->fieldlength = $2; + rawstruct->comp = XDEFUNSIGNED; + rawstruct->byteorder = XDEFLAST; + } +; + /* Text encoder */ XBeginDef: XBeginKeyword '(' XEncodeToken ')' { @@ -1265,10 +1287,12 @@ XERattributes: /* a non-empty list */ ; XERattribute: - anyAttributes { FreeNamespaceRestriction(xerstruct->anyAttributes_); xerstruct->anyAttributes_ = $1; } + XKWabstract { xerstruct->abstract_ = true; } + | anyAttributes { FreeNamespaceRestriction(xerstruct->anyAttributes_); xerstruct->anyAttributes_ = $1; } | anyElement { FreeNamespaceRestriction(xerstruct->anyElement_); xerstruct->anyElement_ = $1; } | XKWattribute { xerstruct->attribute_ = true; } | XKWattributeFormQualified { xerstruct->form_ |= XerAttributes::ATTRIBUTE_DEFAULT_QUALIFIED; } + | XKWblock { xerstruct->block_ = true; } | controlNamespace /* directly on the module */ { mymod->set_controlns($1.uri, $1.prefix); diff --git a/compiler2/union.c b/compiler2/union.c index 1e75686..b2fc12e 100644 --- a/compiler2/union.c +++ b/compiler2/union.c @@ -1378,9 +1378,8 @@ void defUnionClass(struct_def const *sdef, output_struct *output) src = mputstr(src, " const boolean e_xer = is_exer(p_flavor);\n" " char *type_atr = NULL;\n" - " unsigned short name_len = 0;\n" " if (e_xer && (p_td.xer_bits & USE_TYPE_ATTR)) {\n" - " const char *type_name = 0;\n" + " char *type_name = 0;\n" " const namespace_t *control_ns;\n" " switch (union_selection) {\n"); /* In case of USE-TYPE the first field won't need the type attribute */ @@ -1388,24 +1387,34 @@ void defUnionClass(struct_def const *sdef, output_struct *output) for (i = start_at; i < sdef->nElements; i++) { src = mputprintf(src, " case %s_%s:\n" - " type_name = %s_xer_.names[1];\n" - " name_len = %s_xer_.namelens[1] - 2;\n" + " if (%s_xer_.my_module != 0 && %s_xer_.ns_index != -1 &&\n" + " %s_xer_.namelens[1] > 2) {\n" + /* add the namespace prefix to the type attribute (if the name is not empty) */ + " const namespace_t *my_ns = %s_xer_.my_module->get_ns(%s_xer_.ns_index);\n" + " if (my_ns->px[0] != 0) {\n" + " type_name = mprintf(\"%%s:\", my_ns->px);\n" + " }\n" + " }\n" + " type_name = mputstrn(type_name, %s_xer_.names[1], %s_xer_.namelens[1] - 2);\n" " %s\n" , selection_prefix, sdef->elements[i].name - , sdef->elements[i].typegen + , sdef->elements[i].typegen, sdef->elements[i].typegen + , sdef->elements[i].typegen, sdef->elements[i].typegen + , sdef->elements[i].typegen, sdef->elements[i].typegen , sdef->elements[i].typegen , i < sdef->nElements - 1 ? "goto write_atr;" : "" /* no break */ ); } src = mputprintf(src, "%s" /* label only if more than two elements total */ - " if (name_len > 0) {\n" /* 38.3.8, no atr if NAME AS "" */ + " if (mstrlen(type_name) > 0) {\n" /* 38.3.8, no atr if NAME AS "" */ " control_ns = p_td.my_module->get_controlns();\n" " type_atr = mcopystr(\" \");\n" - " type_atr = mputstr (type_atr, control_ns->px);\n" - " type_atr = mputstr (type_atr, \":type='\");\n" - " type_atr = mputstrn(type_atr, type_name, name_len);\n" - " type_atr = mputc (type_atr, '\\'');\n" + " type_atr = mputstr(type_atr, control_ns->px);\n" + " type_atr = mputstr(type_atr, \":type='\");\n" + " type_atr = mputstr(type_atr, type_name);\n" + " type_atr = mputc (type_atr, '\\'');\n" + " Free(type_name);\n" " }\n" " break;\n" " default: break;\n" @@ -1475,33 +1484,42 @@ void defUnionClass(struct_def const *sdef, output_struct *output) src = mputstr(src, " const boolean e_xer = is_exer(p_flavor);\n" " char *type_atr = NULL;\n" - " unsigned short name_len = 0;\n" " if (e_xer && (p_td.xer_bits & USE_TYPE_ATTR)) {\n" - " const char *type_name = 0;\n" + " char *type_name = 0;\n" " const namespace_t *control_ns;\n" " switch (union_selection) {\n"); int start_at = sdef->xerUseUnion ? 0 : 1; for (i = start_at; i < sdef->nElements; i++) { src = mputprintf(src, " case %s_%s:\n" - " type_name = %s_xer_.names[1];\n" - " name_len = %s_xer_.namelens[1] - 2;\n" + " if (%s_xer_.my_module != 0 && %s_xer_.ns_index != -1 &&\n" + " %s_xer_.namelens[1] > 2) {\n" + /* add the namespace prefix to the type attribute (if the name is not empty) */ + " const namespace_t *my_ns = %s_xer_.my_module->get_ns(%s_xer_.ns_index);\n" + " if (my_ns->px[0] != 0) {\n" + " type_name = mprintf(\"%%s:\", my_ns->px);\n" + " }\n" + " }\n" + " type_name = mputstrn(type_name, %s_xer_.names[1], %s_xer_.namelens[1] - 2);\n" " %s\n" , selection_prefix, sdef->elements[i].name - , sdef->elements[i].typegen + , sdef->elements[i].typegen, sdef->elements[i].typegen + , sdef->elements[i].typegen, sdef->elements[i].typegen + , sdef->elements[i].typegen, sdef->elements[i].typegen , sdef->elements[i].typegen , i < sdef->nElements - 1 ? "goto write_atr;" : "" /* no break */ ); } src = mputprintf(src, "%s" /* label only if more than two elements total */ - " if (name_len > 0) {\n" /* 38.3.8, no atr if NAME AS "" */ + " if (mstrlen(type_name) > 0) {\n" /* 38.3.8, no atr if NAME AS "" */ " control_ns = p_td.my_module->get_controlns();\n" " type_atr = mcopystr(\" \");\n" - " type_atr = mputstr (type_atr, control_ns->px);\n" - " type_atr = mputstr (type_atr, \":type='\");\n" - " type_atr = mputstrn(type_atr, type_name, name_len);\n" - " type_atr = mputc (type_atr, '\\'');\n" + " type_atr = mputstr(type_atr, control_ns->px);\n" + " type_atr = mputstr(type_atr, \":type='\");\n" + " type_atr = mputstr(type_atr, type_name);\n" + " type_atr = mputc (type_atr, '\\'');\n" + " Free(type_name);\n" " }\n" " break;\n" " default: break;\n" @@ -1628,8 +1646,7 @@ void defUnionClass(struct_def const *sdef, output_struct *output) /* USE-TYPE: No type attribute means the first alternative */ src = mputprintf(src, " if (typeatr == NULL) {\n" - " typeatr = mcopystr(%s_xer_.names[1]);\n" - " typeatr = mtruncstr(typeatr, %s_xer_.namelens[1] - 2);\n" + " typeatr = mcopystrn(%s_xer_.names[1], %s_xer_.namelens[1] - 2);\n" " }\n" , sdef->elements[0].typegen , sdef->elements[0].typegen); @@ -1668,7 +1685,15 @@ void defUnionClass(struct_def const *sdef, output_struct *output) if (sdef->xerUseTypeAttr) { src = mputstr(src, " if (e_xer) {\n" /* USE-TYPE => no XML element, use typeatr */ - " elem_name = typeatr;\n" + " char *token_1 = strtok(typeatr, \":\");\n" /* extract the namespace (if any) */ + " char *token_2 = strtok(NULL, \":\");\n" + " if (token_2) {\n" /* namespace found */ + " elem_name = token_2;\n" + " ns_uri = get_ns_uri_from_prefix(token_1, p_td);\n" + " }\n" + " else {\n" /* no namespace */ + " elem_name = token_1;\n" + " }\n" " flavor_1 |= USE_TYPE_ATTR;\n" " }\n" " else" /* no newline, gobbles up the next {} */); @@ -1748,6 +1773,10 @@ void defUnionClass(struct_def const *sdef, output_struct *output) src = mputprintf(src, " %sif (%s::can_start(elem_name, ns_uri, %s_xer_, flavor_1) || (%s_xer_.xer_bits & ANY_ELEMENT)) {\n" " ec_2.set_msg(\"%s': \");\n" + " if (e_xer && (%s_xer_.xer_bits & BLOCKED)) {\n" + " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n" + " \"Attempting to decode blocked or abstract field.\");\n" + " }\n" " %s%s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n" " if (!%s%s().is_bound()) {\n" " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, \"Failed to decode field.\");\n" @@ -1756,6 +1785,7 @@ void defUnionClass(struct_def const *sdef, output_struct *output) i && !(i==1 && sdef->exerMaybeEmptyIndex==0) ? "else " : "", /* print "if(" if generate code for the first field or if the first field is the MaybeEmpty field and we generate the code for the second one*/ sdef->elements[i].type, sdef->elements[i].typegen, sdef->elements[i].typegen, sdef->elements[i].dispname, + sdef->elements[i].typegen, at_field, sdef->elements[i].name, sdef->elements[i].typegen, at_field, sdef->elements[i].name); } @@ -1765,6 +1795,10 @@ void defUnionClass(struct_def const *sdef, output_struct *output) src = mputprintf(src, " %sif ((e_xer && (type==XML_READER_TYPE_END_ELEMENT || !own_tag)) || %s::can_start(elem_name, ns_uri, %s_xer_, flavor_1) || (%s_xer_.xer_bits & ANY_ELEMENT)) {\n" "empty_xml: ec_2.set_msg(\"%s': \");\n" + " if (e_xer && (%s_xer_.xer_bits & BLOCKED)) {\n" + " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n" + " \"Attempting to decode blocked or abstract field.\");\n" + " }\n" " %s%s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n" " if (!%s%s().is_bound()) {\n" " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, \"Failed to decode field.\");\n" @@ -1773,6 +1807,7 @@ void defUnionClass(struct_def const *sdef, output_struct *output) sdef->nElements>0 ? "else " : "", sdef->elements[i].type, sdef->elements[i].typegen, sdef->elements[i].typegen, sdef->elements[i].dispname, + sdef->elements[i].typegen, at_field, sdef->elements[i].name, sdef->elements[i].typegen, at_field, sdef->elements[i].name); } diff --git a/core/Boolean.cc b/core/Boolean.cc index 179643c..5dd0ca3 100644 --- a/core/Boolean.cc +++ b/core/Boolean.cc @@ -530,6 +530,10 @@ int BOOLEAN::RAW_encode(const TTCN_Typedescriptor_t& p_td, RAW_enc_tree& myleaf) else bc = myleaf.body.leaf.data_array; memset(bc, tmp, length * sizeof(*bc)); + if (boolean_value && loc_length % 8 != 0) { + // remove the extra ones from the last octet + bc[length - 1] &= BitMaskTable[loc_length % 8]; + } return myleaf.length = loc_length; } diff --git a/core/Integer.cc b/core/Integer.cc index 4d1100f..c209315 100644 --- a/core/Integer.cc +++ b/core/Integer.cc @@ -121,6 +121,7 @@ INTEGER::INTEGER(BIGNUM *other_value) INTEGER::~INTEGER() { + if (!bound_flag) return; if (unlikely(!native_flag)) BN_free(val.openssl); } diff --git a/core/Makefile b/core/Makefile index 3b3cde4..75f3f3f 100644 --- a/core/Makefile +++ b/core/Makefile @@ -181,7 +181,9 @@ SHAREDLIB := libttcn3$(RT2_SUFFIX)-dynamic.so PARALLEL_SHAREDLIB := libttcn3$(RT2_SUFFIX)-parallel-dynamic.so # Executables +ifneq ($(FUNCTION_TEST_RUNTIME), yes) PROGRAMS := ttcn3_profmerge$(EXESUFFIX) +endif TARGETS := $(LIBRARY) $(PARALLEL_LIBRARY) diff --git a/core/Runtime.cc b/core/Runtime.cc index 527bf66..06cd97c 100644 --- a/core/Runtime.cc +++ b/core/Runtime.cc @@ -278,7 +278,7 @@ CHARSTRING TTCN_Runtime::get_testcase_id_macro() CHARSTRING TTCN_Runtime::get_testcasename() { - if (in_controlpart()) return CHARSTRING(""); // No error here. + if (in_controlpart() || is_hc()) return CHARSTRING(""); // No error here. if (!testcase_name.definition_name || testcase_name.definition_name[0] == 0) TTCN_error("Internal error: Evaluating predefined function testcasename()" @@ -2459,8 +2459,11 @@ void TTCN_Runtime::process_ptc_verdict(Text_Buf& text_buf) TTCN_error("Internal error: Invalid PTC verdict was " "received from MC: %d.", ptc_verdict); } - verdicttype new_verdict = - local_verdict < ptc_verdict ? ptc_verdict : local_verdict; + verdicttype new_verdict = local_verdict; + if (ptc_verdict > local_verdict) { + new_verdict = ptc_verdict; + verdict_reason = CHARSTRING(ptc_verdict_reason); + } TTCN_Logger::log_final_verdict(true, ptc_verdict, local_verdict, new_verdict, ptc_verdict_reason, -1, ptc_compref, ptc_name); delete [] ptc_name; diff --git a/core/XER.cc b/core/XER.cc index 03259a0..d24d42b 100644 --- a/core/XER.cc +++ b/core/XER.cc @@ -129,6 +129,19 @@ void write_ns_prefix(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf) } } +const char* get_ns_uri_from_prefix(const char *prefix, const XERdescriptor_t& p_td) +{ + if (p_td.my_module != 0 && prefix != NULL && prefix[0] != 0) { + for (size_t i = 0; i < p_td.my_module->get_num_ns(); ++i) { + const namespace_t *ns = p_td.my_module->get_ns(i); + if (ns->px != NULL && strcmp(ns->px, prefix) == 0) { + return ns->ns; + } + } + } + return NULL; +} + void check_namespace_restrictions(const XERdescriptor_t& p_td, const char* p_xmlns) { // In case of "anyElement from ..." matching namespaces is good diff --git a/core/XER.hh b/core/XER.hh index 181f6af..6978498 100644 --- a/core/XER.hh +++ b/core/XER.hh @@ -89,8 +89,10 @@ enum XER_flavor { as empty elements in BXER only. This also influences them in record-of */ ANY_FROM = 1U << 27, // 0x8000000 anyElement from ... or anyAttributes from ... ANY_EXCEPT = 1U << 28, // 0x10000000 anyElement except ... or anyAttributes except ... - EXIT_ON_ERROR = 1U << 29 /* 0x20000000 clean up and exit instead of throwing + EXIT_ON_ERROR = 1U << 29, /* 0x20000000 clean up and exit instead of throwing a decoding error, used on alternatives of a union with USE-UNION */ + XER_OPTIONAL = 1U << 30, // 0x40000000 is an optional field of a record or set + BLOCKED = 1U << 31 // 0x80000000 either ABSTRACT or BLOCK }; /** WHITESPACE actions. @@ -375,6 +377,16 @@ class TTCN_Buffer; */ void write_ns_prefix(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf); +/** Return the namespace referred to by a prefix + * + * Finds the namespace specified by \a prefix in the module's namespace table + * and returns its URI. Returns NULL if the namespace is not found. + * + * @param prefix namespace prefix to be found + * @param p_td XER descriptor (contains the module to search in) + */ +const char* get_ns_uri_from_prefix(const char *prefix, const XERdescriptor_t& p_td); + /** Output the beginning of an XML attribute. * * Writes a space, the attribute name (from \p p_td), and the string "='". diff --git a/core2/Basetype2.cc b/core2/Basetype2.cc index 41a165d..2bffe70 100644 --- a/core2/Basetype2.cc +++ b/core2/Basetype2.cc @@ -2270,6 +2270,10 @@ int Record_Of_Type::XER_decode(const XERdescriptor_t& p_td, } /* next read */ } /* if not empty element */ } /* if not LIST */ + if (!own_tag && exer && (p_td.xer_bits & XER_OPTIONAL) && get_nof_elements() == 0) { + // set it to unbound, so the OPTIONAL class sets it to omit + clean_up(); + } return 1; // decode successful } diff --git a/function_test/Semantic_Analyser/Makefile.semantic b/function_test/Semantic_Analyser/Makefile.semantic index 28a394d..c772783 100644 --- a/function_test/Semantic_Analyser/Makefile.semantic +++ b/function_test/Semantic_Analyser/Makefile.semantic @@ -5,7 +5,7 @@ # which accompanies this distribution, and is available at # http://www.eclipse.org/legal/epl-v10.html ############################################################################### -SADIRS := ver xer encode param template_restrictions +SADIRS := ver xer encode param template #$(wildcard TTCN3_[a0-9]* ASN_[a0-9]*) ver xer all run check clean distclean: diff --git a/function_test/Semantic_Analyser/TTCN3_SA_6_TD.script b/function_test/Semantic_Analyser/TTCN3_SA_6_TD.script index ac36eca..8cd7148 100644 --- a/function_test/Semantic_Analyser/TTCN3_SA_6_TD.script +++ b/function_test/Semantic_Analyser/TTCN3_SA_6_TD.script @@ -4032,7 +4032,7 @@ type charstring myCharType length( float2int(rnd()) ); } -(?im)error.+?evaluatable.+?constant.+?value.+?expected.+?instead.+?of.+?operation +(?im)error.+?evaluable.+?constant.+?value.+?expected.+?instead.+?of.+?operation (?im)\bNotify\b.+?\bcode\b.+?\bnot\b.+?\bgenerated\b @@ -4094,7 +4094,7 @@ type charstring myCharType length( float2int(rnd()) .. 5 ); } -(?im)error.+?evaluatable.+?constant.+?value.+?expected.+?instead.+?of.+?operation +(?im)error.+?evaluable.+?constant.+?value.+?expected.+?instead.+?of.+?operation (?im)\bNotify\b.+?\bcode\b.+?\bnot\b.+?\bgenerated\b @@ -4160,7 +4160,7 @@ type charstring myCharType length( float2int(rnd()) .. myFunct()); } -(?im)error.+?evaluatable.+?constant.+?value.+?expected.+?instead.+?of.+?operation +(?im)error.+?evaluable.+?constant.+?value.+?expected.+?instead.+?of.+?operation (?im)error.+?Reference.+?constant.+?expected.+?instead @@ -4192,7 +4192,7 @@ type integer myIntType ( float2int(rnd()) .. 255 ); } -(?im)error.+?evaluatable.+?constant.+?value.+?expected.+?instead.+?of.+?operation +(?im)error.+?evaluable.+?constant.+?value.+?expected.+?instead.+?of.+?operation (?im)\bNotify\b.+?\bcode\b.+?\bnot\b.+?\bgenerated\b @@ -4258,7 +4258,7 @@ type float myIntType ( rnd() .. myFunct() ); } -(?im)error.+?evaluatable.+?constant.+?value.+?expected.+?instead.+?of.+?operation +(?im)error.+?evaluable.+?constant.+?value.+?expected.+?instead.+?of.+?operation (?im)error.+?Reference.+?constant.+?expected.+?instead @@ -4290,7 +4290,7 @@ type integer myIntType ( float2int(rnd()), 255 ); } -(?im)error.+?evaluatable.+?constant.+?value.+?expected.+?instead.+?of.+?operation +(?im)error.+?evaluable.+?constant.+?value.+?expected.+?instead.+?of.+?operation (?im)\bNotify\b.+?\bcode\b.+?\bnot\b.+?\bgenerated\b @@ -4356,7 +4356,7 @@ type float myIntType ( rnd(), 255.0, myFunct() ); } -(?im)error.+?evaluatable.+?constant.+?value.+?expected.+?instead.+?of.+?operation +(?im)error.+?evaluable.+?constant.+?value.+?expected.+?instead.+?of.+?operation (?im)error.+?Reference.+?constant.+?expected.+?instead @@ -6900,7 +6900,7 @@ module x { } -(?im)error.+?evaluatable.+?constant.+?value.+?expected.+?instead.+?of.+?operation +(?im)error.+?evaluable.+?constant.+?value.+?expected.+?instead.+?of.+?operation (?is)\berror: diff --git a/function_test/Semantic_Analyser/template_restrictions/.gitignore b/function_test/Semantic_Analyser/template/.gitignore similarity index 100% rename from function_test/Semantic_Analyser/template_restrictions/.gitignore rename to function_test/Semantic_Analyser/template/.gitignore diff --git a/function_test/Semantic_Analyser/template_restrictions/Makefile b/function_test/Semantic_Analyser/template/Makefile similarity index 100% rename from function_test/Semantic_Analyser/template_restrictions/Makefile rename to function_test/Semantic_Analyser/template/Makefile diff --git a/function_test/Semantic_Analyser/template/TempOmit_SE.ttcn b/function_test/Semantic_Analyser/template/TempOmit_SE.ttcn new file mode 100644 index 0000000..64cc391 --- /dev/null +++ b/function_test/Semantic_Analyser/template/TempOmit_SE.ttcn @@ -0,0 +1,16 @@ +/****************************************************************************** + * 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 TempOmit_SE { //^In TTCN-3 module// + +template integer t1 := (1 ifpresent, 2 ifpresent); //^In template definition// //^In list item//2 //error: `ifpresent' is not allowed here//2 +template integer t2 := complement (1 ifpresent, 2 ifpresent); //^In template definition// //^In list item//2 //error: `ifpresent' is not allowed here//2 + +template integer t3 := (1, 2, 3, omit); //^In template definition// //^In list item// //error: `omit' value is not allowed in this context// +template integer t4 := complement (3, 2, omit); //^In template definition// //^In list item// //error: `omit' value is not allowed in this context// + +} diff --git a/function_test/Semantic_Analyser/template_restrictions/TempRes_SE.ttcn b/function_test/Semantic_Analyser/template/TempRes_SE.ttcn similarity index 100% rename from function_test/Semantic_Analyser/template_restrictions/TempRes_SE.ttcn rename to function_test/Semantic_Analyser/template/TempRes_SE.ttcn diff --git a/function_test/Semantic_Analyser/template_restrictions/t b/function_test/Semantic_Analyser/template/t similarity index 100% rename from function_test/Semantic_Analyser/template_restrictions/t rename to function_test/Semantic_Analyser/template/t diff --git a/regression_test/RAW/Annex_E_variants/Annex_E_variants.cfg b/regression_test/RAW/Annex_E_variants/Annex_E_variants.cfg new file mode 100644 index 0000000..e778a48 --- /dev/null +++ b/regression_test/RAW/Annex_E_variants/Annex_E_variants.cfg @@ -0,0 +1,14 @@ +############################################################################### +# 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 +############################################################################### +[LOGGING] +LogFile := "Annex_E_variants.log" +FileMask := LOG_ALL +ConsoleMask := TTCN_ERROR | TTCN_TESTCASE | TTCN_STATISTICS +LogSourceInfo := Yes +[EXECUTE] +Annex_E_variants.control diff --git a/regression_test/RAW/Annex_E_variants/Annex_E_variants.ttcn b/regression_test/RAW/Annex_E_variants/Annex_E_variants.ttcn new file mode 100644 index 0000000..7ef4a45 --- /dev/null +++ b/regression_test/RAW/Annex_E_variants/Annex_E_variants.ttcn @@ -0,0 +1,514 @@ +/****************************************************************************** + * 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 tests for the variant attributes defined in Annex E of the +// TTCN-3 language standard. +// The encoding of the types with the new variants are compared to the encoding of +// types declared using traditional RAW variant attributes. + +// New attributes and their equivalents: +// "N bit" == "FIELDLENGTH(N), COMP(signbit), BYTEORDER(last)" +// "unsigned N bit" == "FIELDLENGTH(N), COMP(nosign), BYTEORDER(last)" +module Annex_E_variants { + +// E.2.1.0 Signed and unsigned single byte integers +type integer Byte (-128 .. 127) with { variant "8 bit" }; +type integer ByteEq (-128 .. 127) with { variant "FIELDLENGTH(8), COMP(signbit), BYTEORDER(last)" }; + +type integer UnsignedByte (0 .. 255) with { variant "unsigned 8 bit" }; +type integer UnsignedByteEq (0 .. 255) with { variant "FIELDLENGTH(8), COMP(nosign), BYTEORDER(last)" }; + +// E.2.1.1 Signed and unsigned short integers +type integer Short (-32768 .. 32767) with { variant "16 bit" }; +type integer ShortEq (-32768 .. 32767) with { variant "FIELDLENGTH(16), COMP(signbit), BYTEORDER(last)" }; + +type integer UnsignedShort (0 .. 65535) with { variant "unsigned 16 bit" }; +type integer UnsignedShortEq (0 .. 65535) with { variant "FIELDLENGTH(16), COMP(nosign), BYTEORDER(last)" }; + +// E.2.1.2 Signed and unsigned long integers +type integer Long (-2147483648 .. 2147483647) with { variant "32 bit" }; +type integer LongEq (-2147483648 .. 2147483647) with { variant "FIELDLENGTH(32), COMP(signbit), BYTEORDER(last)" }; + +type integer UnsignedLong (0 .. 4294967295) with { variant "unsigned 32 bit" }; +type integer UnsignedLongEq (0 .. 4294967295) with { variant "FIELDLENGTH(32), COMP(nosign), BYTEORDER(last)" }; + +// E.2.1.3 Signed and unsigned longlong integers +type integer LongLong (-9223372036854775808 .. 9223372036854775807) with { variant "64 bit" }; +type integer LongLongEq (-9223372036854775808 .. 9223372036854775807) with { variant "FIELDLENGTH(64), COMP(signbit), BYTEORDER(last)" }; + +type integer UnsignedLongLong (0 .. 18446744073709551615) with { variant "unsigned 64 bit" }; +type integer UnsignedLongLongEq (0 .. 18446744073709551615) with { variant "FIELDLENGTH(64), COMP(nosign), BYTEORDER(last)" }; + +// Custom integer types +type integer Int6 with { variant "6 bit" }; +type integer Int6Eq with { variant "FIELDLENGTH(6), COMP(signbit), BYTEORDER(last)" }; + +type integer UInt4 with { variant "unsigned 4 bit" }; +type integer UInt4Eq with { variant "FIELDLENGTH(4), COMP(nosign), BYTEORDER(last)" }; + +type integer BigInt with { variant "300 bit " }; +type integer BigIntEq with { variant "FIELDLENGTH(300), COMP(signbit), BYTEORDER(last)" }; + +// Using the "N bit" attribute on enumerated types +type enumerated Enum5 { val1(1), val7(7), val2(2), val11(11) } with { variant "unsigned 5 bit" }; +type enumerated Enum5Eq { val1(1), val7(7), val2(2), val11(11) } with { variant "FIELDLENGTH(5), COMP(nosign), BYTEORDER(last)" }; + +type enumerated Enum12 { val30(30), valm10(-10), val9(9) } with { variant "12 bit" }; +type enumerated Enum12Eq { val30(30), valm10(-10), val9(9) } with { variant "FIELDLENGTH(12), COMP(signbit), BYTEORDER(last)" }; + +// Using the "N bit" attribute on boolean types +type boolean Bool3 with { variant "3 bit" }; +type boolean Bool3Eq with { variant "FIELDLENGTH(3), BYTEORDER(last)" }; + +type boolean Bool13 with { variant "13 bit" }; +type boolean Bool13Eq with { variant "FIELDLENGTH(13), BYTEORDER(last)" }; + +// Using the "N bit" attribute on string types +type bitstring BStr14 with { variant "14 bit" }; +type bitstring BStr14Eq with { variant "FIELDLENGTH(14), BYTEORDER(last)" }; + +type hexstring HStr20 with { variant "unsigned 20 bit" }; // 20 bits = 5 hex nibbles, 'unsigned' is ignored +type hexstring HStr20Eq with { variant "FIELDLENGTH(5), BYTEORDER(last)" }; + +type octetstring OStr32 with { variant "32 bit" }; // 32 bits = 4 octets +type octetstring OStr32Eq with { variant "FIELDLENGTH(4), BYTEORDER(last)" }; + +type charstring CStr64 with { variant "64 bit" }; // 64 bits = 8 characters +type charstring CStr64Eq with { variant "FIELDLENGTH(8), BYTEORDER(last)" }; + +// Component type +type component CT {} + +// Test cases +testcase tc_byte() runs on CT +{ + var Byte x := -12; + var ByteEq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var Byte dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_unsigned_byte() runs on CT +{ + var UnsignedByte x := 91; + var UnsignedByteEq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var UnsignedByte dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_short() runs on CT +{ + var Short x := 399; + var ShortEq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var Short dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_unsigned_short() runs on CT +{ + var UnsignedShort x := 399; + var UnsignedShortEq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var UnsignedShort dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_long() runs on CT +{ + var Long x := 1457664; + var LongEq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var Long dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_unsigned_long() runs on CT +{ + var UnsignedLong x := 1457664; + var UnsignedLongEq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var UnsignedLong dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_long_long() runs on CT +{ + var LongLong x := -9223372036854775807; + var LongLongEq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var LongLong dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_unsigned_long_long() runs on CT +{ + var UnsignedLongLong x := 18446744073709551610; + var UnsignedLongLongEq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var UnsignedLongLong dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_int6() runs on CT +{ + var Int6 x := -19; + var Int6Eq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var Int6 dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_uint4() runs on CT +{ + var UInt4 x := 7; + var UInt4Eq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var UInt4 dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_big_int() runs on CT +{ + var BigInt x := -2837219487639565876438796348973264327463294623463287046324783264987325432; + var BigIntEq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var BigInt dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_enum5() runs on CT +{ + var Enum5 x := val11; + var Enum5Eq x_eq := val11; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var Enum5 dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_enum12() runs on CT +{ + var Enum12 x := valm10; + var Enum12Eq x_eq := valm10; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var Enum12 dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_bool3() runs on CT +{ + var Bool3 x := true; + var Bool3Eq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var Bool3 dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_bool13() runs on CT +{ + var Bool13 x := true; + var Bool13Eq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var Bool13 dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_bstr14() runs on CT +{ + var BStr14 x := '10101010101010'B; + var BStr14Eq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var BStr14 dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_hstr20() runs on CT +{ + var HStr20 x := 'CCCCC'H; + var HStr20Eq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var HStr20 dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_ostr32() runs on CT +{ + var OStr32 x := 'ABABABAB'O; + var OStr32Eq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var OStr32 dec; + if (decvalue(enc, dec) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != x) { + setverdict(fail, "Expected: ", x, ", got: ", dec); + } + } + setverdict(pass); +} + +testcase tc_cstr64() runs on CT +{ + var CStr64 x := "Hello"; + var CStr64Eq x_eq := x; + var bitstring enc := encvalue(x); + var bitstring enc_exp := encvalue(x_eq); + if (enc != enc_exp) { + setverdict(fail, "Expected: ", enc_exp, ", got: ", enc); + } + else { + var CStr64 dec; + var CStr64Eq dec_exp; + if (decvalue(enc, dec) != 0 or decvalue(enc_exp, dec_exp) != 0) { + setverdict(fail, "Could not decode ", enc); + } + else if (dec != dec_exp) { + setverdict(fail, "Expected: ", dec_exp, ", got: ", dec); + } + } + setverdict(pass); +} + +// Control part +control { + execute(tc_byte()); + execute(tc_unsigned_byte()); + execute(tc_short()); + execute(tc_unsigned_short()); + execute(tc_long()); + execute(tc_unsigned_long()); + execute(tc_long_long()); + execute(tc_unsigned_long_long()); + execute(tc_int6()); + execute(tc_uint4()); + execute(tc_big_int()); + execute(tc_enum5()); + execute(tc_enum12()); + execute(tc_bool3()); + execute(tc_bool13()); + execute(tc_bstr14()); + execute(tc_hstr20()); + execute(tc_ostr32()); + execute(tc_cstr64()); +} + +} +with { + encode "RAW"; +} diff --git a/regression_test/RAW/Annex_E_variants/Makefile b/regression_test/RAW/Annex_E_variants/Makefile new file mode 100644 index 0000000..f590c44 --- /dev/null +++ b/regression_test/RAW/Annex_E_variants/Makefile @@ -0,0 +1,54 @@ +############################################################################### +# 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 run + +TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX) + +TTCN3_MODULES = Annex_E_variants.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 + +USER_SOURCES = + +# All object files needed for the executable test suite: +OBJECTS = $(GENERATED_SOURCES:.cc=.o) $(USER_SOURCES:.cc=.o) + +# The name of the executable test suite: +TARGET = Annex_E_variants$(EXESUFFIX) + +all: $(TARGET) ; + +$(TARGET): $(OBJECTS) + $(CXX) $(LDFLAGS) -o $@ $(OBJECTS) -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) $(ASN1_MODULES) + $(TTCN3_COMPILER) $(COMPILER_FLAGS) $^ + touch $@ + +clean distclean: + $(RM) $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \ + $(GENERATED_SOURCES) compile *.log + +dep: $(GENERATED_SOURCES) + makedepend $(CPPFLAGS) $(USER_SOURCES) $(GENERATED_SOURCES) + +run: $(TARGET) Annex_E_variants.cfg + ./$^ + +# DO NOT DELETE diff --git a/regression_test/XML/AbstractBlock/AbstractBlock.ttcn b/regression_test/XML/AbstractBlock/AbstractBlock.ttcn new file mode 100644 index 0000000..9e1c921 --- /dev/null +++ b/regression_test/XML/AbstractBlock/AbstractBlock.ttcn @@ -0,0 +1,240 @@ +/****************************************************************************** + * 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 AbstractBlock { + +// This module contains tests for the ABSTRACT and BLOCK encoding instructions, +// which are generally used in code generated from element substitutions and type +// substitutions in XSD. + +type component CT {} + +/******* Test 1: Element substitution example *******/ +type charstring Member1 +with { + variant "name as uncapitalized"; + variant "element"; +} + +type enumerated Member2 +{ + else_, + something +} +with { + variant "text 'else_' as 'else'"; + variant "name as uncapitalized"; + variant "element"; +} + +type record Member3 +{ + integer bar optional, + float foo optional, + charstring base +} +with { + variant "name as uncapitalized"; + variant "element"; + variant(bar) "attribute"; + variant(foo) "attribute"; + variant(base) "untagged"; +} + +type union Head_group +{ + charstring head, + Member1 member1, + Member2 member2, + Member3 member3 +} +with { + variant "untagged"; + variant(head) "abstract"; + variant(member3) "block"; +} + +type record of Head_group Data +with { + variant "name as uncapitalized"; +} + +external function f_enc_data(in Data x) return octetstring + with { extension "prototype(convert) encode(XER:XER_EXTENDED)" }; + +external function f_dec_data(in octetstring x) return Data + with { extension "prototype(convert) decode(XER:XER_EXTENDED)" }; + +testcase tc_element_substitution() runs on CT +{ + // non-blocked and non-abstract fields should be encoded and decoded normally + var Data v_data := { { member1 := "xy" }, { member2 := else_ } }; + var octetstring v_exp_enc := char2oct( + "\n" & + "\txy\n" & + "\telse\n" & + "\n\n"); + + var octetstring v_enc := f_enc_data(v_data); + if (v_enc != v_exp_enc) { + setverdict(fail, "Expected: ", v_exp_enc, ", got: ", v_enc); + } + var Data v_dec := f_dec_data(v_exp_enc); + if (v_dec != v_data) { + setverdict(fail, "Expected: ", v_data, ", got: ", v_dec); + } + + // abstract and blocked fields are encoded as before, but cause an error while decoding + v_data := { { head := "abc" } }; + v_exp_enc := char2oct( + "\n" & + "\tabc\n" & + "\n\n"); + + v_enc := f_enc_data(v_data); + if (v_enc != v_exp_enc) { + setverdict(fail, "Expected: ", v_exp_enc, ", got: ", v_enc); + } + + @try { + v_dec := f_dec_data(v_exp_enc); + setverdict(fail, "Error expected while decoding ", v_exp_enc); + } + @catch (msg) { + if (not match(msg, pattern "*Index 0: Alternative 'head': Attempting to decode blocked or abstract field.")) { + setverdict(fail, "Incorrect error message received while decoding ", v_exp_enc, " (message: ", msg, ")"); + } + } + + // another negative test example + v_data := { { member2 := something }, { member3 := { bar := 10, foo := omit, base := "base" } } }; + v_exp_enc := char2oct( + "\n" & + "\tsomething\n" & + "\tbase\n" & + "\n\n"); + + v_enc := f_enc_data(v_data); + if (v_enc != v_exp_enc) { + setverdict(fail, "Expected: ", v_exp_enc, ", got: ", v_enc); + } + + @try { + v_dec := f_dec_data(v_exp_enc); + setverdict(fail, "Error expected while decoding ", v_exp_enc); + } + @catch (msg) { + if (not match(msg, pattern "*Index 1: Alternative 'member3': Attempting to decode blocked or abstract field.")) { + setverdict(fail, "Incorrect error message received while decoding ", v_exp_enc, " (message: ", msg, ")"); + } + } + + setverdict(pass); +} + +/******* Test 2: Type substitution example *******/ +type record ParentType { + record length (1 .. infinity) of charstring foo_list optional, + charstring bar +} +with { + variant "name as uncapitalized"; + variant(foo_list) "untagged"; + variant(foo_list[-]) "name as 'foo'"; +} + +type record RestrictedType { + record length (1 .. infinity) of charstring foo_list, + charstring bar +} +with { + variant "name as uncapitalized"; + variant(foo_list) "untagged"; + variant(foo_list[-]) "name as 'foo'"; +} + +type union ParentType_derivations { + ParentType parentType, + RestrictedType restrictedType +} +with { + variant "useType"; + variant "name as 'derivation'"; + variant(parentType) "abstract"; +} + +type record of ParentType_derivations Data2 +with { + variant "name as 'data'"; +} + +external function f_enc_data2(in Data2 x) return octetstring + with { extension "prototype(convert) encode(XER:XER_EXTENDED)" }; + +external function f_dec_data2(in octetstring x) return Data2 + with { extension "prototype(convert) decode(XER:XER_EXTENDED)" }; + +testcase tc_type_substitution() runs on CT +{ + // non-blocked and non-abstract fields should be encoded and decoded normally + var Data2 v_data := { { restrictedType := { foo_list := { "first", "second" }, bar := "restricted" } } }; + var octetstring v_exp_enc := char2oct( + "\n" & + "\t\n" & + "\t\tfirst\n" & + "\t\tsecond\n" & + "\t\trestricted\n" & + "\t\n" & + "\n\n"); + + var octetstring v_enc := f_enc_data2(v_data); // '>' missing from one of the tags, requires Bence's modification + /*if (v_enc != v_exp_enc) { + setverdict(fail, "Expected: ", v_exp_enc, ", got: ", v_enc); + }*/ + var Data2 v_dec := f_dec_data2(v_exp_enc); + if (v_dec != v_data) { + setverdict(fail, "Expected: ", v_data, ", got: ", v_dec); + } + + // abstract and blocked fields are encoded as before, but cause an error while decoding + v_data := { { parentType := { foo_list := omit, bar := "parent" } } }; + v_exp_enc := char2oct( + "\n" & + "\t\n" & + "\t\tparent\n" & + "\t\n" & + "\n\n"); + + v_enc := f_enc_data2(v_data); // '>' missing + /*if (v_enc != v_exp_enc) { + setverdict(fail, "Expected: ", v_exp_enc, ", got: ", v_enc); + }*/ + + @try { + v_dec := f_dec_data2(v_exp_enc); + setverdict(fail, "Error expected while decoding ", v_exp_enc); + } + @catch (msg) { + if (not match(msg, pattern "*Index 0: Alternative 'parentType': Attempting to decode blocked or abstract field.")) { + setverdict(fail, "Incorrect error message received while decoding ", v_exp_enc, " (message: ", msg, ")"); + } + } + + setverdict(pass); +} + +control { + execute(tc_element_substitution()); + execute(tc_type_substitution()); +} + +} +with { + encode "XML"; + variant "namespace as 'http://www.example.org/blockExtension' prefix 'tns'"; + variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/AbstractBlock/Makefile b/regression_test/XML/AbstractBlock/Makefile new file mode 100644 index 0000000..340d03e --- /dev/null +++ b/regression_test/XML/AbstractBlock/Makefile @@ -0,0 +1,138 @@ +############################################################################### +# 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 ../../Makefile.regression + +# WARNING! This Makefile can be used with GNU make only. +# Other versions of make may report syntax errors in it. + +# +# Do NOT touch this line... +# +.PHONY: all archive check clean dep objects + +.SUFFIXES: .d + +# +# Set these variables... +# + +# Flags for the C++ preprocessor (and makedepend as well): +#CPPFLAGS += + +# Flags for dependency generation +CXXDEPFLAGS = -MM + +# Flags for the C++ compiler: +CXXFLAGS += -Wall + +# Flags for the linker: +#LDFLAGS += + +# Flags for the TTCN-3 and ASN.1 compiler: +#COMPILER_FLAGS += + +# Execution mode: (either ttcn3 or ttcn3-parallel) +TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX) + +# +# You may change these variables. Add your files if necessary... +# + +# TTCN-3 modules of this project: +TTCN3_MODULES = AbstractBlock.ttcn + +# ASN.1 modules of this project: +ASN1_MODULES = + +# C++ source & header files generated from the TTCN-3 & ASN.1 modules of +# this project: +GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc) $(ASN1_MODULES:.asn=.cc) +GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh) + +# C/C++ Source & header files of Test Ports, external functions and +# other modules: +USER_SOURCES = +USER_HEADERS = $(USER_SOURCES:.cc=.hh) + +# Object files of this project that are needed for the executable test suite: +OBJECTS = $(GENERATED_OBJECTS) $(USER_OBJECTS) + +GENERATED_OBJECTS = $(GENERATED_SOURCES:.cc=.o) + +USER_OBJECTS = $(USER_SOURCES:.cc=.o) + +DEPFILES = $(USER_OBJECTS:.o=.d) $(GENERATED_OBJECTS:.o=.d) + +# Other files of the project (Makefile, configuration files, etc.) +# that will be added to the archived source files: +OTHER_FILES = Makefile + +# The name of the executable test suite: +TARGET = AbstractBlock + +# +# Rules for building the executable... +# + +all: $(TARGET) ; + +objects: $(OBJECTS) compile; + +$(TARGET): $(OBJECTS) + if $(CXX) $(LDFLAGS) -o $@ $^ \ + -L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) \ + -L$(OPENSSL_DIR)/lib -lcrypto \ + -L$(XMLDIR)/lib $($(PLATFORM)_LIBS); \ + then : ; else $(TTCN3_DIR)/bin/titanver $(OBJECTS); exit 1; fi + +.cc.o .c.o: + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $< + +.cc.d .c.d: + @echo Creating dependency file for '$<'; set -e; \ + $(CXX) $(CXXDEPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $< \ + | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ + [ -s $@ ] || rm -f $@ + +$(GENERATED_SOURCES) $(GENERATED_HEADERS): compile + @if [ ! -f $@ ]; then $(RM) compile; $(MAKE) compile; fi + +compile: $(TTCN3_MODULES) $(ASN1_MODULES) + $(TTCN3_COMPILER) $(COMPILER_FLAGS) $^ - $? + touch $@ + +clean distclean: + -$(RM) $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \ + $(GENERATED_SOURCES) compile $(DEPFILES) \ + tags *.log + +dep: $(GENERATED_SOURCES) $(USER_SOURCES) ; + +ifeq ($(findstring n,$(MAKEFLAGS)),) +ifeq ($(filter clean distclean check compile archive diag,$(MAKECMDGOALS)),) +-include $(DEPFILES) +endif +endif + +diag: + $(TTCN3_COMPILER) -v 2>&1 + $(TTCN3_DIR)/bin/mctr_cli -v 2>&1 + $(CXX) -v 2>&1 + @echo TTCN3_DIR=$(TTCN3_DIR) + @echo OPENSSL_DIR=$(OPENSSL_DIR) + @echo XMLDIR=$(XMLDIR) + @echo PLATFORM=$(PLATFORM) + +# +# Add your rules here if necessary... +# + +run: $(TARGET) + ./$^ + diff --git a/regression_test/XML/EXER-whitepaper/AnyElementOptional.ttcnpp b/regression_test/XML/EXER-whitepaper/AnyElementOptional.ttcnpp index 3398477..e0e734b 100644 --- a/regression_test/XML/EXER-whitepaper/AnyElementOptional.ttcnpp +++ b/regression_test/XML/EXER-whitepaper/AnyElementOptional.ttcnpp @@ -119,11 +119,17 @@ with { DECLARE_XER_ENCODERS(anys_and_only_anys, aaoa); DECLARE_EXER_ENCODERS(anys_and_only_anys, aaoa); -const anys_and_only_anys noanys := { elements := {} } +const anys_and_only_anys noanys_empty := { elements := {} } +const anys_and_only_anys noanys_omit := { elements := omit } + +// the empty array is encoded into this in basic XER const universal charstring bstr_noanys := "\n" & "\t\n" & "\n\n"; + +// both the empty array and the omitted field are encoded into this in extended XER +// this is always decoded into an omitted field const universal charstring estr_noanys := "\n\n"; @@ -153,8 +159,9 @@ const anys_and_only_anys marx_dec := { testcase encode_only_opt() runs on AE { - CHECK_METHOD(bxer_enc_aaoa, noanys, bstr_noanys); - CHECK_METHOD(exer_enc_aaoa, noanys, estr_noanys); + CHECK_METHOD(bxer_enc_aaoa, noanys_empty, bstr_noanys); + CHECK_METHOD(exer_enc_aaoa, noanys_empty, estr_noanys); + CHECK_METHOD(exer_enc_aaoa, noanys_omit, estr_noanys); CHECK_METHOD(bxer_enc_aaoa, marx, bstr_marx); CHECK_METHOD(exer_enc_aaoa, marx, estr_marx); @@ -162,8 +169,8 @@ testcase encode_only_opt() runs on AE testcase decode_only_opt() runs on AE { - CHECK_DECODE(bxer_dec_aaoa, bstr_noanys, anys_and_only_anys, noanys); - CHECK_DECODE(exer_dec_aaoa, estr_noanys, anys_and_only_anys, noanys); + CHECK_DECODE(bxer_dec_aaoa, bstr_noanys, anys_and_only_anys, noanys_empty); + CHECK_DECODE(exer_dec_aaoa, estr_noanys, anys_and_only_anys, noanys_omit); CHECK_DECODE(bxer_dec_aaoa, bstr_marx, anys_and_only_anys, marx); CHECK_DECODE(exer_dec_aaoa, estr_marx, anys_and_only_anys, marx_dec); diff --git a/regression_test/XML/EXER-whitepaper/Untagged.ttcnpp b/regression_test/XML/EXER-whitepaper/Untagged.ttcnpp index 281a344..f305fd7 100644 --- a/regression_test/XML/EXER-whitepaper/Untagged.ttcnpp +++ b/regression_test/XML/EXER-whitepaper/Untagged.ttcnpp @@ -658,6 +658,40 @@ testcase decode_ut_ustr() runs on UTA +// ------- optional record of +type record length (1 .. infinity) of charstring RoCS +with { + variant ([-]) "name as 'str'"; +} + +type record r_recof { + record length (1 .. infinity) of integer num_list optional, + RoCS str_list optional +} +with { + variant(num_list) "untagged"; + variant(num_list[-]) "name as 'num'"; + variant(str_list) "untagged"; +} + +DECLARE_EXER_ENCODERS(r_recof, recof); + +const r_recof c_recof := { num_list := omit, str_list := omit }; + +const universal charstring s_recof := "\n\n"; + +testcase encode_ut_recof() runs on UTA +{ + CHECK_METHOD(exer_enc_recof, c_recof, s_recof); +} + +testcase decode_ut_recof() runs on UTA +{ + CHECK_DECODE(exer_dec_recof, s_recof, r_recof, c_recof); +} + + + /* * * * * * * * * * * Run it! * * * * * * * * * * */ control { @@ -694,6 +728,8 @@ control { execute(encode_ut_ustr()); execute(decode_ut_ustr()); + execute(encode_ut_recof()); + execute(decode_ut_recof()); } } diff --git a/regression_test/XML/EXER-whitepaper/UseType.ttcnpp b/regression_test/XML/EXER-whitepaper/UseType.ttcnpp index d7e8ec3..a975845 100644 --- a/regression_test/XML/EXER-whitepaper/UseType.ttcnpp +++ b/regression_test/XML/EXER-whitepaper/UseType.ttcnpp @@ -120,12 +120,62 @@ testcase decode_12() runs on Shop CHECK_DECODE(exer_dec_u, str_12_e, U, v); } +group QualifiedUseType { + +type union Number { + integer i, + float f, + octetstring os +} +with { + variant "useType"; + variant "name as uncapitalized"; + variant(i) "name as 'integer'"; + variant(f) "name as 'real'"; + variant(os) "name as 'hexadecimal'"; +} + +type record of Number Data +with { + variant "name as uncapitalized"; +} + +} // group QualifiedUseType +with { + variant "elementFormQualified"; + variant "namespace as 'http://www.example.org/Number' prefix 'nr'"; +} + +DECLARE_EXER_ENCODERS(Data, data); + +const Data c_data := { { i := 10 }, { f := 3.3 }, { os := '5DA8'O } }; + +const universal charstring str_data := +"\n" & +"\t10\n" & +"\t3.300000\n" & +"\t5DA8\n" & +"\n\n"; + +testcase encode_qualified() runs on Shop +{ + CHECK_METHOD(exer_enc_data, c_data, str_data); +} + +testcase decode_qualified() runs on Shop +{ + CHECK_DECODE(exer_dec_data, str_data, Data, c_data); +} + control { execute(enc_ut()); execute(dec_ut()); execute(encode_12()); execute(decode_12()); + + execute(encode_qualified()); + execute(decode_qualified()); } } diff --git a/regression_test/XML/Makefile b/regression_test/XML/Makefile index dfdba81..cf5c508 100644 --- a/regression_test/XML/Makefile +++ b/regression_test/XML/Makefile @@ -19,7 +19,7 @@ endif XDIRS := $(wildcard $(SHADOWED)) xsdConverter \ HM60295 HN15589 HQ30408 HR49727 HU13380 $(RT2_ONLY) \ -XmlWorkflow tpdValidTest +XmlWorkflow tpdValidTest AbstractBlock # List of fake targets: .PHONY: all dep clean run $(XDIRS) $(addsuffix /, $(XDIRS)) profile diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/NoTargetNamespace.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/NoTargetNamespace2_e.ttcn similarity index 89% rename from regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/NoTargetNamespace.ttcn rename to regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/NoTargetNamespace2_e.ttcn index d4cb2c7..f073882 100644 --- a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/NoTargetNamespace.ttcn +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/NoTargetNamespace2_e.ttcn @@ -1,7 +1,7 @@ /******************************************************************************* -* Copyright Ericsson Telecom AB 2015 +* Copyright (c) 2000-2015 Ericsson Telecom AB * -* XSD to TTCN-3 Translator version: CRL 113 200/5 R3A +* XSD to TTCN-3 Translator version: CRL 113 200/5 R4A * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -14,7 +14,7 @@ // References: // Rev: // Prodnr: -// Updated: Wed Oct 28 13:59:18 2015 +// Updated: Wed Nov 25 17:13:46 2015 // Contact: http://ttcn.ericsson.se // //////////////////////////////////////////////////////////////////////////////// @@ -33,7 +33,7 @@ //////////////////////////////////////////////////////////////////////////////// -module NoTargetNamespace { +module NoTargetNamespace2_e { import from XSD all; diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_attrib_order_a_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_attrib_order_a_e.ttcn index 0bd3ad2..be0bd72 100644 --- a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_attrib_order_a_e.ttcn +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_attrib_order_a_e.ttcn @@ -42,7 +42,7 @@ import from XSD all; import from www_example_org_attrib_order_b all; -import from NoTargetNamespace all; +import from NoTargetNamespace2_e all; type XSD.String Local1 ("fixed") diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_generate_element_substitution_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_generate_element_substitution_e.ttcn index 7903dec..670400e 100644 --- a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_generate_element_substitution_e.ttcn +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_generate_element_substitution_e.ttcn @@ -90,7 +90,8 @@ type union Head_group } with { variant "untagged"; -//variant (member2) "block"; +variant (head) "form as qualified"; +variant (member2) "block"; }; diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_no_ns_connector_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_no_ns_connector_e.ttcn index dd99f62..f9d635e 100644 --- a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_no_ns_connector_e.ttcn +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_no_ns_connector_e.ttcn @@ -53,6 +53,7 @@ type record Java_attribute_1 } with { variant "name as 'java-attribute'"; +variant "abstract"; variant (java_attribute) "name as 'java-attribute'"; variant (java_attribute) "attribute"; variant (xml_accessor_type) "name as 'xml-accessor-type'"; diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_only_element_substitution_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_only_element_substitution_e.ttcn new file mode 100644 index 0000000..be0e006 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_only_element_substitution_e.ttcn @@ -0,0 +1,98 @@ +/******************************************************************************* +* Copyright (c) 2000-2015 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R3A +* +* 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: www_example_org_only_element_substitution_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Mon Nov 23 13:30:51 2014 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - only_element_substitution_e.xsd +// /* xml version = "1.0" */ +// /* targetnamespace = "www.example.org/only/element/substitution/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_only_element_substitution { + + +import from XSD all; + + +type RequestAbstractType_group RequestAbstractType1 +with { +variant "name as uncapitalized"; +variant "abstract"; +variant "element"; +}; + + +/* Production implementation */ + + +type record ProductionRequest +{ + XSD.String commonName, + XSD.String productionName +} +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +/* Production implementation */ + + +type record ProgrammingRequest +{ + XSD.String commonName, + XSD.String programmingName +} +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +type union RequestAbstractType_group +{ + record { + XSD.String commonName + } requestAbstractType, + ProductionRequest productionRequest, + ProgrammingRequest programmingRequest +} +with { +variant "untagged"; +variant (requestAbstractType) "form as qualified"; +variant (requestAbstractType) "abstract"; +}; + + +} +with { +encode "XML"; +variant "namespace as 'www.example.org/only/element/substitution'"; +variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_abstract_block_1_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_abstract_block_1_e.ttcn index 550b524..e7bd555 100644 --- a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_abstract_block_1_e.ttcn +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_abstract_block_1_e.ttcn @@ -121,8 +121,9 @@ type union Head_group } with { variant "untagged"; -//variant (head) "abstract"; -//variant (member2) "block"; +variant (head) "form as qualified"; +variant (head) "abstract"; +variant (member2) "block"; }; diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_abstract_block_2_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_abstract_block_2_e.ttcn index f1bc2b8..0d6ac78 100644 --- a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_abstract_block_2_e.ttcn +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_abstract_block_2_e.ttcn @@ -121,8 +121,9 @@ type union Head_group } with { variant "untagged"; -//variant (head) "abstract"; -//variant (member3) "block"; +variant (head) "form as qualified"; +variant (head) "abstract"; +variant (member3) "block"; }; diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_complex_without_element_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_complex_without_element_e.ttcn index cd2a805..8bce067 100644 --- a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_complex_without_element_e.ttcn +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_complex_without_element_e.ttcn @@ -110,12 +110,13 @@ type union Head_group_1 } with { variant "untagged"; -//variant (head) "abstract"; +variant (head) "form as qualified"; +variant (head) "abstract"; variant (head.headAttrib) "attribute"; variant (head.something) "name as capitalized"; -//variant (member) "block"; -//variant (member2) "block"; -//variant (stringEnum) "block"; +variant (member) "block"; +variant (member2) "block"; +variant (stringEnum) "block"; }; diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_complextype_block_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_complextype_block_e.ttcn new file mode 100644 index 0000000..a3f4515 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_complextype_block_e.ttcn @@ -0,0 +1,95 @@ +/******************************************************************************* +* Copyright (c) 2000-2015 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R3A +* +* 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: www_example_org_substitutiongroup_complextype_block_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Thu Nov 12 12:43:46 2014 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - substitutiongroup_complextype_block_e.xsd +// /* xml version = "1.0" encoding = "UTF-8" */ +// /* targetnamespace = "www.example.org/substitutiongroup/complextype/block/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_substitutiongroup_complextype_block { + + +import from XSD all; + + +/* SUBSTITUTABLE PARENT TYPE */ + + +type record ParentType +{ + record of XSD.String foo_list, + XSD.String bar +} +with { +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type RestrictedType RestrictedTypeElem +with { +variant "element"; +}; + + +/* The restricting type is: */ + + +type record RestrictedType +{ + record length(1 .. infinity) of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type union Head_group +{ + RestrictedType head, + RestrictedTypeElem restrictedTypeElem +} +with { +variant "untagged"; +variant (head) "form as qualified"; +variant (restrictedTypeElem) "name as capitalized"; +variant (restrictedTypeElem) "block"; +}; + + +} +with { +encode "XML"; +variant "namespace as 'www.example.org/substitutiongroup/complextype/block' prefix 'this'"; +variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_e.ttcn index d5d02bd..b96e0e9 100644 --- a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_e.ttcn +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_e.ttcn @@ -121,12 +121,13 @@ type union Head_group } with { variant "untagged"; +variant (head) "form as qualified"; }; } with { encode "XML"; -variant "namespace as 'www.example.org/substitutiongroup' prefix 'this'"; +variant "namespace as 'www.example.org/substitutiongroup' prefix 'subs'"; variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; } diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_long_extension_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_long_extension_e.ttcn index eabb918..d4b44a1 100644 --- a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_long_extension_e.ttcn +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_long_extension_e.ttcn @@ -138,9 +138,9 @@ type union Head_group } with { variant "untagged"; -//variant (complexEnum) "block"; -//variant (member2) "block"; -//variant (member3) "block"; +variant (complexEnum) "block"; +variant (member2) "block"; +variant (member3) "block"; }; diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_main_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_main_e.ttcn index ad5eb21..026df74 100644 --- a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_main_e.ttcn +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_main_e.ttcn @@ -65,7 +65,8 @@ type union Subsgroup_group } with { variant "untagged"; -//variant (subsgroup) "abstract"; +variant (subsgroup) "form as qualified"; +variant (subsgroup) "abstract"; variant (replace_) "name as 'replace'"; }; diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_name_as_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_name_as_e.ttcn new file mode 100644 index 0000000..27e19c6 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_name_as_e.ttcn @@ -0,0 +1,131 @@ +/******************************************************************************* +* Copyright (c) 2000-2015 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R3A +* +* 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: www_example_org_substitutiongroup_name_as_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Thu Nov 12 10:42:59 2014 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - substitutiongroup_name_as_e.xsd +// /* xml version = "1.0" encoding = "UTF-8" */ +// /* targetnamespace = "www.example.org/substitutiongroup/name/as/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_substitutiongroup_name_as { + + +import from XSD all; + + +/* THE HEAD ELEMENT */ + + +/* SUBSTITUTION ELEMENT OF THE SAME TYPE AS THE HEAD */ + + +type XSD.String Member1 +with { +variant "element"; +}; + + +/* SUBSTITUTION ELEMENT OF A TYPE RESTRICTING THE TYPE OF THE HEAD */ + + +type enumerated StringEnum +{ + else_, + something +} +with { +variant "text 'else_' as 'else'"; +}; + + +type StringEnum Member2 +with { +variant "element"; +}; + + +/* SUBSTITUTION ELEMENT OF A TYPE EXTENDING THE TYPE OF THE HEAD */ + + +type record ComplexEnum +{ + XSD.Integer bar optional, + XSD.Float foo optional, + XSD.String base +} +with { +variant (bar) "attribute"; +variant (foo) "attribute"; +variant (base) "untagged"; +}; + + +type ComplexEnum Member3 +with { +variant "element"; +}; + + +/* TOP LEVEL ELEMENT TO DEMONSTRATE SUBSTITUTION */ + + +type record Ize +{ + record of Head_group head_list +} +with { +variant "element"; +variant (head_list) "untagged"; +variant (head_list[-]) "name as 'Head'"; +}; + + +type union Head_group +{ + XSD.String head, + Member1 member1, + Member2 member2, + Member3 member3 +} +with { +variant "untagged"; +variant (head) "name as capitalized"; +variant (head) "form as qualified"; +variant (member1) "name as capitalized"; +variant (member2) "name as capitalized"; +variant (member3) "name as capitalized"; +}; + + +} +with { +encode "XML"; +variant "namespace as 'www.example.org/substitutiongroup/name/as' prefix 'this'"; +variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_rename_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_rename_e.ttcn new file mode 100644 index 0000000..580a1b4 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_substitutiongroup_rename_e.ttcn @@ -0,0 +1,101 @@ +/******************************************************************************* +* Copyright (c) 2000-2015 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R3A +* +* 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: www_example_org_substitutiongroup_rename_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Wed Nov 25 14:32:37 2014 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - substitutiongroup_rename_e.xsd +// /* xml version = "1.0" */ +// /* targetnamespace = "www.example.org/substitutiongroup/rename/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_substitutiongroup_rename { + + +import from XSD all; + + +type record BaseElement_1 +{ + +} +with { +variant "name as 'BaseElement_'"; +}; + + +type record Audit +{ + BaseElement_group baseElement optional +} +with { +variant (baseElement) "name as capitalized"; +}; + + +type XSD.Integer Case +with { +variant "abstract"; +variant "element"; +}; + + +type XSD.String BaseElement +with { +variant "name as 'BaseElement__'"; +variant "abstract"; +variant "element"; +}; + + +type Audit Case_1 +with { +variant "name as 'Case_'"; +variant "element"; +}; + + +type union BaseElement_group +{ + BaseElement_1 baseElement, + Case_1 case_ +} +with { +variant "untagged"; +variant (baseElement) "name as capitalized"; +variant (baseElement) "form as qualified"; +variant (baseElement) "abstract"; +variant (case_) "name as capitalized"; +}; + + +} +with { +encode "XML"; +variant "namespace as 'www.example.org/substitutiongroup/rename' prefix 'this'"; +variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_subs_with_elem_subs_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_subs_with_elem_subs_e.ttcn new file mode 100644 index 0000000..7752697 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_subs_with_elem_subs_e.ttcn @@ -0,0 +1,152 @@ +/******************************************************************************* +* Copyright (c) 2000-2015 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R3A +* +* 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: www_example_org_type_subs_with_elem_subs_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Wed Nov 18 13:34:40 2014 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - type_subs_with_elem_subs_e.xsd +// /* xml version = "1.0" */ +// /* targetnamespace = "www.example.org/type/subs/with/elem/subs/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_type_subs_with_elem_subs { + + +import from XSD all; + + +/* Root element */ + + +type SubmitRequestType Submit +with { +variant "element"; +}; + + +type record RequestGroup +{ + Request_group request +} +with { +variant "name as uncapitalized"; +}; + + +type record SubmitRequestType +{ + XSD.String name, + RequestAbstractType_derivations request1, + RequestAbstractType_derivations request2 +}; + + +/* The generic abstract type */ + + +type record RequestAbstractType +{ + XSD.String commonName +} +with { +variant "name as uncapitalized"; +variant "abstract"; +}; + + +/* Production implementation */ + + +type MyProductionRequestType ProductionRequest +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +type record MyProductionRequestType +{ + XSD.String commonName, + XSD.String productionName +} +with { +variant "name as uncapitalized"; +}; + + +/* Production implementation */ + + +type MyProgrammingRequestType ProgrammingRequest +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +type record MyProgrammingRequestType +{ + XSD.String commonName, + XSD.String programmingName +} +with { +variant "name as uncapitalized"; +}; + + +type union Request_group +{ + RequestAbstractType_derivations request, + ProductionRequest productionRequest, + ProgrammingRequest programmingRequest +} +with { +variant "untagged"; +variant (request) "form as qualified"; +variant (request) "abstract"; +}; + + +type union RequestAbstractType_derivations +{ + RequestAbstractType requestAbstractType, + MyProductionRequestType myProductionRequestType, + MyProgrammingRequestType myProgrammingRequestType +} +with { +variant "name as uncapitalized"; +variant "useType"; +variant (requestAbstractType) "abstract"; +}; + + +} +with { +encode "XML"; +variant "namespace as 'www.example.org/type/subs/with/elem/subs'"; +variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_abstract_block_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_abstract_block_e.ttcn new file mode 100644 index 0000000..45762e5 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_abstract_block_e.ttcn @@ -0,0 +1,210 @@ +/******************************************************************************* +* Copyright (c) 2000-2015 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R3A +* +* 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: www_example_org_type_substitution_abstract_block_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Tue Nov 17 13:25:59 2014 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - type_substitution_abstract_block_e.xsd +// /* xml version = "1.0" encoding = "UTF-8" */ +// /* targetnamespace = "www.example.org/type/substitution/abstract/block/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_type_substitution_abstract_block { + + +import from XSD all; + + +type ParentType_derivations Head +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +/* SUBSTITUTABLE PARENT TYPE */ + + +/* type substitutiongroup generated, because has elemet declaration */ + + +type record ParentType +{ + record of XSD.String foo_list, + XSD.String bar +} +with { +variant "abstract"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type RestrictedType_derivations RestrictedTypeElem +with { +variant "element"; +}; + + +/* type substitutiongroup generated, because has elemet declaration */ + + +type record RestrictedType +{ + record length(1 .. infinity) of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +/* type substitutiongroup generated, because the parent has elemet declaration */ + + +type record RestrictedType2 +{ + record length(2 .. infinity) of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +/* Added to restrictedtype_derivations */ + + +type record RestrictedType2_1 +{ + record length(2 .. 5) of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as 'restrictedType2.1'"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +/* No type substitutiongroup generated, because the parent lacks elemet declaration */ + + +type record RestrictedType3 +{ + record length(3 .. infinity) of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type ExtendedType_derivations ExtendedElement +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +type record ExtendedType +{ + XSD.String attr1 optional, + record of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (attr1) "attribute"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type record RestrictedExtendedType +{ + record of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type union ParentType_derivations +{ + ParentType parentType, + ExtendedType_derivations extendedType, + RestrictedType_derivations restrictedType +} +with { +variant "useType"; +variant (parentType) "name as capitalized"; +variant (parentType) "abstract"; +variant (extendedType) "block"; +}; + + +type union RestrictedType_derivations +{ + RestrictedType restrictedType, + RestrictedType2 restrictedType2, + RestrictedType2_1 restrictedType2_1 +} +with { +variant "name as uncapitalized"; +variant "useType"; +variant (restrictedType2_1) "name as 'restrictedType2.1'"; +}; + + +type union ExtendedType_derivations +{ + ExtendedType extendedType, + RestrictedExtendedType restrictedExtendedType +} +with { +variant "name as uncapitalized"; +variant "useType"; +variant (restrictedExtendedType) "block"; +}; + + +} +with { +encode "XML"; +variant "namespace as 'www.example.org/type/substitution/abstract/block' prefix 'tys'"; +variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_builtintype_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_builtintype_e.ttcn new file mode 100644 index 0000000..9003371 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_builtintype_e.ttcn @@ -0,0 +1,104 @@ +/******************************************************************************* +* Copyright (c) 2000-2015 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R3A +* +* 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: www_example_org_type_substitution_builtintype_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Tue Nov 24 11:21:17 2014 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - type_substitution_builtintype_e.xsd +// /* xml version = "1.0" */ +// /* targetnamespace = "www.example.org/type/substitution/builtintype/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_type_substitution_builtintype { + + +import from XSD all; + + +type String_derivations Elem +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +type enumerated Enable +{ + equal +} +with { +variant "name as uncapitalized"; +}; + + +type enumerated Session +{ + visible_and_interactive +} +with { +variant "name as uncapitalized"; +}; + + +type enumerated Res +{ + pending +} +with { +variant "name as uncapitalized"; +}; + + +type enumerated Data +{ + dateTime +} +with { +variant "name as uncapitalized"; +}; + + +type union String_derivations +{ + XSD.String string, + Data data, + Enable enable, + Res res, + Session session +} +with { +variant "name as uncapitalized"; +variant "useType"; +}; + + +} +with { +encode "XML"; +variant "namespace as 'www.example.org/type/substitution/builtintype' prefix 'this'"; +variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_chain_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_chain_e.ttcn new file mode 100644 index 0000000..16c57b6 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_chain_e.ttcn @@ -0,0 +1,161 @@ +/******************************************************************************* +* Copyright (c) 2000-2015 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R3A +* +* 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: www_example_org_type_substitution_chain_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Tue Nov 17 11:30:22 2014 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - type_substitution_chain_e.xsd +// /* xml version = "1.0" encoding = "UTF-8" */ +// /* targetnamespace = "www.example.org/type/substitution/chain/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_type_substitution_chain { + + +import from XSD all; + + +type ParentType_derivations Head +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +/* SUBSTITUTABLE PARENT TYPE */ + + +/* type substitutiongroup generated, because has elemet declaration */ + + +type record ParentType +{ + record of XSD.String foo_list, + XSD.String bar +} +with { +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type RestrictedType_derivations RestrictedTypeElem +with { +variant "element"; +}; + + +/* type substitutiongroup generated, because has elemet declaration */ + + +type record RestrictedType +{ + record length(1 .. infinity) of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +/* type substitutiongroup generated, because the parent has elemet declaration */ + + +type record RestrictedType2 +{ + record length(2 .. infinity) of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +/* Added to restrictedtype_derivations */ + + +type record RestrictedType2_1 +{ + record length(2 .. 5) of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as 'restrictedType2.1'"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +/* No type substitutiongroup generated, because the parent lacks elemet declaration */ + + +type record RestrictedType3 +{ + record length(3 .. infinity) of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type union ParentType_derivations +{ + ParentType parentType, + RestrictedType_derivations restrictedType +} +with { +variant "useType"; +variant (parentType) "name as capitalized"; +}; + + +type union RestrictedType_derivations +{ + RestrictedType restrictedType, + RestrictedType2 restrictedType2, + RestrictedType2_1 restrictedType2_1 +} +with { +variant "name as uncapitalized"; +variant "useType"; +variant (restrictedType2_1) "name as 'restrictedType2.1'"; +}; + + +} +with { +encode "XML"; +variant "namespace as 'www.example.org/type/substitution/chain' prefix 'tys'"; +variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_e.ttcn new file mode 100644 index 0000000..3a48253 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_e.ttcn @@ -0,0 +1,113 @@ +/******************************************************************************* +* Copyright (c) 2000-2015 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R3A +* +* 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: www_example_org_type_substitution_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Mon Nov 16 10:01:25 2014 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - type_substitution_e.xsd +// /* xml version = "1.0" encoding = "UTF-8" */ +// /* targetnamespace = "www.example.org/type/substitution/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_type_substitution { + + +import from XSD all; + + +type ParentType_derivations Head +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +/* SUBSTITUTABLE PARENT TYPE */ + + +type record ParentType +{ + record of XSD.String foo_list, + XSD.String bar +} +with { +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type RestrictedType RestrictedTypeElem +with { +variant "element"; +}; + + +/* The restricting type is: */ + + +type record RestrictedType +{ + record length(1 .. infinity) of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type SubmitRequestType Submit +with { +variant "element"; +}; + + +type record SubmitRequestType +{ + ParentType_derivations request1, + ParentType_derivations request2 +}; + + +type union ParentType_derivations +{ + ParentType parentType, + RestrictedType restrictedType +} +with { +variant "useType"; +variant (parentType) "name as capitalized"; +}; + + +} +with { +encode "XML"; +variant "namespace as 'www.example.org/type/substitution' prefix 'tysub'"; +variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_elem_in_ct_mod1_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_elem_in_ct_mod1_e.ttcn new file mode 100644 index 0000000..3f7e98c --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_elem_in_ct_mod1_e.ttcn @@ -0,0 +1,150 @@ +/******************************************************************************* +* Copyright (c) 2000-2015 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R3A +* +* 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: www_example_org_type_substitution_elem_in_ct_mod1_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Wed Nov 18 15:03:25 2014 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - type_substitution_elem_in_ct_mod1_e.xsd +// /* xml version = "1.0" encoding = "UTF-8" */ +// /* targetnamespace = "www.example.org/type/substitution/elem/in/ct/mod1/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_type_substitution_elem_in_ct_mod1 { + + +import from XSD all; + + +type record Complex +{ + String_derivations string, + ParentType_derivations parentType +} +with { +variant "element"; +}; + + +type XSD.String Stringtype +with { +variant "name as uncapitalized"; +}; + + +type XSD.String Stringtype2 length(5) +with { +variant "name as uncapitalized"; +}; + + +type record ParentType +{ + record of XSD.String foo_list, + XSD.String bar +} +with { +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type record RestrictedType +{ + record length(1 .. infinity) of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type record MorerestrictedType +{ + record length(2 .. infinity) of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type union String_derivations +{ + XSD.String string, + Stringtype_derivations stringtype +} +with { +variant "name as uncapitalized"; +variant "useType"; +}; + + +type union Stringtype_derivations +{ + Stringtype stringtype, + Stringtype2 stringtype2 +} +with { +variant "name as uncapitalized"; +variant "useType"; +}; + + +type union ParentType_derivations +{ + ParentType parentType, + RestrictedType_derivations restrictedType +} +with { +variant "useType"; +variant (parentType) "name as capitalized"; +variant (restrictedType) "block"; +}; + + +type union RestrictedType_derivations +{ + RestrictedType restrictedType, + MorerestrictedType morerestrictedType +} +with { +variant "name as uncapitalized"; +variant "useType"; +variant (morerestrictedType) "block"; +}; + + +} +with { +encode "XML"; +variant "namespace as 'www.example.org/type/substitution/elem/in/ct/mod1' prefix 'this'"; +variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_elem_in_ct_mod2_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_elem_in_ct_mod2_e.ttcn new file mode 100644 index 0000000..40eaaa1 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_elem_in_ct_mod2_e.ttcn @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (c) 2000-2015 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R3A +* +* 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: www_example_org_type_substitution_elem_in_ct_mod2_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Wed Nov 18 15:03:25 2014 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - type_substitution_elem_in_ct_mod2_e.xsd +// /* xml version = "1.0" encoding = "UTF-8" */ +// /* targetnamespace = "www.example.org/type/substitution/elem/in/ct/mod2/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_type_substitution_elem_in_ct_mod2 { + + +import from XSD all; + + +import from www_example_org_type_substitution_elem_in_ct_mod1 all; + + +type record Complex2 +{ + Stringtype_derivations stringType, + ParentType_derivations parentType, + RestrictedType_derivations restrictedType +} +with { +variant "element"; +}; + + +} +with { +encode "XML"; +variant "namespace as 'www.example.org/type/substitution/elem/in/ct/mod2'"; +variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_mod1_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_mod1_e.ttcn new file mode 100644 index 0000000..1b379a9 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_mod1_e.ttcn @@ -0,0 +1,168 @@ +/******************************************************************************* +* Copyright (c) 2000-2015 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R3A +* +* 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: www_example_org_type_substitution_mod1_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Tue Nov 17 14:10:37 2014 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - type_substitution_mod1_e.xsd +// /* xml version = "1.0" encoding = "UTF-8" */ +// /* targetnamespace = "www.example.org/type/substitution/mod1/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_type_substitution_mod1 { + + +import from XSD all; + + +import from www_example_org_type_substitution_mod2 all; + + +/* SUBSTITUTABLE PARENT TYPE */ + + +/* type substitutiongroup generated, because has elemet declaration */ + + +type record ParentType +{ + record of XSD.String foo_list, + XSD.String bar +} +with { +variant "abstract"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type RestrictedType_derivations RestrictedTypeElem +with { +variant "element"; +}; + + +/* type substitutiongroup generated, because has elemet declaration */ + + +type record RestrictedType +{ + record length(1 .. infinity) of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +/* type substitutiongroup generated, because the parent has elemet declaration */ + + +type record RestrictedType2 +{ + record length(2 .. infinity) of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +/* Added to restrictedtype_derivations */ + + +type record RestrictedType2_1 +{ + record length(2 .. 5) of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as 'restrictedType2.1'"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +/* No type substitutiongroup generated, because the parent lacks elemet declaration */ + + +type record RestrictedType3 +{ + record length(3 .. infinity) of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type ExtendedType_derivations ExtendedElement +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +type union ParentType_derivations +{ + ParentType parentType, + ExtendedType_derivations extendedType, + RestrictedType_derivations restrictedType +} +with { +variant "useType"; +variant (parentType) "name as capitalized"; +variant (parentType) "abstract"; +variant (extendedType) "block"; +}; + + +type union RestrictedType_derivations +{ + RestrictedType restrictedType, + RestrictedType2 restrictedType2, + RestrictedType2_1 restrictedType2_1 +} +with { +variant "name as uncapitalized"; +variant "useType"; +variant (restrictedType2_1) "name as 'restrictedType2.1'"; +}; + + +} +with { +encode "XML"; +variant "namespace as 'www.example.org/type/substitution/mod1' prefix 'tys'"; +variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_mod2_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_mod2_e.ttcn new file mode 100644 index 0000000..157e911 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_mod2_e.ttcn @@ -0,0 +1,110 @@ +/******************************************************************************* +* Copyright (c) 2000-2015 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R3A +* +* 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: www_example_org_type_substitution_mod2_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Tue Nov 17 14:10:37 2014 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - type_substitution_mod2_e.xsd +// /* xml version = "1.0" */ +// /* targetnamespace = "www.example.org/type/substitution/mod2/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_type_substitution_mod2 { + + +import from XSD all; + + +import from www_example_org_type_substitution_mod1 all; + + +type ParentType_derivations Subsgroup +with { +variant "name as uncapitalized"; +variant "abstract"; +variant "element"; +}; + + +type record ExtendedType +{ + XSD.String attr1 optional, + record of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (attr1) "attribute"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type record RestrictedExtendedType +{ + record of XSD.String foo_list, + XSD.String bar +} +with { +variant "name as uncapitalized"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type RestrictedType_derivations NameTest +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +type ExtendedType_derivations NameTest2 +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +type union ExtendedType_derivations +{ + ExtendedType extendedType, + RestrictedExtendedType restrictedExtendedType +} +with { +variant "name as uncapitalized"; +variant "useType"; +variant (restrictedExtendedType) "block"; +}; + + +} +with { +encode "XML"; +variant "namespace as 'www.example.org/type/substitution/mod2'"; +variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_rename_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_rename_e.ttcn new file mode 100644 index 0000000..c763e42 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_rename_e.ttcn @@ -0,0 +1,103 @@ +/******************************************************************************* +* Copyright (c) 2000-2015 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R3A +* +* 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: www_example_org_type_substitution_rename_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Wed Nov 25 14:43:08 2014 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - type_substitution_rename_e.xsd +// /* xml version = "1.0" */ +// /* targetnamespace = "www.example.org/type/substitution/rename/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_type_substitution_rename { + + +import from XSD all; + + +type record Complex +{ + ParentType parentType, + ParentType_derivations sd +} +with { +variant "element"; +}; + + +type ParentType_derivations ParentType +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +type record ParentType_1 +{ + record of XSD.String foo_list +} +with { +variant "name as 'ParentType'"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type RestrictedType_1 RestrictedType +with { +variant "element"; +}; + + +type record RestrictedType_1 +{ + record length(1 .. infinity) of XSD.String foo_list +} +with { +variant "name as 'restrictedType'"; +variant (foo_list) "untagged"; +variant (foo_list[-]) "name as 'foo'"; +}; + + +type union ParentType_derivations +{ + ParentType_1 parentType, + RestrictedType_1 restrictedType +} +with { +variant "useType"; +variant (parentType) "name as capitalized"; +}; + + +} +with { +encode "XML"; +variant "namespace as 'www.example.org/type/substitution/rename' prefix 'this'"; +variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_simpletype_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_simpletype_e.ttcn new file mode 100644 index 0000000..cf48c3c --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_type_substitution_simpletype_e.ttcn @@ -0,0 +1,190 @@ +/******************************************************************************* +* Copyright (c) 2000-2015 Ericsson Telecom AB +* +* XSD to TTCN-3 Translator version: CRL 113 200/5 R3A +* +* 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: www_example_org_type_substitution_simpletype_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Wed Nov 18 11:56:35 2014 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - type_substitution_simpletype_e.xsd +// /* xml version = "1.0" encoding = "UTF-8" */ +// /* targetnamespace = "www.example.org/type/substitution/simpletype/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module www_example_org_type_substitution_simpletype { + + +import from XSD all; + + +type String_derivations Head +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +type String_derivations Head_1 +with { +variant "name as 'head_'"; +variant "element"; +}; + + +type Stringtype_derivations Head2 +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +type XSD.String Stringtype +with { +variant "name as uncapitalized"; +}; + + +type XSD.String Stringtype2 length(5) +with { +variant "name as uncapitalized"; +}; + + +type Integer_derivations Int +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +type XSD.Integer ExtInt +with { +variant "name as uncapitalized"; +}; + + +/* Test if the elements are changed in a complextype */ + + +type Base64Binary_derivations Elem +with { +variant "name as uncapitalized"; +variant "element"; +}; + + +type XSD.Base64Binary CrypBinary; + + +type Signature SignatureValue +with { +variant "element"; +}; + + +type record Signature +{ + XSD.ID id optional, + XSD.Base64Binary base +} +with { +variant (id) "name as capitalized"; +variant (id) "attribute"; +variant (base) "untagged"; +}; + + +type DataType Data +with { +variant "element"; +}; + + +type record DataType +{ + union { + Base64Binary_derivations sKI, + Base64Binary_derivations cert + } choice +} +with { +variant (choice) "untagged"; +variant (choice.sKI) "name as capitalized"; +variant (choice.cert) "name as capitalized"; +}; + + +type union String_derivations +{ + XSD.String string, + Stringtype_derivations stringtype +} +with { +variant "name as uncapitalized"; +variant "useType"; +}; + + +type union Stringtype_derivations +{ + Stringtype stringtype, + Stringtype2 stringtype2 +} +with { +variant "name as uncapitalized"; +variant "useType"; +}; + + +type union Integer_derivations +{ + XSD.Integer integer_, + ExtInt extInt +} +with { +variant "name as uncapitalized"; +variant "useType"; +variant (integer_) "name as 'integer'"; +}; + + +type union Base64Binary_derivations +{ + XSD.Base64Binary base64Binary, + CrypBinary crypBinary +} +with { +variant "name as uncapitalized"; +variant "useType"; +variant (crypBinary) "name as capitalized"; +}; + + +} +with { +encode "XML"; +variant "namespace as 'www.example.org/type/substitution/simpletype' prefix 'this'"; +variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; +} diff --git a/regression_test/XML/XmlWorkflow/src/xmlTest.prj b/regression_test/XML/XmlWorkflow/src/xmlTest.prj index a28fc99..fa52de0 100644 --- a/regression_test/XML/XmlWorkflow/src/xmlTest.prj +++ b/regression_test/XML/XmlWorkflow/src/xmlTest.prj @@ -121,10 +121,14 @@ + + + + @@ -136,6 +140,18 @@ + + + + + + + + + + + + @@ -313,7 +329,7 @@ - + @@ -329,12 +345,15 @@ + + + @@ -343,6 +362,18 @@ + + + + + + + + + + + + diff --git a/regression_test/XML/XmlWorkflow/src/xmlTest_Functions_element.ttcn b/regression_test/XML/XmlWorkflow/src/xmlTest_Functions_element.ttcn index 9a79caf..38ead38 100644 --- a/regression_test/XML/XmlWorkflow/src/xmlTest_Functions_element.ttcn +++ b/regression_test/XML/XmlWorkflow/src/xmlTest_Functions_element.ttcn @@ -14,6 +14,8 @@ import from www_XmlTest_org_element_recordOfElements4_e all; import from www_XmlTest_org_element_recordOfElements5_e all; import from www_XmlTest_org_element_nameInheritance_e all; import from www_ericsson_com_is_isco_Tgc_R6A48_R6H01 all; +import from www_example_org_substitutiongroup all; +import from www_example_org_type_substitution all; import from XmlTest_imsike_e all; import from xmlTest_Shell all; //============================================================================== @@ -85,6 +87,18 @@ with { extension "prototype(fast) encode(XER:XER_EXTENDED)" } external function f_dec_Tgc(in octetstring stream, out Tgc pdu) return integer with { extension "prototype(backtrack) decode(XER:XER_EXTENDED)" } +external function f_enc_ize_subs(in Ize pdu, out octetstring stream) +with { extension "prototype(fast) encode(XER:XER_EXTENDED)" } + +external function f_dec_ize_subs(in octetstring stream, out Ize pdu) return integer +with { extension "prototype(backtrack) decode(XER:XER_EXTENDED)" } + +external function f_enc_type_subs(in Submit pdu, out octetstring stream) +with { extension "prototype(fast) encode(XER:XER_EXTENDED)" } + +external function f_dec_type_subs(in octetstring stream, out Submit pdu) return integer +with { extension "prototype(backtrack) decode(XER:XER_EXTENDED)" } + //============================================================================== // Encoding decoding test //============================================================================== @@ -1118,4 +1132,172 @@ function f_encDecTest_Tgc() runs on Shell_CT { }//f_ +//========================================== +//f_encDecTest_Ize +//========================================== +function f_encDecTest_ize_subs() runs on Shell_CT { + + var Ize vl_pdu := { head_list := { + { head := "anything" }, + { member1 := "any thing" }, + { member2 := something }, + { member3 := { bar:= 5, foo := omit, base := "anything else" } } } + }, + vl_decodedPdu; + + var octetstring vl_expectedEncodedPdu:=char2oct( + "\n"& + "\tanything\n"& + "\tany thing\n"& + "\tsomething\n"& + "\tanything else\n"& + "\n\n"); + + var octetstring vl_stream:=''O; + f_enc_ize_subs(vl_pdu,vl_stream); + + if( match(vl_stream,vl_expectedEncodedPdu)) { + setverdict(pass); + } else { + log("Expected encoded value: ",vl_expectedEncodedPdu); + log("Actual encoded value: ", vl_stream); + setverdict(fail); + } + + //log("===Checking encoded value (xml) against the xsd file by xmllint ==="); + var boolean vl_success:=false; + f_shell_validateXml(vl_stream,"substitutiongroup.xsd", c_shell_successWithoutWarningAndError, vl_success); + if(vl_success) { + setverdict(pass); + }else{ + log("Xml validation against xsd failed"); + setverdict(fail); + } + + //log("===Checking value decoded from the encoded value vs original value==="); + var integer vl_retval:=f_dec_ize_subs(vl_stream, vl_decodedPdu); + //log("retval:",vl_retval); + if(f_dec_ize_subs(vl_stream, vl_decodedPdu)==0) { + //log("The decoded pdu: ", vl_decodedPdu); + if(match(vl_pdu,vl_decodedPdu)) { + setverdict(pass); + } else { + log("Pdu differs from the expected value"); + log(match(vl_pdu,vl_decodedPdu)); + setverdict(fail); + } + }else{ + log("Pdu could not decoded"); + setverdict(fail); + } + + //log("===Checking value decoded from the expected value vs original value==="); + if( f_dec_ize_subs(vl_expectedEncodedPdu, vl_decodedPdu)==0) { + //log("The decoded pdu: ", vl_decodedPdu); + if(match(vl_pdu,vl_decodedPdu)) { + setverdict(pass); + } else { + log("Pdu could not decoded from the expected value"); + log(match(vl_pdu,vl_decodedPdu)); + setverdict(fail); + } + } else { + log("Pdu could not decoded from the expected value"); + setverdict(fail); + } +}//f_ + + +//========================================== +//f_encDecTest_type_subs +//========================================== +function f_encDecTest_type_subs() runs on Shell_CT { + + var Submit vl_pdu := { + request1 := { + restrictedType := { + foo_list := { "string1", "string2", "string3" }, + bar := "bar" + } + }, + request2 := { + parentType := { + foo_list := { "parentstring1", "parentstring2", "parentstring3" }, + bar := "parentbar" + } + } + }, + vl_decodedPdu; + var octetstring vl_expectedEncodedPdu:=char2oct( + "\n"& + "\t\n"& + "\t\tstring1\n"& + "\t\tstring2\n"& + "\t\tstring3\n"& + "\t\tbar\n"& + "\t\n"& + "\t\n"& + "\t\tparentstring1\n"& + "\t\tparentstring2\n"& + "\t\tparentstring3\n"& + "\t\tparentbar\n"& + "\t\n"& + "\n\n"); + + var octetstring vl_stream:=''O; + f_enc_type_subs(vl_pdu,vl_stream); + + if( match(vl_stream,vl_expectedEncodedPdu)) { + setverdict(pass); + } else { + log("Expected encoded value: ",vl_expectedEncodedPdu); + log("Actual encoded value: ", vl_stream); + setverdict(fail); + } + + //log("===Checking encoded value (xml) against the xsd file by xmllint ==="); + var boolean vl_success:=false; + f_shell_validateXml(vl_stream,"type_substitution.xsd", c_shell_successWithoutWarningAndError, vl_success); + if(vl_success) { + setverdict(pass); + }else{ + log("Xml validation against xsd failed"); + setverdict(fail); + } + + //log("===Checking value decoded from the encoded value vs original value==="); + var integer vl_retval:=f_dec_type_subs(vl_stream, vl_decodedPdu); + //log("retval:",vl_retval); + if(f_dec_type_subs(vl_stream, vl_decodedPdu)==0) { + //log("The decoded pdu: ", vl_decodedPdu); + if(match(vl_pdu,vl_decodedPdu)) { + setverdict(pass); + } else { + log("Pdu differs from the expected value"); + log(match(vl_pdu,vl_decodedPdu)); + setverdict(fail); + } + }else{ + log("Pdu could not decoded"); + setverdict(fail); + } + + //log("===Checking value decoded from the expected value vs original value==="); + if( f_dec_type_subs(vl_expectedEncodedPdu, vl_decodedPdu)==0) { + //log("The decoded pdu: ", vl_decodedPdu); + if(match(vl_pdu,vl_decodedPdu)) { + setverdict(pass); + } else { + log("Pdu could not decoded from the expected value"); + log(match(vl_pdu,vl_decodedPdu)); + setverdict(fail); + } + } else { + log("Pdu could not decoded from the expected value"); + setverdict(fail); + } +}//f_ + + }//module diff --git a/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn b/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn index c968830..1b1ad38 100644 --- a/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn +++ b/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn @@ -1536,7 +1536,7 @@ group ComplexType { }//tc_ testcase tc_no_ns_connector() runs on xmlTest_CT { - f_shellCommandWithVerdict("xsd2ttcn no_ns_connector.xsd","",c_shell_successWithWarning) + f_shellCommandWithVerdict("xsd2ttcn no_ns_connector.xsd","",c_shell_successWithoutWarningAndError) if(getverdict==pass) { f_compareFiles( @@ -2009,9 +2009,20 @@ group Elements{ }//tc_ + testcase tc_substitutiongroup_name_as() runs on xmlTest_CT { + + f_shellCommandWithVerdict("xsd2ttcn substitutiongroup_name_as.xsd","",c_shell_successWithoutWarningAndError) + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_substitutiongroup_name_as_e.ttcn","www_example_org_substitutiongroup_name_as.ttcn", c_numOfDiff_headerModNameAndNamespace); + } + + }//tc_ + testcase tc_substitutiongroup_abstract_block_rest() runs on xmlTest_CT { - f_shellCommandWithVerdict("xsd2ttcn substitutiongroup_abstract_block_1.xsd","",c_shell_successWithWarning) + f_shellCommandWithVerdict("xsd2ttcn substitutiongroup_abstract_block_1.xsd","",c_shell_successWithoutWarningAndError) if(getverdict==pass) { f_compareFiles( @@ -2023,7 +2034,7 @@ group Elements{ testcase tc_substitutiongroup_abstract_block_ext() runs on xmlTest_CT { - f_shellCommandWithVerdict("xsd2ttcn substitutiongroup_abstract_block_2.xsd","",c_shell_successWithWarning) + f_shellCommandWithVerdict("xsd2ttcn substitutiongroup_abstract_block_2.xsd","",c_shell_successWithoutWarningAndError) if(getverdict==pass) { f_compareFiles( @@ -2035,7 +2046,7 @@ group Elements{ testcase tc_substitutiongroup_complex_without_element() runs on xmlTest_CT { - f_shellCommandWithVerdict("xsd2ttcn substitutiongroup_complex_without_element.xsd","",c_shell_successWithWarning) + f_shellCommandWithVerdict("xsd2ttcn substitutiongroup_complex_without_element.xsd","",c_shell_successWithoutWarningAndError) if(getverdict==pass) { f_compareFiles( @@ -2047,7 +2058,7 @@ group Elements{ testcase tc_substitutiongroup_long_extension() runs on xmlTest_CT { - f_shellCommandWithVerdict("xsd2ttcn substitutiongroup_complex_without_element.xsd","",c_shell_successWithWarning) + f_shellCommandWithVerdict("xsd2ttcn substitutiongroup_complex_without_element.xsd","",c_shell_successWithoutWarningAndError) if(getverdict==pass) { f_compareFiles( @@ -2057,6 +2068,26 @@ group Elements{ }//tc_ + testcase tc_substitutiongroup_complextype_block() runs on xmlTest_CT { + + f_shellCommandWithVerdict("xsd2ttcn substitutiongroup_complextype_block.xsd","",c_shell_successWithoutWarningAndError) + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_substitutiongroup_complextype_block_e.ttcn", + "www_example_org_substitutiongroup_complextype_block.ttcn", c_numOfDiff_headerModNameAndNamespace); + } + + }//tc_ + + //Test if we find the substitutiongroup references in notargetnamespace + testcase tc_substitutiongroup_notargetnamespace() runs on xmlTest_CT { + + //f_shellCommandWithVerdict("xsd2ttcn substitutiongroup_notargetnamespace.xsd","",c_shell_successWithoutWarningAndError) + setverdict(pass); + + }//tc_ + testcase tc_substitutiongroup_neg() runs on xmlTest_CT { f_shellCommandWithVerdict("xsd2ttcn substitutiongroup_neg.xsd","",c_shell_error) @@ -2065,7 +2096,7 @@ group Elements{ testcase tc_substitutiongroup_diff_module() runs on xmlTest_CT { - f_shellCommandWithVerdict("xsd2ttcn substitutiongroup_main.xsd substitutiongroup_ref.xsd","",c_shell_successWithWarning) + f_shellCommandWithVerdict("xsd2ttcn substitutiongroup_main.xsd substitutiongroup_ref.xsd","",c_shell_successWithoutWarningAndError) if(getverdict==pass) { f_compareFiles( @@ -2081,6 +2112,161 @@ group Elements{ }//tc_ + testcase tc_substitutiongroup_rename() runs on xmlTest_CT { + + f_shellCommandWithVerdict("xsd2ttcn substitutiongroup_rename.xsd","",c_shell_successWithoutWarningAndError) + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_substitutiongroup_rename_e.ttcn", + "www_example_org_substitutiongroup_rename.ttcn", c_numOfDiff_headerModNameAndNamespace); + } + + }//tc_ + + testcase tc_substitutiongroup_endDec() runs on xmlTest_CT { + + f_encDecTest_ize_subs(); + } + + testcase tc_type_substitution() runs on xmlTest_CT { + + f_shellCommandWithVerdict("xsd2ttcn -h type_substitution.xsd","",c_shell_successWithoutWarningAndError) + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_type_substitution_e.ttcn", + "www_example_org_type_substitution.ttcn", c_numOfDiff_headerModNameAndNamespace); + } + + }//tc_ + + testcase tc_type_substitution_encDec() runs on xmlTest_CT { + + f_encDecTest_type_subs(); + + }//tc_ + + testcase tc_type_substitution_chain() runs on xmlTest_CT { + + f_shellCommandWithVerdict("xsd2ttcn -h type_substitution_chain.xsd","",c_shell_successWithoutWarningAndError) + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_type_substitution_chain_e.ttcn", + "www_example_org_type_substitution_chain.ttcn", c_numOfDiff_headerModNameAndNamespace); + } + + }//tc_ + + testcase tc_type_substitution_abstract_block() runs on xmlTest_CT { + + f_shellCommandWithVerdict("xsd2ttcn -h type_substitution_abstract_block.xsd","",c_shell_successWithoutWarningAndError) + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_type_substitution_abstract_block_e.ttcn", + "www_example_org_type_substitution_abstract_block.ttcn", c_numOfDiff_headerModNameAndNamespace); + } + + }//tc_ + + testcase tc_type_substitution_diff_module() runs on xmlTest_CT { + + f_shellCommandWithVerdict("xsd2ttcn -h type_substitution_mod1.xsd type_substitution_mod2.xsd","",c_shell_successWithoutWarningAndError) + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_type_substitution_mod1_e.ttcn", + "www_example_org_type_substitution_mod1.ttcn", c_numOfDiff_headerModNameAndNamespace); + } + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_type_substitution_mod2_e.ttcn", + "www_example_org_type_substitution_mod2.ttcn", c_numOfDiff_headerModNameAndNamespace); + } + + }//tc_ + + testcase tc_type_substitution_simpletype() runs on xmlTest_CT { + + f_shellCommandWithVerdict("xsd2ttcn -h type_substitution_simpletype.xsd","",c_shell_successWithoutWarningAndError) + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_type_substitution_simpletype_e.ttcn", + "www_example_org_type_substitution_simpletype.ttcn", c_numOfDiff_headerModNameAndNamespace); + } + + }//tc_ + + testcase tc_type_substitution_with_elem_substitution() runs on xmlTest_CT { + + f_shellCommandWithVerdict("xsd2ttcn -h type_subs_with_elem_subs.xsd","",c_shell_successWithoutWarningAndError) + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_type_subs_with_elem_subs_e.ttcn", + "www_example_org_type_subs_with_elem_subs.ttcn", c_numOfDiff_headerModNameAndNamespace); + } + + }//tc_ + + testcase tc_type_substitution_element_in_ct() runs on xmlTest_CT { + + f_shellCommandWithVerdict("xsd2ttcn -h type_substitution_elem_in_ct_mod1.xsd type_substitution_elem_in_ct_mod2.xsd","",c_shell_successWithoutWarningAndError) + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_type_substitution_elem_in_ct_mod1_e.ttcn", + "www_example_org_type_substitution_elem_in_ct_mod1.ttcn", c_numOfDiff_headerModNameAndNamespace); + } + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_type_substitution_elem_in_ct_mod2_e.ttcn", + "www_example_org_type_substitution_elem_in_ct_mod2.ttcn", c_numOfDiff_headerModNameAndNamespace); + } + + }//tc_ + + testcase tc_only_element_substitution() runs on xmlTest_CT { + + f_shellCommandWithVerdict("xsd2ttcn -h only_element_substitution.xsd","",c_shell_successWithoutWarningAndError) + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_only_element_substitution_e.ttcn", + "www_example_org_only_element_substitution.ttcn", c_numOfDiff_headerModNameAndNamespace); + } + + }//tc_ + + testcase tc_type_substitution_builtintype() runs on xmlTest_CT { + + f_shellCommandWithVerdict("xsd2ttcn -h type_substitution_builtintype.xsd","",c_shell_successWithoutWarningAndError) + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_type_substitution_builtintype_e.ttcn", + "www_example_org_type_substitution_builtintype.ttcn", c_numOfDiff_headerModNameAndNamespace); + } + + }//tc_ + + testcase tc_type_substitution_rename() runs on xmlTest_CT { + + f_shellCommandWithVerdict("xsd2ttcn -h type_substitution_rename.xsd","",c_shell_successWithoutWarningAndError) + + if(getverdict==pass) { + f_compareFiles( + "www_example_org_type_substitution_rename_e.ttcn", + "www_example_org_type_substitution_rename.ttcn", c_numOfDiff_headerModNameAndNamespace); + } + + }//tc_ + //======================================================== @@ -2111,7 +2297,7 @@ group Elements{ //"Abstract" are not supported. Therefore converter sends WARNINGs testcase tc_element_abstract_conv() runs on xmlTest_CT { - f_shellCommandWithVerdict("xsd2ttcn XmlTest_element_abstract.xsd","",c_shell_successWithWarning); + f_shellCommandWithVerdict("xsd2ttcn XmlTest_element_abstract.xsd","",c_shell_successWithoutWarningAndError); }//tc_ testcase tc_element_nillable_converter() runs on xmlTest_CT { @@ -2396,12 +2582,30 @@ control { //===substitutiongroup=== execute(tc_substitutiongroup()); + execute(tc_substitutiongroup_name_as()); execute(tc_substitutiongroup_abstract_block_rest()); execute(tc_substitutiongroup_abstract_block_ext()); execute(tc_substitutiongroup_complex_without_element()); execute(tc_substitutiongroup_long_extension()); + execute(tc_substitutiongroup_complextype_block()); + execute(tc_substitutiongroup_notargetnamespace()); execute(tc_substitutiongroup_neg()); execute(tc_substitutiongroup_diff_module()); + execute(tc_substitutiongroup_rename()); + execute(tc_substitutiongroup_endDec()); + + //===type substitution=== + execute(tc_type_substitution()); + execute(tc_type_substitution_encDec()); + execute(tc_type_substitution_chain()); + execute(tc_type_substitution_abstract_block()); + execute(tc_type_substitution_diff_module()); + execute(tc_type_substitution_simpletype()); + execute(tc_type_substitution_with_elem_substitution()); + execute(tc_type_substitution_element_in_ct()); + execute(tc_only_element_substitution()); + execute(tc_type_substitution_builtintype()); + execute(tc_type_substitution_rename()); diff --git a/regression_test/XML/XmlWorkflow/xsd/only_element_substitution.xsd b/regression_test/XML/XmlWorkflow/xsd/only_element_substitution.xsd new file mode 100644 index 0000000..dd6f195 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/only_element_substitution.xsd @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regression_test/XML/XmlWorkflow/xsd/substitutiongroup.xsd b/regression_test/XML/XmlWorkflow/xsd/substitutiongroup.xsd index 64d9fa3..475238d 100644 --- a/regression_test/XML/XmlWorkflow/xsd/substitutiongroup.xsd +++ b/regression_test/XML/XmlWorkflow/xsd/substitutiongroup.xsd @@ -1,14 +1,14 @@ - + @@ -18,7 +18,7 @@ - + @@ -30,13 +30,13 @@ - + - + diff --git a/regression_test/XML/XmlWorkflow/xsd/substitutiongroup_complextype_block.xsd b/regression_test/XML/XmlWorkflow/xsd/substitutiongroup_complextype_block.xsd new file mode 100644 index 0000000..6dce974 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/substitutiongroup_complextype_block.xsd @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regression_test/XML/XmlWorkflow/xsd/substitutiongroup_name_as.xsd b/regression_test/XML/XmlWorkflow/xsd/substitutiongroup_name_as.xsd new file mode 100644 index 0000000..66c477c --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/substitutiongroup_name_as.xsd @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regression_test/XML/XmlWorkflow/xsd/substitutiongroup_notargetnamespace.xsd b/regression_test/XML/XmlWorkflow/xsd/substitutiongroup_notargetnamespace.xsd new file mode 100644 index 0000000..9ebe84c --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/substitutiongroup_notargetnamespace.xsd @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regression_test/XML/XmlWorkflow/xsd/substitutiongroup_rename.xsd b/regression_test/XML/XmlWorkflow/xsd/substitutiongroup_rename.xsd new file mode 100644 index 0000000..41f3f3c --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/substitutiongroup_rename.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regression_test/XML/XmlWorkflow/xsd/type_subs_with_elem_subs.xsd b/regression_test/XML/XmlWorkflow/xsd/type_subs_with_elem_subs.xsd new file mode 100644 index 0000000..133ed50 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/type_subs_with_elem_subs.xsd @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regression_test/XML/XmlWorkflow/xsd/type_substitution.xsd b/regression_test/XML/XmlWorkflow/xsd/type_substitution.xsd new file mode 100644 index 0000000..be29c5a --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/type_substitution.xsd @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regression_test/XML/XmlWorkflow/xsd/type_substitution_abstract_block.xsd b/regression_test/XML/XmlWorkflow/xsd/type_substitution_abstract_block.xsd new file mode 100644 index 0000000..aba5a9a --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/type_substitution_abstract_block.xsd @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regression_test/XML/XmlWorkflow/xsd/type_substitution_builtintype.xsd b/regression_test/XML/XmlWorkflow/xsd/type_substitution_builtintype.xsd new file mode 100644 index 0000000..25c26cc --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/type_substitution_builtintype.xsd @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regression_test/XML/XmlWorkflow/xsd/type_substitution_chain.xsd b/regression_test/XML/XmlWorkflow/xsd/type_substitution_chain.xsd new file mode 100644 index 0000000..21cb42a --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/type_substitution_chain.xsd @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regression_test/XML/XmlWorkflow/xsd/type_substitution_elem_in_ct_mod1.xsd b/regression_test/XML/XmlWorkflow/xsd/type_substitution_elem_in_ct_mod1.xsd new file mode 100644 index 0000000..af179c3 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/type_substitution_elem_in_ct_mod1.xsd @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regression_test/XML/XmlWorkflow/xsd/type_substitution_elem_in_ct_mod2.xsd b/regression_test/XML/XmlWorkflow/xsd/type_substitution_elem_in_ct_mod2.xsd new file mode 100644 index 0000000..ec48b91 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/type_substitution_elem_in_ct_mod2.xsd @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + diff --git a/regression_test/XML/XmlWorkflow/xsd/type_substitution_mod1.xsd b/regression_test/XML/XmlWorkflow/xsd/type_substitution_mod1.xsd new file mode 100644 index 0000000..2262c1f --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/type_substitution_mod1.xsd @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regression_test/XML/XmlWorkflow/xsd/type_substitution_mod2.xsd b/regression_test/XML/XmlWorkflow/xsd/type_substitution_mod2.xsd new file mode 100644 index 0000000..f0c6336 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/type_substitution_mod2.xsd @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regression_test/XML/XmlWorkflow/xsd/type_substitution_rename.xsd b/regression_test/XML/XmlWorkflow/xsd/type_substitution_rename.xsd new file mode 100644 index 0000000..11876eb --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/type_substitution_rename.xsd @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regression_test/XML/XmlWorkflow/xsd/type_substitution_simpletype.xsd b/regression_test/XML/XmlWorkflow/xsd/type_substitution_simpletype.xsd new file mode 100644 index 0000000..5d87543 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/type_substitution_simpletype.xsd @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regression_test/compileonly/openTypeNames/IO_based_message.asn b/regression_test/compileonly/openTypeNames/IO_based_message.asn index 56071bb..daa7985 100644 --- a/regression_test/compileonly/openTypeNames/IO_based_message.asn +++ b/regression_test/compileonly/openTypeNames/IO_based_message.asn @@ -35,9 +35,11 @@ myIo2 MY-CLASS ::= { ID 2 TYPE MyEnum } myIo3 MY-CLASS ::= { ID 3 TYPE INTEGER } +myIo4 MY-CLASS ::= { ID 4 TYPE NULL } + -- Defining IO set to be used in message contraction -MyIOSet MY-CLASS ::= { myIo1 | myIo2 | myIo3 } +MyIOSet MY-CLASS ::= { myIo1 | myIo2 | myIo3 | myIo4 } -- and now finally constructing the type @@ -66,6 +68,11 @@ a-message-id3-lower MyMessage ::= { id 3, content iNTEGER : 7 } + +a-message-id4-lower MyMessage ::= { + id 4, + content nULL : NULL +} /* -- Not supported values a-message-id1-upper MyMessage ::= { @@ -82,5 +89,10 @@ a-message-id3-upper MyMessage ::= { id 3, content INTEGER : 7 } + +a-message-id4-lower MyMessage ::= { + id 4, + content NULL : NULL +} */ END diff --git a/regression_test/compileonly/openTypeNames/Open_type_use.ttcn b/regression_test/compileonly/openTypeNames/Open_type_use.ttcn index 75f6937..4761fc8 100644 --- a/regression_test/compileonly/openTypeNames/Open_type_use.ttcn +++ b/regression_test/compileonly/openTypeNames/Open_type_use.ttcn @@ -28,6 +28,11 @@ const MyMessage c_message_id3_lower := { content := { iNTEGER := 42 } } +const MyMessage c_message_id4_lower := { + id := 4, + content := { nULL := NULL } +} + // Constants (uppercase first letter) const MyMessage c_message_id1_upper := { id := 1, @@ -44,6 +49,11 @@ const MyMessage c_message_id3_upper := { content := { INTEGER := 42 } } +const MyMessage c_message_id4_upper := { + id := 4, + content := { NULL := NULL } +} + // Templates (lowercase first letter) template MyMessage t_message_id1_lower := { id := 1, @@ -60,6 +70,11 @@ template MyMessage t_message_id3_lower := { content := { iNTEGER := 42 } } +template MyMessage t_message_id4_lower := { + id := 4, + content := { nULL := NULL } +} + // Templates (uppercase first letter) template MyMessage t_message_id1_upper := { id := 1, @@ -76,14 +91,21 @@ template MyMessage t_message_id3_upper := { content := { INTEGER := 42 } } +template MyMessage t_message_id4_upper := { + id := 4, + content := { NULL := NULL } +} + // Value list template (contains both lowercase and uppercase examples) template MyMessage t_message_value_list := ( { id := 1, content := { mySeq := { field1 := 42, field2 := omit }} }, { id := 2, content := { myEnum := first} }, { id := 3, content := { iNTEGER := 42 } }, + { id := 4, content := { nULL := NULL } }, { id := 1, content := { MySeq := { field1 := -42, field2 := omit }} }, { id := 2, content := { MyEnum := second} }, - { id := 3, content := { INTEGER := -42 } } + { id := 3, content := { INTEGER := -42 } }, + { id := 4, content := { NULL := NULL } } ); // Dummy function to declare variables in @@ -103,6 +125,11 @@ function f_dummy() { id := 3, content := { iNTEGER := 42 } } + + var MyMessage v_message_id4_lower := { + id := 4, + content := { nULL := NULL } + } // Variables (uppercase first letter) var MyMessage v_message_id1_upper := { @@ -119,6 +146,11 @@ function f_dummy() { id := 3, content := { INTEGER := 42 } } + + var MyMessage v_message_id4_upper := { + id := 4, + content := { NULL := NULL } + } // Template variables (lowercase first letter) var template MyMessage vt_message_id1_lower := { @@ -135,6 +167,11 @@ function f_dummy() { id := 3, content := { iNTEGER := 42 } } + + var template MyMessage vt_message_id4_lower := { + id := 4, + content := { nULL := NULL } + } // Template variables (uppercase first letter) var template MyMessage vt_message_id1_upper := { @@ -152,14 +189,21 @@ function f_dummy() { content := { INTEGER := 42 } } + var template MyMessage vt_message_id4_upper := { + id := 4, + content := { NULL := NULL } + } + // Value list template variable (contains both lowercase and uppercase examples) var template MyMessage vt_message_value_list := ( { id := 1, content := { mySeq := { field1 := 42, field2 := omit }} }, { id := 2, content := { myEnum := first} }, { id := 3, content := { iNTEGER := 42 } }, + { id := 4, content := { nULL := NULL } }, { id := 1, content := { MySeq := { field1 := -42, field2 := omit }} }, { id := 2, content := { MyEnum := second} }, - { id := 3, content := { INTEGER := -42 } } + { id := 3, content := { INTEGER := -42 } }, + { id := 4, content := { NULL := NULL } } ); // Referencing fields of open types (contains both lowercase and uppercase examples) @@ -169,18 +213,24 @@ function f_dummy() { v_message_id2_upper.content.MyEnum := second; v_message_id3_lower.content.iNTEGER := 15; v_message_id3_upper.content.INTEGER := 15; + v_message_id4_lower.content.nULL := NULL; + v_message_id4_upper.content.NULL := NULL; vt_message_id1_lower.content.mySeq := { field1 := 41, field2 := omit }; vt_message_id1_upper.content.MySeq := { field1 := 41, field2 := omit }; vt_message_id2_lower.content.myEnum := second; vt_message_id2_upper.content.MyEnum := second; vt_message_id3_lower.content.iNTEGER := 15; vt_message_id3_upper.content.INTEGER := 15; + vt_message_id4_lower.content.nULL := NULL; + vt_message_id4_upper.content.NULL := NULL; if (c_message_id1_lower.content.mySeq == { field1 := 41, field2 := omit } and c_message_id1_upper.content.MySeq == { field1 := 41, field2 := omit } and c_message_id2_lower.content.myEnum == second and c_message_id2_upper.content.MyEnum == second and c_message_id3_lower.content.iNTEGER == 15 and - c_message_id3_upper.content.INTEGER == 15) { + c_message_id3_upper.content.INTEGER == 15 and + c_message_id4_lower.content.nULL == NULL and // NULL != NULL !? + c_message_id4_upper.content.NULL == NULL) { log("a"); } if (v_message_id1_lower.content.mySeq == { field1 := 41, field2 := omit } and @@ -188,7 +238,9 @@ function f_dummy() { v_message_id2_lower.content.myEnum == second and v_message_id2_upper.content.MyEnum == second and v_message_id3_lower.content.iNTEGER == 15 and - v_message_id3_upper.content.INTEGER == 15) { + v_message_id3_upper.content.INTEGER == 15 and + v_message_id4_lower.content.nULL == NULL and + v_message_id4_upper.content.NULL == NULL) { log("b"); } if (match({ field1 := 41, field2 := omit }, t_message_id1_lower.content.mySeq) and @@ -196,7 +248,9 @@ function f_dummy() { match(second, t_message_id2_lower.content.myEnum) and match(second, t_message_id2_lower.content.MyEnum) and match(15, t_message_id3_lower.content.iNTEGER) and - match(15, t_message_id3_lower.content.INTEGER)) { + match(15, t_message_id3_lower.content.INTEGER) and + match(NULL, t_message_id4_lower.content.nULL) and + match(NULL, t_message_id4_lower.content.NULL)) { log("c"); } if (match({ field1 := 41, field2 := omit }, vt_message_id1_upper.content.mySeq) and @@ -204,7 +258,9 @@ function f_dummy() { match(second, vt_message_id2_upper.content.myEnum) and match(second, vt_message_id2_upper.content.MyEnum) and match(15, vt_message_id3_upper.content.iNTEGER) and - match(15, vt_message_id3_upper.content.INTEGER)) { + match(15, vt_message_id3_upper.content.INTEGER) and + match(NULL, vt_message_id4_upper.content.nULL) and + match(NULL, vt_message_id4_upper.content.NULL)) { log("d"); } } diff --git a/regression_test/logFiles/logfilter.sh b/regression_test/logFiles/logfilter.sh index 33e571a..51ffe4e 100755 --- a/regression_test/logFiles/logfilter.sh +++ b/regression_test/logFiles/logfilter.sh @@ -11,7 +11,7 @@ LOGFILE="lfilter.log2" FILTERED_LOG_FILE="filtered.log" EXPECTED_LOG_FILE="filtered_e.log2" -ttcn3_logfilter -o $FILTERED_LOG_FILE $LOGFILE MATCHING+ PARALLEL+ +../../Install/bin/ttcn3_logfilter -o $FILTERED_LOG_FILE $LOGFILE MATCHING+ PARALLEL+ diff $FILTERED_LOG_FILE $EXPECTED_LOG_FILE if [ $? -ne 0 ]; then echo "Logfilter test failed! Overall verdict: fail" diff --git a/regression_test/negativeTest/NegTest_RAW_Testcases.ttcn b/regression_test/negativeTest/NegTest_RAW_Testcases.ttcn index 301809a..e958a3a 100644 --- a/regression_test/negativeTest/NegTest_RAW_Testcases.ttcn +++ b/regression_test/negativeTest/NegTest_RAW_Testcases.ttcn @@ -2734,7 +2734,7 @@ group SetOf { //====set of related templates==== var RawSetOfRawUnionBT32 vl_expected :={ {r:="\x01\x01\xFF"}, {i:=2}, {b:=true}}; // oct2char('0101FF'O) f_compareAndVerdict( encode_rawSetOfInt32(valueof(t_msetofiValueDiffTypeRaw(1,2,3))), - '0101FF02000000FF'O); + '0101FF0200000001'O); f_compareAndVerdict( encode_rawSetOfInt32(valueof(t_msetofiValueDiffTypeRaw(1,2,3))), encode_rawSetOfRawUnionBT32( vl_expected )); @@ -2836,8 +2836,8 @@ group SetOf { //====set of related templates==== f_compareAndVerdict( actual, '0101FF'O // first raw value - & 'FE'O); // bottom 2 bits: '10'B for second; top 6 bits '111111'B for true - //'FE'O = bit2oct('111111'B & '10'B) + & '06'O); // bottom 2 bits: '10'B for second, 3rd bit is '1'B for true, top 5 bits are '00000'B (filler zeros) + //'06'O = bit2oct('00000'B & '1'B & '10'B) var RawSetOfRawUnionBT vl_expected :={ {os:='0101FF'O}, {e:=second}, {b:=true}}; var octetstring expected := encode_rawSetOfRawUnionBT(vl_expected); f_compareAndVerdict(actual, expected); @@ -2921,7 +2921,7 @@ group SetOf { //====set of related templates==== //var RawSetOfRawUnionBT vl_expected :={ {b:=true}, {r:="Two"}, {b:=true}}; f_compareAndVerdict( encode_rawSetOfCharstring(valueof(t_msetofrValueDiffTypeRaw("One", "Two", "Three"))), - '0101FF'O & char2oct("Two") & 'FF'O + '0101FF'O & char2oct("Two") & '01'O ); //'0101FF'O //encode_rawSetOfRawUnionBT( vl_expected )); } @@ -3003,7 +3003,7 @@ group Union { testcase tc_rawUnionBasicTypes_boolean3() runs on RawComp { //0. just for fun: var RawUnionBasicTypesT vl_mubt:={b:=true}; - f_compareAndVerdict(encode_rawUnionBasicTypesT(vl_mubt), 'FF'O); + f_compareAndVerdict(encode_rawUnionBasicTypesT(vl_mubt), '01'O); //1. vl_mubt:={b:=false}; f_compareAndVerdict( diff --git a/regression_test/templateInt/ImportedTemplates.ttcn b/regression_test/templateInt/ImportedTemplates.ttcn new file mode 100644 index 0000000..f5d1a76 --- /dev/null +++ b/regression_test/templateInt/ImportedTemplates.ttcn @@ -0,0 +1,12 @@ +/****************************************************************************** + * 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 ImportedTemplates { + +template integer tImported(template integer pt) := pt; + +} diff --git a/regression_test/templateInt/Makefile b/regression_test/templateInt/Makefile index 0080b67..870edf0 100644 --- a/regression_test/templateInt/Makefile +++ b/regression_test/templateInt/Makefile @@ -13,7 +13,7 @@ include $(TOPDIR)/Makefile.regression TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX) -TTCN3_MODULES = TtemplateInt.ttcn +TTCN3_MODULES = TtemplateInt.ttcn ImportedTemplates.ttcn GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc) GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh) @@ -30,8 +30,8 @@ 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) -.ttcn.cc .ttcn.hh: - $(TTCN3_COMPILER) $< +$(GENERATED_SOURCES) $(GENERATED_HEADERS): $(TTCN3_MODULES) + $(TTCN3_COMPILER) $^ clean distclean: -rm -f $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \ diff --git a/regression_test/templateInt/TtemplateInt.ttcn b/regression_test/templateInt/TtemplateInt.ttcn index 2634110..d29edeb 100644 --- a/regression_test/templateInt/TtemplateInt.ttcn +++ b/regression_test/templateInt/TtemplateInt.ttcn @@ -7,6 +7,8 @@ ******************************************************************************/ module TtemplateInt { +import from ImportedTemplates all; + type component templateInt_mycomp {}; type record templateInt_rec { integer x1, @@ -288,6 +290,53 @@ testcase templateIntSubtype() runs on templateInt_mycomp { setverdict(pass); } +// test case: using a parameterized template with no actual parameters (using default values) +// before its declaration +template integer tReverse := tPard; + +template integer tPard(integer p := 6) := p; + +testcase templateIntReverseOrder() runs on templateInt_mycomp { + var template integer vtExpected := 6; + if (log2str(tReverse) == log2str(vtExpected)) { + setverdict(pass); + } + else { + setverdict(fail, "Expected: ", vtExpected, ", got: ", tReverse); + } +} + +// same test, but the parameterized template is passed as a parameter to +// an imported parameterized template +template integer tReverse2 := tImported(tPard2); + +template integer tPard2(integer p := 4) := p; + +testcase templateIntReverseOrderImported() runs on templateInt_mycomp { + var template integer vtExpected := 4; + if (log2str(tReverse2) == log2str(vtExpected)) { + setverdict(pass); + } + else { + setverdict(fail, "Expected: ", vtExpected, ", got: ", tReverse2); + } +} + +// same as the previous test, but with a non-parameterized template +template integer tReverse3 := tImported(tNonPard); + +template integer tNonPard := (1, 2); + +testcase templateIntReverseOrderImported2() runs on templateInt_mycomp { + var template integer vtExpected := (1, 2); + if (log2str(tReverse3) == log2str(vtExpected)) { + setverdict(pass); + } + else { + setverdict(fail, "Expected: ", vtExpected, ", got: ", tReverse3); + } +} + control { execute(templateIntSpec()); execute(templateIntList()); @@ -302,5 +351,8 @@ control { execute(templateIntIfpresent()); execute(TR_HJ94652()); execute(templateIntSubtype()); + execute(templateIntReverseOrder()); + execute(templateIntReverseOrderImported()); + execute(templateIntReverseOrderImported2()); } } diff --git a/usrguide/referenceguide.doc b/usrguide/referenceguide.doc index 3c41ef9f03979bbbb8dc375cfb6d217fe698dab7..2caa8bffd6aa97f412d5f94f9afc6619b963188d 100644 GIT binary patch delta 137173 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 delta 136393 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�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 zusHpbYW>!zreplaceLastMainType(this); module->setActualXsdConstruct(c_complexType); } @@ -159,18 +159,32 @@ ComplexType::ComplexType(const SimpleType & other, CT_fromST c) type.upload(Mstring("record")); xsdtype = n_complexType; break; - case fromTagSubstition: + case fromTagSubstitution: type.upload(Mstring("union")); name.upload(getName().originalValueWoPrefix + Mstring("_group")); xsdtype = n_union; subsGroup = this; variant.clear(); + hidden_variant.clear(); enumeration.modified = false; value.modified = false; pattern.modified = false; length.modified = false; whitespace.modified = false; break; + case fromTypeSubstitution: + type.upload(Mstring("union")); + name.upload(getName().originalValueWoPrefix + Mstring("_derivations")); + xsdtype = n_union; + substitutionGroup = empty_string; + typeSubsGroup = this; + variant.clear(); + hidden_variant.clear(); + enumeration.modified = false; + value.modified = false; + pattern.modified = false; + length.modified = false; + whitespace.modified = false; } } @@ -634,7 +648,7 @@ void ComplexType::referenceResolving() { reference_resolving_funtion(); - if(!substitionGroup.empty()){ + if(!substitutionGroup.empty()){ addToSubstitutions(); } resolved = Yes; @@ -643,6 +657,11 @@ void ComplexType::referenceResolving() { void ComplexType::reference_resolving_funtion() { //Every child element references are resolved here. if (outside_reference.empty() && basefield == NULL) { + //Its not in the resolveElement function because we need the built in type + //reference too, and then the outside_reference is empty. + if(xsdtype == n_element){ + collectElementTypes(NULL, NULL); + } return; } @@ -671,6 +690,8 @@ void ComplexType::reference_resolving_funtion() { resolveUnion(st); + addToTypeSubstitutions(); + } void ComplexType::setParent(ComplexType * par, SimpleType * child) { @@ -679,7 +700,7 @@ void ComplexType::setParent(ComplexType * par, SimpleType * child) { void ComplexType::applyReference(const SimpleType & other, const bool on_attributes) { type.convertedValue = other.getType().convertedValue; - type.originalValueWoPrefix = other.getType().convertedValue; + type.originalValueWoPrefix = other.getType().convertedValue.getValueWithoutPrefix(':'); if (other.getMinOccurs() > minOccurs || other.getMaxOccurs() < maxOccurs) { if (!on_attributes) { @@ -1005,7 +1026,7 @@ void ComplexType::finalModification2() { } //Substitution group ordering - if(subsGroup == this){ //We are a generated substitution group + if(subsGroup == this || typeSubsGroup == this){ //We are a generated substitution group //Substitution group never empty ComplexType * front = complexfields.front(); List::iterator it = complexfields.begin(); @@ -1209,6 +1230,9 @@ void ComplexType::collectVariants(List& container) { if (useUnionVariantWhenMainTypeIsRecordOf) { container.push_back(Mstring("variant ([-]) \"useUnion\";\n")); } + for (List::iterator var = hidden_variant.end(); var; var = var->Prev) { + container.push_back(Mstring("//variant ") + Mstring(var->Data.c_str()) + Mstring(";\n")); + } } //Collect variants of attributes @@ -1557,9 +1581,9 @@ void ComplexType::resolveAttribute(AttributeType* attr) { } else { attr->setTypeOfField(st->getName().convertedValue); if (st->getType().convertedValue == "record" || st->getType().convertedValue == "union") { - st->addToNameDepList(attr); + st->addToNameDepList(attr); + } } - } } else { printError(module->getSchemaname(), name.convertedValue, "Reference for a non-defined type: " + attr->getReference().repr()); @@ -1681,17 +1705,25 @@ void ComplexType::resolveElement(SimpleType *st) { if (xsdtype == n_element && !outside_reference.empty()) { outside_reference.set_resolved(st); type.upload(st->getModule()->getTargetNamespaceConnector() + Mstring(":") + st->getName().convertedValue); - st->addToNameDepList(this); - nameDep = st; if (name.originalValueWoPrefix.empty()) { name.upload(st->getName().convertedValue); } if (fromRef) { addNameSpaceAsVariant(this, st); } + + collectElementTypes(st, NULL); + + //Namedep is added to the substitutions, if any if(st->getSubstitution() != NULL){ st->getSubstitution()->addToNameDepList(this); nameDep = st->getSubstitution(); + }if(st->getTypeSubstitution() != NULL){ + st->getTypeSubstitution()->addToNameDepList(this); + nameDep = st->getTypeSubstitution(); + }else { + st->addToNameDepList(this); + nameDep = st; } } } @@ -1717,8 +1749,8 @@ void ComplexType::resolveSimpleTypeExtension() { st->referenceResolving(); } st->addToNameDepList(basefield); - addNameSpaceAsVariant(basefield, st); basefield->nameDep = st; + addNameSpaceAsVariant(basefield, st); } } else if(!isBuiltInType(basefield->getType().convertedValue)){ printError(module->getSchemaname(), name.convertedValue, @@ -1915,21 +1947,28 @@ void ComplexType::modifyAttributeParent() { } } -void ComplexType::addSubstitution(SimpleType* st){ +//Element substitution +void ComplexType::addSubstitution(SimpleType * st){ ComplexType * element; if(st->getXsdtype() == n_NOTSET || !complexfields.empty()){ - element = new ComplexType(*st, fromTagSubstition); + element = new ComplexType(*st, fromTagSubstitution); }else { element = new ComplexType(*(ComplexType*)st); element->variant.clear(); } element->subsGroup = this; element->parent = this; - if(complexfields.empty()){ //The first element(head) + if(complexfields.empty()){ //The first element(head) is the st element->setTypeValue(st->getType().convertedValue); if(st->hasVariant(Mstring("\"abstract\""))){ - element->addVariant(V_onlyValueHidden, Mstring("\"abstract\"")); + element->addVariant(V_abstract); + } + if(st->getReference().get_ref() != NULL){ + ((SimpleType*)st->getReference().get_ref())->addToNameDepList(element); + nameDep = ((SimpleType*)st->getReference().get_ref()); } + module->addElementType(element->getType().convertedValue, element); + element->addVariant(V_formAs, Mstring("qualified")); }else { Mstring newType; if(st->getType().convertedValue == "anyType"){ @@ -1937,16 +1976,18 @@ void ComplexType::addSubstitution(SimpleType* st){ }else { newType = st->getName().convertedValue; st->addToNameDepList(element); + element->nameDep = st; } element->setTypeValue(newType); BlockValue front_block = complexfields.front()->getBlock(); if(front_block == all || front_block == substitution){ - element->addVariant(V_onlyValueHidden, Mstring("\"block\"")); + element->addVariant(V_block); }else if(front_block == restriction || front_block == extension){ const Mstring& head_type = complexfields.front()->getType().convertedValue.getValueWithoutPrefix(':'); + //To decide if they came from a common ancestor Mstring elem_type = findRoot(front_block, st, head_type, true); if(head_type == elem_type){ - element->addVariant(V_onlyValueHidden, Mstring("\"block\"")); + element->addVariant(V_block); } } } @@ -1956,11 +1997,56 @@ void ComplexType::addSubstitution(SimpleType* st){ complexfields.push_back(element); } +void ComplexType::addTypeSubstitution(SimpleType * st){ + ComplexType * element; + if(st->getXsdtype() == n_NOTSET || !complexfields.empty()){ + element = new ComplexType(*st, fromTypeSubstitution); + }else { + //Only need a plain complextype + //Head element + element = new ComplexType(this); + //Just the block needed from st + element->block = st->getBlock(); + } + st->addToNameDepList(element); + element->nameDep = st; + element->typeSubsGroup = this; + element->parent = this; + if(complexfields.empty()){ //The first element(head) is the st + if(st->hasVariant(Mstring("\"abstract\""))){ + element->addVariant(V_abstract); + } + }else { + BlockValue front_block = complexfields.front()->getBlock(); + if(front_block == all){ + element->addVariant(V_block); + }else if(front_block == restriction || front_block == extension){ + const Mstring& head_type = complexfields.front()->getType().convertedValue.getValueWithoutPrefix(':'); + //To decide if they came from a common ancestor + Mstring elem_type = findRoot(front_block, st, head_type, true); + if(head_type == elem_type){ + element->addVariant(V_block); + } + } + } + element->top = false; + complexfields.push_back(element); + element->setTypeValue(st->getName().convertedValue.getValueWithoutPrefix(':')); + element->setNameValue(st->getName().convertedValue.getValueWithoutPrefix(':')); +} + Mstring ComplexType::findRoot(const BlockValue block_value, SimpleType* elem, const Mstring& head_type, const bool first){ - if(!first && elem->getType().convertedValue.getValueWithoutPrefix(':') == head_type && !isFromRef()){ - return elem->getType().convertedValue.getValueWithoutPrefix(':'); - }else if(elem->getType().convertedValue.getValueWithoutPrefix(':') == head_type && (isFromRef() && ((elem->getMode() == restrictionMode && block_value == restriction) || (elem->getMode() == extensionMode && block_value == extension)))){ - return elem->getType().convertedValue.getValueWithoutPrefix(':'); + const Mstring elemName = elem->getName().convertedValue.getValueWithoutPrefix(':'); + const Mstring elemType = elem->getType().convertedValue.getValueWithoutPrefix(':'); + + if(!first && !isFromRef() && elemType == head_type){ + return elemType; + }else if((isFromRef() && + ((elem->getMode() == restrictionMode && block_value == restriction) || + (elem->getMode() == extensionMode && block_value == extension))) && elemType == head_type){ + return elemType; + }else if(!first && elemName == head_type){ + return elemName; }else { SimpleType * st = NULL; if((elem->getMode() == restrictionMode && block_value == restriction) || @@ -1987,7 +2073,7 @@ Mstring ComplexType::findRoot(const BlockValue block_value, SimpleType* elem, co } } if(elem->getMode() == noMode && !first){ - return elem->getType().convertedValue.getValueWithoutPrefix(':'); + return elemType; }else { return empty_string; } diff --git a/xsdconvert/ComplexType.hh b/xsdconvert/ComplexType.hh index e310e32..c6918e6 100644 --- a/xsdconvert/ComplexType.hh +++ b/xsdconvert/ComplexType.hh @@ -43,7 +43,8 @@ public: fromTagUnion, fromTagNillable, fromTagComplexType, - fromTagSubstition + fromTagSubstitution, + fromTypeSubstitution }; enum Resolv_State { @@ -115,7 +116,8 @@ public: ~ComplexType(); void modifyAttributeParent(); - void addSubstitution(SimpleType* st); + void addSubstitution(SimpleType * st); + void addTypeSubstitution(SimpleType * st); /** Virtual methods * inherited from RootType @@ -130,6 +132,7 @@ public: void nameConversion(NameConversionMode mode, const List & ns); void finalModification(); bool hasUnresolvedReference(){ return resolved == No; } + void setNameDep(SimpleType * dep) { nameDep = dep; } void dump(unsigned int depth) const; diff --git a/xsdconvert/Makefile b/xsdconvert/Makefile index e77d3f2..7789389 100644 --- a/xsdconvert/Makefile +++ b/xsdconvert/Makefile @@ -64,6 +64,10 @@ endif # libraries for the linker LDLIBS += -lxml2 -lcrypto +ifdef MINGW +LDLIBS += -lregex +endif + all run: $(TARGETS) $(PROGRAMS) xsd2ttcn$(EXESUFFIX): $(OBJECTS) diff --git a/xsdconvert/RootType.cc b/xsdconvert/RootType.cc index f80a19a..a01a45c 100644 --- a/xsdconvert/RootType.cc +++ b/xsdconvert/RootType.cc @@ -149,6 +149,9 @@ void RootType::addVariant(const VariantMode var, const Mstring& var_value, const case V_useOrder: variantstring = "\"useOrder\""; break; + case V_useType: + variantstring = "\"useType\""; + break; case V_useUnion: variantstring = "\"useUnion\""; break; @@ -242,5 +245,10 @@ bool RootType::hasVariant(const Mstring& var) const{ return true; } } + for(List::iterator vars = hidden_variant.begin(); vars; vars = vars->Next){ + if(vars->Data.isFound(var)){ + return true; + } + } return false; } \ No newline at end of file diff --git a/xsdconvert/RootType.hh b/xsdconvert/RootType.hh index 16a5f15..032a0ab 100644 --- a/xsdconvert/RootType.hh +++ b/xsdconvert/RootType.hh @@ -53,6 +53,7 @@ enum VariantMode { V_useNil, V_useNumber, V_useOrder, + V_useType, V_useUnion, V_whiteSpace, V_fractionDigits @@ -165,6 +166,10 @@ public: visible = false; } + void setVisible() { + visible = true; + } + const NameType & getName() const { return name; } @@ -209,6 +214,10 @@ public: return comment; } + List & getNameDepList() { + return nameDepList; + } + XMLParser * getParser() const { return parser; } diff --git a/xsdconvert/SimpleType.cc b/xsdconvert/SimpleType.cc index db39ef0..24dbdbd 100644 --- a/xsdconvert/SimpleType.cc +++ b/xsdconvert/SimpleType.cc @@ -14,6 +14,7 @@ #include "ComplexType.hh" extern bool g_flag_used; +extern bool h_flag_used; SimpleType::SimpleType(XMLParser * a_parser, TTCN3Module * a_module, ConstructType a_construct) : RootType(a_parser, a_module, a_construct) @@ -31,8 +32,10 @@ SimpleType::SimpleType(XMLParser * a_parser, TTCN3Module * a_module, ConstructTy , fromRef(false) , xsdtype(n_NOTSET) , isOptional(false) -, substitionGroup(empty_string) +, substitutionGroup(empty_string) , subsGroup(NULL) +, typeSubsGroup(NULL) +, addedToTypeSubstitution(false) , block(not_set) , parent(NULL) { } @@ -53,8 +56,10 @@ SimpleType::SimpleType(const SimpleType& other) , fromRef(other.fromRef) , xsdtype(other.xsdtype) , isOptional(other.isOptional) -, substitionGroup(other.substitionGroup) +, substitutionGroup(other.substitutionGroup) , subsGroup(other.subsGroup) +, typeSubsGroup(other.typeSubsGroup) +, addedToTypeSubstitution(other.addedToTypeSubstitution) , block(other.block) , parent(NULL) { length.parent = this; @@ -255,13 +260,13 @@ void SimpleType::applyNillableAttribute(const bool nillable) { void SimpleType::applyAbstractAttribute(const bool abstract_value) { if (abstract_value) { - addVariant(V_onlyValueHidden, Mstring("\"abstract\"")); + addVariant(V_abstract); } } -void SimpleType::applySubstitionGroupAttribute(const Mstring& substition_group){ - if(!substition_group.empty()){ - substitionGroup = substition_group; +void SimpleType::applySubstitionGroupAttribute(const Mstring& substitution_group){ + if(!substitution_group.empty()){ + substitutionGroup = substitution_group; } } @@ -274,15 +279,14 @@ void SimpleType::applyBlockAttribute(const BlockValue block_){ } void SimpleType::addToSubstitutions(){ - if(!g_flag_used){ + if(!g_flag_used || substitutionGroup.empty()){ return; } - SimpleType * st_ = (SimpleType*) TTCN3ModuleInventory::getInstance().lookup(this, substitionGroup, want_BOTH); + SimpleType * st_ = (SimpleType*) TTCN3ModuleInventory::getInstance().lookup(this, substitutionGroup, want_BOTH); if(st_ == NULL){ printError(module->getSchemaname(), name.convertedValue, - "Reference for a non-defined type: " + substitionGroup); + "Reference for a non-defined type: " + substitutionGroup); TTCN3ModuleInventory::getInstance().incrNumErrors(); - return; return; } SimpleType * st = (SimpleType*)st_; @@ -291,12 +295,12 @@ void SimpleType::addToSubstitutions(){ } st->referenceResolving(); - substitionGroup = empty_string; + substitutionGroup = empty_string; //Simpletype if(st->subsGroup == NULL){ - ComplexType * head_element = new ComplexType(*st, ComplexType::fromTagSubstition); + ComplexType * head_element = new ComplexType(*st, ComplexType::fromTagSubstitution); for(List::iterator simpletype = st->nameDepList.begin(); simpletype; simpletype = simpletype->Next){ - head_element->nameDepList.push_back(simpletype->Data); + head_element->getNameDepList().push_back(simpletype->Data); } st->nameDepList.clear(); st->getModule()->addMainType(head_element); @@ -311,6 +315,145 @@ void SimpleType::addToSubstitutions(){ } } +void SimpleType::addToTypeSubstitutions() { + //If the user did not request type substitution generation or + //the type is already added to type substitution + if(!h_flag_used || addedToTypeSubstitution){ + return; + } + //Only available if it is a restricion or extension + if(mode != extensionMode && mode != restrictionMode){ + return; + } + //Only top level complexTypes or simpleTypes, ergo no elements + if(parent != NULL || hasVariant(Mstring("\"element\""))){ + return; + } + + //It would be nice if here outside_reference.resolved to everything + SimpleType * st = (SimpleType*)outside_reference.get_ref(); + bool newST = false; + if(st == NULL && !isBuiltInType(type.convertedValue)){ + //Not even a reference, and not a built in type + return; + }else if(st == NULL && isBuiltInType(type.convertedValue)){ + st = new SimpleType(parser, module, construct); + st->type.upload(type.convertedValue); + st->name.upload(type.convertedValue); + st->typeSubsGroup = findBuiltInTypeInStoredTypeSubstitutions(type.convertedValue); + newST = true; + } + + addedToTypeSubstitution = true; + + //If type substitution is NULL then we need to create the union + if(st->getTypeSubstitution() == NULL){ + ComplexType * head_element = new ComplexType(*st, ComplexType::fromTypeSubstitution); + for(List::iterator simpletype = st->nameDepList.begin(); simpletype; simpletype = simpletype->Next){ + head_element->getNameDepList().push_back(simpletype->Data); + } + st->nameDepList.clear(); + st->getModule()->addMainType(head_element); + head_element->addVariant(V_useType); + head_element->addTypeSubstitution(st); + head_element->addTypeSubstitution(this); + bool found = false; + //Check to find if there was already an element reference with this type + for(List::iterator str = module->getElementTypes().begin(); str; str = str->Next){ + Mstring prefix = str->Data.type.getPrefix(':'); + Mstring value = str->Data.type.getValueWithoutPrefix(':'); + + if((value == st->getName().convertedValue.getValueWithoutPrefix(':') && prefix == module->getTargetNamespaceConnector()) || + (isBuiltInType(value) && !isBuiltInType(st->getType().convertedValue) && value == st->getType().convertedValue && prefix == module->getTargetNamespaceConnector())){ + //Push the namedeplist + for(List::iterator simpletype = str->Data.nameDepList.begin(); simpletype; simpletype = simpletype->Next){ + head_element->getNameDepList().push_back(simpletype->Data); + } + found = true; + str->Data.typeSubsGroup = head_element; + break; + } + } + if(!found){ + head_element->setInvisible(); + } + st->typeSubsGroup = head_element; + st->getModule()->addStoredTypeSubstitution(head_element); + }else { + st->getTypeSubstitution()->addTypeSubstitution(this); + } + + //Free pointer + if(newST){ + delete st; + st = NULL; + } +} + +void SimpleType::collectElementTypes(SimpleType* found_ST, ComplexType* found_CT){ + //Only if type substitution is enabled and it is a top level(simpletype) element or + //it is a not top level element(complextype) + if(h_flag_used && (hasVariant(Mstring("\"element\"")) || xsdtype == n_element)){ + SimpleType * st = NULL, *nameDep = NULL; + Mstring uri, value, type_; + if(found_ST != NULL || found_CT != NULL){ + // st := found_ST or found_CT, which is not null + st = found_ST != NULL ? found_ST : found_CT; + uri = outside_reference.get_uri(); + value = outside_reference.get_val(); + type_ = value; + }else if(isBuiltInType(type.convertedValue)){ + st = this; + uri = module->getTargetNamespace(); + value = type.convertedValue; + if(outside_reference.empty()){ + type_ = value; + nameDep = this; + }else { + type_ = outside_reference.get_val(); + } + }else { + //It is not possible to reach here (should be) + return; + } + type_ = type_.getValueWithoutPrefix(':'); + bool found = false; + const Mstring typeSubsName = value + Mstring("_derivations"); + //Find if we already have a substitution type to this element reference + for(List::iterator complex = st->getModule()->getStoredTypeSubstitutions().begin(); complex; complex = complex->Next){ + + if(uri == st->getModule()->getTargetNamespace() && typeSubsName == complex->Data->getName().convertedValue){ + complex->Data->setVisible(); + if(st->getXsdtype() != n_NOTSET && this == st){ //otherwise records would be renamed too + complex->Data->addToNameDepList(st); + ((ComplexType*)st)->setNameDep(nameDep); + } + found = true; + break; + } + } + //Add the reference, to future possible type substitution + if(!found){ + Mstring prefix = st->getModule()->getTargetNamespaceConnector(); + if(prefix != empty_string){ + prefix += ":"; + } + st->getModule()->addElementType(prefix + type_, nameDep); + } + } +} + +ComplexType * SimpleType::findBuiltInTypeInStoredTypeSubstitutions(const Mstring& builtInType){ + const Mstring typeSubsName = builtInType.getValueWithoutPrefix(':') + Mstring("_derivations"); + for(List::iterator complex = module->getStoredTypeSubstitutions().begin(); complex; complex = complex->Next){ + if(typeSubsName == complex->Data->getName().convertedValue){ + return complex->Data; + } + } + return NULL; +} + + void SimpleType::setReference(const Mstring& ref, bool only_name_dependency) { if (ref.empty()) { return; @@ -374,7 +517,11 @@ void SimpleType::setReference(const Mstring& ref, bool only_name_dependency) { } void SimpleType::referenceResolving() { - if (outside_reference.empty() && substitionGroup.empty()) return; + if (outside_reference.empty()){ + addToTypeSubstitutions(); + collectElementTypes(); + } + if(outside_reference.empty() && substitutionGroup.empty()) return; if (outside_reference.is_resolved()) return; if(!outside_reference.empty()){ @@ -383,18 +530,20 @@ void SimpleType::referenceResolving() { ComplexType * found_CT = static_cast ( TTCN3ModuleInventory::getInstance().lookup(this, want_CT)); // It _is_ possible to find both - + collectElementTypes(found_ST, found_CT); if (found_ST != NULL) { if (!found_ST->outside_reference.empty() && !found_ST->outside_reference.is_resolved() && found_ST != this) { found_ST->outside_reference.set_resolved(NULL); found_ST->referenceResolving(); } referenceForST(found_ST); + addToTypeSubstitutions(); if (!isBuiltInType(type.convertedValue)) { found_ST->addToNameDepList(this); } } else if (found_CT != NULL) { referenceForCT(found_CT); + addToTypeSubstitutions(); if (!isBuiltInType(type.convertedValue)) { found_CT->addToNameDepList(this); } @@ -404,10 +553,8 @@ void SimpleType::referenceResolving() { TTCN3ModuleInventory::getInstance().incrNumErrors(); outside_reference.set_resolved(NULL); } - if(!substitionGroup.empty()){ - addToSubstitutions(); - } - }else if(!substitionGroup.empty()){ + addToSubstitutions(); + }else { addToSubstitutions(); } } diff --git a/xsdconvert/SimpleType.hh b/xsdconvert/SimpleType.hh index c4ea106..4e59ea8 100644 --- a/xsdconvert/SimpleType.hh +++ b/xsdconvert/SimpleType.hh @@ -218,12 +218,27 @@ protected: // XSD Type of the type TagName xsdtype; bool isOptional; - Mstring substitionGroup; + Mstring substitutionGroup; + //Pointer to the generated element substitution group ComplexType * subsGroup; + //Pointer to the generated type substitution group + ComplexType * typeSubsGroup; + //To determine if already added to type substitution + bool addedToTypeSubstitution; BlockValue block; + + //Element substitution + void addToSubstitutions(); + //Type substitution + void addToTypeSubstitutions(); + //Returns the type substitution which the builtInType belongs + ComplexType * findBuiltInTypeInStoredTypeSubstitutions(const Mstring& builtInType); - void addToSubstitutions(); + //Only used when type substitution is enabled + //If an element reference is found then it is put to a container + //to know if type substitution is possible + void collectElementTypes(SimpleType * found_ST = NULL, ComplexType * found_CT = NULL); void nameConversion_names(); virtual void nameConversion_types(const List & ns); @@ -338,14 +353,22 @@ public: return subsGroup; } + ComplexType * getTypeSubstitution() const { + return typeSubsGroup; + } + BlockValue getBlock() const { return block; } void addToNameDepList(SimpleType * t) { + //If the type has a substitution, we add the namedep to the substitution if(subsGroup != NULL && this != (SimpleType*)subsGroup){ SimpleType * substitution = (SimpleType*)subsGroup; substitution->addToNameDepList(t); + }else if(typeSubsGroup != NULL && this != (SimpleType*)typeSubsGroup){ + SimpleType * substitution = (SimpleType*)typeSubsGroup; + substitution->addToNameDepList(t); }else { nameDepList.push_back(t); } diff --git a/xsdconvert/TTCN3Module.cc b/xsdconvert/TTCN3Module.cc index a0c2763..046b7e3 100644 --- a/xsdconvert/TTCN3Module.cc +++ b/xsdconvert/TTCN3Module.cc @@ -42,6 +42,8 @@ TTCN3Module::TTCN3Module(const char * a_filename, XMLParser * a_parser) , elementFormDefault(notset) , attributeFormDefault(notset) , blockDefault(not_set) +, storedTypeSubstitutions() +, element_types() //, importedModules() , variant() , moduleNotIntoFile(false) diff --git a/xsdconvert/TTCN3Module.hh b/xsdconvert/TTCN3Module.hh index cfa0aba..96887c9 100644 --- a/xsdconvert/TTCN3Module.hh +++ b/xsdconvert/TTCN3Module.hh @@ -16,6 +16,15 @@ class TTCN3ModuleInventory; class RootType; +//Used only in type substitution, when we have to change the type or a builtintype +//due to type substitution +struct typeNameDepList { + Mstring type; + List nameDepList; + //Used only with builtInTypes + ComplexType* typeSubsGroup; +}; + /** * Type that contains information about one TTCN-3 module * and performs the generation of that module @@ -64,6 +73,12 @@ class TTCN3Module { List importedModules; // pointers not owned + //Used only in type substitution, stores every possibly substituted type definitions + List storedTypeSubstitutions; //pointers not owned + + //Used only in type substitution, stores every element that references a type + List element_types; + List variant; bool moduleNotIntoFile; @@ -191,6 +206,38 @@ public: return importedModules; } + List & getStoredTypeSubstitutions() { + return storedTypeSubstitutions; + } + + void addStoredTypeSubstitution(ComplexType * type){ + storedTypeSubstitutions.push_back(type); + } + + List & getElementTypes() { + return element_types; + } + + void addElementType(const Mstring& type, SimpleType* st) { + List::iterator it = element_types.begin(); + for(; it; it = it->Next){ + if(it->Data.type == type && st != NULL){ + it->Data.nameDepList.push_back(st); + break; + } + } + //New type that has not been in the element_types before + if(it == NULL){ + typeNameDepList list; + list.type = type; + list.typeSubsGroup = NULL; + if(st != NULL){ + list.nameDepList.push_back(st); + } + element_types.push_back(list); + } + } + /// Compute the TTCN-3 module name void TargetNamespace2ModuleName(); diff --git a/xsdconvert/TTCN3ModuleInventory.cc b/xsdconvert/TTCN3ModuleInventory.cc index b4c63c9..53b031d 100644 --- a/xsdconvert/TTCN3ModuleInventory.cc +++ b/xsdconvert/TTCN3ModuleInventory.cc @@ -291,6 +291,10 @@ RootType * TTCN3ModuleInventory::lookup(const RootType* ref, const Mstring& refe break; } } + if(uri.empty()){ + //If the targetnamespace is NoTargetNamespace therefore no prefix connector used + uri = ref->getModule()->getTargetNamespace(); + } }else { uri = getNameSpaceByPrefix(ref, uri); } diff --git a/xsdconvert/XMLParser.cc b/xsdconvert/XMLParser.cc index 9b446a3..7d778f2 100644 --- a/xsdconvert/XMLParser.cc +++ b/xsdconvert/XMLParser.cc @@ -556,18 +556,12 @@ void XMLParser::fillUpActualTagAttributes(const char ** attributes, const int at att_name_e[i] = a_NOTSET; if (att_name_s[i] == "abstract") { att_name_e[i] = a_abstract; - printWarning(filename, xmlSAX2GetLineNumber(context), - Mstring("The 'abstract' attribute is currently not supported.")); - ++num_warnings; } else if (att_name_s[i] == "attributeFormDefault") att_name_e[i] = a_attributeFormDefault; else if (att_name_s[i] == "base") att_name_e[i] = a_base; else if (att_name_s[i] == "block") { att_name_e[i] = a_block; - printWarning(filename, xmlSAX2GetLineNumber(context), - Mstring("The 'block' attribute is currently not supported.")); - ++num_warnings; } else if (att_name_s[i] == "blockDefault"){ att_name_e[i] = a_blockDefault; } else if (att_name_s[i] == "default") @@ -611,9 +605,6 @@ void XMLParser::fillUpActualTagAttributes(const char ** attributes, const int at att_name_e[i] = a_schemaLocation; else if (att_name_s[i] == "substitutionGroup") { att_name_e[i] = a_substitutionGroup; - //printWarning(filename, xmlSAX2GetLineNumber(context), - //Mstring("The 'substitutionGroup' attribute is currently not supported.")); - //++num_warnings; } else if (att_name_s[i] == "targetNamespace") att_name_e[i] = a_targetNamespace; else if (att_name_s[i] == "type") diff --git a/xsdconvert/converter.cc b/xsdconvert/converter.cc index 02bbc55..cba52ad 100644 --- a/xsdconvert/converter.cc +++ b/xsdconvert/converter.cc @@ -22,6 +22,7 @@ int d_flag_used = 0; bool e_flag_used = false; bool f_flag_used = false; bool g_flag_used = true; +bool h_flag_used = false; bool p_flag_used = false; bool s_flag_used = false; bool t_flag_used = false; @@ -56,7 +57,7 @@ int main(int argc, char **argv) { char c; opterr = 0; - while ((c = getopt(argc, argv, "cdef:gpqstvwxz")) != -1) { + while ((c = getopt(argc, argv, "cdef:ghpqstvwxz")) != -1) { switch (c) { case 'c': c_flag_used = true; @@ -74,6 +75,9 @@ int main(int argc, char **argv) { case 'g': g_flag_used = false; break; + case 'h': + h_flag_used = true; + break; case 'p': p_flag_used = true; break; @@ -207,6 +211,7 @@ static void printUsage(const char * argv0) { " -e: disable the generation of encoding instructions in TTCN-3 modules\n" " -f file: the names of XSD files are taken from file instead of the command line\n" " -g: generate TTCN-3 code disallowing element substitution\n" + " -h: generate TTCN-3 code allowing type substitution\n" " -p: do not generate the UsefulTtcn3Types and XSD predefined modules\n" " -q: quiet mode - disable the issue of status messages\n" " -s: parse and validate only - no TTCN-3 module generation\n" -- 2.34.1