From: ebensza Date: Mon, 13 Jun 2016 10:56:46 +0000 (+0200) Subject: xsd2ttcn: fixed error when reading XMLSchema.xsd (Bug 495653) X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;ds=sidebyside;h=4999ad2e3024f452e8164f5132317fe196207fe9;p=deliverable%2Ftitan.core.git xsd2ttcn: fixed error when reading XMLSchema.xsd (Bug 495653) Signed-off-by: ebensza --- diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/http_www_example_org_2001_XMLSchema_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/http_www_example_org_2001_XMLSchema_e.ttcn new file mode 100644 index 0000000..b0bef7f --- /dev/null +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/http_www_example_org_2001_XMLSchema_e.ttcn @@ -0,0 +1,134 @@ +/******************************************************************************* +* Copyright (c) 2000-2016 Ericsson Telecom AB +* +* 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 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +*******************************************************************************/ +// +// File: http_www_example_org_2001_XMLSchema_e.ttcn +// Description: +// References: +// Rev: +// Prodnr: +// Updated: Mon Jun 13 09:08:10 2015 +// Contact: http://ttcn.ericsson.se +// +//////////////////////////////////////////////////////////////////////////////// +// Generated from file(s): +// - MyXMLSchema.xsd +// /* xml version = "1.0" encoding = "UTF-8" */ +// /* targetnamespace = "http://www.example.org/2001/XMLSchema/e" */ +//////////////////////////////////////////////////////////////////////////////// +// Modification header(s): +//----------------------------------------------------------------------------- +// Modified by: +// Modification date: +// Description: +// Modification contact: +//------------------------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////////////// + + +module http_www_example_org_2001_XMLSchema { + + +import from XSD all; + + +type record AttrDecls +{ + record of union { + XSD.String attribute, + XSD.String attributeGroup + } choice_list +} +with { + variant "untagged"; + variant (choice_list) "untagged"; + variant (choice_list[-]) "untagged"; +}; + + +type record OpenAttrs +{ + record of XSD.String attr optional +} +with { + variant "name as uncapitalized"; + variant (attr) "anyAttributes except unqualified, 'http://www.example.org/2001/XMLSchema'"; +}; + + +type record Annotated +{ + record of XSD.String attr optional, + XSD.String asd optional +} +with { + variant "name as uncapitalized"; + variant (attr) "anyAttributes except unqualified, 'http://www.example.org/2001/XMLSchema'"; +}; + + +type union TypeDefParticle +{ + XSD.String group_ +} +with { + variant "untagged"; + variant (group_) "name as 'group'"; +}; + + +type record RestrictionType +{ + record of XSD.String attr optional, + XSD.String asd optional, + union { + TypeDefParticle typeDefParticle + } choice optional, + record of union { + XSD.String attribute, + XSD.String attributeGroup + } choice_list +} +with { + variant "name as uncapitalized"; + variant (attr) "anyAttributes except unqualified, 'http://www.example.org/2001/XMLSchema'"; + variant (choice) "untagged"; + variant (choice_list) "untagged"; + variant (choice_list[-]) "untagged"; +}; + + +type record ComplexRestrictionType +{ + record of XSD.String attr optional, + union { + TypeDefParticle typeDefParticle + } choice, + record of union { + XSD.String attribute, + XSD.String attributeGroup + } choice_list +} +with { + variant "name as uncapitalized"; + variant (attr) "anyAttributes except unqualified, 'http://www.example.org/2001/XMLSchema'"; + variant (choice) "untagged"; + variant (choice_list) "untagged"; + variant (choice_list[-]) "untagged"; +}; + + +} +with { + encode "XML"; + variant "namespace as 'http://www.example.org/2001/XMLSchema' prefix 'a'"; + variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'"; + variant "elementFormQualified"; +} diff --git a/regression_test/XML/XmlWorkflow/src/xmlTest.prj b/regression_test/XML/XmlWorkflow/src/xmlTest.prj index 080be3e..6c60f9b 100644 --- a/regression_test/XML/XmlWorkflow/src/xmlTest.prj +++ b/regression_test/XML/XmlWorkflow/src/xmlTest.prj @@ -164,6 +164,7 @@ + @@ -398,6 +399,7 @@ + diff --git a/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn b/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn index f78a24b..f666ec9 100644 --- a/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn +++ b/regression_test/XML/XmlWorkflow/src/xmlTest_Testcases.ttcn @@ -1598,6 +1598,16 @@ group ComplexType { } }//tc_ + testcase tc_xmlschema() runs on xmlTest_CT { + f_shellCommandWithVerdict("xsd2ttcn MyXMLSchema.xsd","",c_shell_successWithoutWarningAndError) + + if(getverdict==pass) { + f_compareFiles( + "http_www_example_org_2001_XMLSchema_e.ttcn", + "http_www_example_org_2001_XMLSchema.ttcn", c_numOfDiff_headerModNameAndNamespace); + } + }//tc_ + testcase tc_complex_restriction_encDec() runs on xmlTest_CT { var MySubjects4Restriction vl_pdu:={ @@ -2650,6 +2660,7 @@ control { execute(tc_complex_nillable()); execute(tc_nillable_fixed()); execute(tc_no_ns_connector()); + execute(tc_xmlschema()); diff --git a/regression_test/XML/XmlWorkflow/xsd/MyXMLSchema.xsd b/regression_test/XML/XmlWorkflow/xsd/MyXMLSchema.xsd new file mode 100644 index 0000000..6e3e742 --- /dev/null +++ b/regression_test/XML/XmlWorkflow/xsd/MyXMLSchema.xsd @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xsdconvert/AttributeType.cc b/xsdconvert/AttributeType.cc index 6ea93c2..73e6475 100644 --- a/xsdconvert/AttributeType.cc +++ b/xsdconvert/AttributeType.cc @@ -120,20 +120,20 @@ void AttributeType::applyUseAttribute() { } switch (useVal) { case optional: - minOccurs = 0; - maxOccurs = 1; + setMinOccurs(0); + setMaxOccurs(1); break; case required: - minOccurs = 1; - maxOccurs = 1; + setMinOccurs(1); + setMaxOccurs(1); break; case prohibited: - minOccurs = 0; - maxOccurs = 0; + setMinOccurs(0); + setMaxOccurs(0); setInvisible(); break; } - isOptional = isOptional || (minOccurs == 0 && maxOccurs == 1); + isOptional = isOptional || (getMinOccurs() == 0 && getMaxOccurs() == 1); } void AttributeType::applyNamespaceAttribute(VariantMode varLabel) { @@ -194,8 +194,8 @@ void AttributeType::applyNamespaceAttribute(VariantMode varLabel) { } void AttributeType::applyMinMaxOccursAttribute(unsigned long long min, unsigned long long max) { - minOccurs = min; - maxOccurs = max; + setMinOccurs(min); + setMaxOccurs(max); } void AttributeType::dump(unsigned int depth) const { @@ -203,7 +203,7 @@ void AttributeType::dump(unsigned int depth) const { name.originalValueWoPrefix.c_str(), name.convertedValue.c_str(), (const void*) this); fprintf(stderr, "%*s %s Type: \n", depth * 2, "", type.convertedValue.c_str()); fprintf(stderr, "%*s type %s \n", (depth + 1) * 2, "", type.convertedValue.c_str()); - fprintf(stderr, "%*s (%llu .. %llu)\n", (depth + 1) * 2, "", minOccurs, maxOccurs); + fprintf(stderr, "%*s (%llu .. %llu)\n", (depth + 1) * 2, "", getMinOccurs(), getMaxOccurs()); fprintf(stderr, "%*s %d variants: ", (depth + 1) * 2, "", (int) variant.size()); for (List::iterator var = variant.begin(); var; var = var->Next) { fprintf(stderr, "%s, ", var->Data.c_str()); diff --git a/xsdconvert/ComplexType.cc b/xsdconvert/ComplexType.cc index 12dc49b..7c56c89 100644 --- a/xsdconvert/ComplexType.cc +++ b/xsdconvert/ComplexType.cc @@ -733,15 +733,16 @@ void ComplexType::applyReference(const SimpleType & other, const bool on_attribu type.convertedValue = other.getType().convertedValue; type.originalValueWoPrefix = other.getType().convertedValue.getValueWithoutPrefix(':'); - if (other.getMinOccurs() > minOccurs || other.getMaxOccurs() < maxOccurs) { + if (other.getMinOccurs() > getMinOccurs() || + other.getMaxOccurs() < getMaxOccurs()) { if (!on_attributes) { expstring_t temp = memptystr(); temp = mputprintf( temp, "The occurrence range (%llu .. %llu) of the element (%s) is not compatible " "with the occurrence range (%llu .. %llu) of the referenced element.", - minOccurs, - maxOccurs, + getMinOccurs(), + getMaxOccurs(), name.originalValueWoPrefix.c_str(), other.getMinOccurs(), other.getMaxOccurs()); @@ -751,8 +752,8 @@ void ComplexType::applyReference(const SimpleType & other, const bool on_attribu TTCN3ModuleInventory::getInstance().incrNumErrors(); } } else { - minOccurs = llmax(minOccurs, other.getMinOccurs()); - maxOccurs = llmin(maxOccurs, other.getMaxOccurs()); + setMinOccurs(llmax(getMinOccurs(), other.getMinOccurs())); + setMaxOccurs(llmin(getMaxOccurs(), other.getMaxOccurs())); } for (List::iterator var = other.getVariantRef().begin(); var; var = var->Next) { @@ -929,7 +930,7 @@ void ComplexType::setFieldPaths(Mstring path) { if (path.empty()) { if (!top) { Mstring field_prefix = empty_string; - if(parent->minOccurs == 0 && parent->maxOccurs == ULLONG_MAX){ + if(parent->getMinOccurs() == 0 && parent->getMaxOccurs() == ULLONG_MAX){ field_prefix = "[-]."; } path = field_prefix + getName().convertedValue; @@ -959,14 +960,14 @@ void ComplexType::finalModification2() { SimpleType::finalModification(); //Set isOptional field - isOptional = isOptional || (minOccurs == 0 && maxOccurs == 1); + isOptional = isOptional || (getMinOccurs() == 0 && getMaxOccurs() == 1); // List enumNames; for (List::iterator field = complexfields.begin(), nextField; field; field = nextField) { nextField = field->Next; //Remove invisible fields - if ((field->Data->minOccurs == 0 && field->Data->maxOccurs == 0) || !field->Data->isVisible()) { + if ((field->Data->getMinOccurs() == 0 && field->Data->getMaxOccurs() == 0) || !field->Data->isVisible()) { delete field->Data; field->Data = NULL; complexfields.remove(field); @@ -1252,7 +1253,7 @@ void ComplexType::collectVariants(List& container) { if (top) { bool useUnionVariantWhenMainTypeIsRecordOf = false; for (List::iterator var = variant.end(); var; var = var->Prev) { - if ((minOccurs != 1 || maxOccurs != 1) && (var->Data == "\"useUnion\"")) { // main type is a record of + if ((getMinOccurs() != 1 || getMaxOccurs() != 1) && (var->Data == "\"useUnion\"")) { // main type is a record of useUnionVariantWhenMainTypeIsRecordOf = true; // TR HL15893 } else { container.push_back(Mstring("variant ") + Mstring(var->Data.c_str()) + Mstring(";\n")); @@ -1389,7 +1390,7 @@ void ComplexType::dump(unsigned int depth) const { for (List::iterator field = enumfields.begin(); field; field = field->Next) { fprintf(stderr, "%*s enum: %s\n", depth * 2 + depth, "", field->Data.c_str()); } - fprintf(stderr, "%*s (%llu .. %llu) | Optional:%s | List:%s\n", (depth + 1) * 2, "", minOccurs, maxOccurs, isOptional ? "true" : "false", name.list_extension ? "true" : "false"); + fprintf(stderr, "%*s (%llu .. %llu) | Optional:%s | List:%s\n", (depth + 1) * 2, "", getMinOccurs(), getMaxOccurs(), isOptional ? "true" : "false", name.list_extension ? "true" : "false"); fprintf(stderr, "%*s %d variants: ", (depth + 1) * 2, "", (int) variant.size()); for (List::iterator var = variant.begin(); var; var = var->Next) { fprintf(stderr, "%s, ", var->Data.c_str()); @@ -1403,8 +1404,8 @@ void ComplexType::setMinMaxOccurs(const unsigned long long min, const unsigned l if (min != 1 || max != 1) { if (xsdtype == n_choice) { - minOccurs = min; - maxOccurs = max; + setMinOccurs(min); + setMaxOccurs(max); addVariant(V_untagged); first_child = false; } else if (xsdtype == n_sequence) { @@ -1414,17 +1415,17 @@ void ComplexType::setMinMaxOccurs(const unsigned long long min, const unsigned l rec->setXsdtype(n_sequence); rec->addVariant(V_untagged); rec->addVariant(V_untagged); - rec->minOccurs = min; - rec->maxOccurs = max; + rec->setMinOccurs(min); + rec->setMaxOccurs(max); complexfields.push_back(rec); actfield = rec; - if ((rec->minOccurs == 0 && rec->maxOccurs > 1) || rec->minOccurs > 0) { + if ((rec->getMinOccurs() == 0 && rec->getMaxOccurs() > 1) || rec->getMinOccurs() > 0) { rec->name.list_extension = true; } } else { - minOccurs = min; - maxOccurs = max; - if ((minOccurs == 0 && maxOccurs > 1) || minOccurs > 0) { + setMinOccurs(min); + setMaxOccurs(max); + if ((getMinOccurs() == 0 && getMaxOccurs() > 1) || getMinOccurs() > 0) { if (generate_list_postfix) { name.list_extension = true; } @@ -1432,7 +1433,7 @@ void ComplexType::setMinMaxOccurs(const unsigned long long min, const unsigned l if (parent != NULL && parent->getXsdtype() == n_choice) { name.list_extension = true; if ((parent != NULL && parent->getXsdtype() == n_choice)) { - if (parent->first_child == false && minOccurs == 0) { + if (parent->first_child == false && getMinOccurs() == 0) { parent->first_child = true; with_union = true; first_child = false; @@ -1445,7 +1446,7 @@ void ComplexType::setMinMaxOccurs(const unsigned long long min, const unsigned l } } - if (maxOccurs > 1 && generate_list_postfix) { + if (getMaxOccurs() > 1 && generate_list_postfix) { name.list_extension = true; } } @@ -1691,7 +1692,7 @@ void ComplexType::resolveGroup(SimpleType *st) { ct->getModule()->getTargetNamespace() != "NoTargetNamespace") { addNameSpaceas = true; } - if (ct->getXsdtype() == n_sequence && minOccurs == 1 && maxOccurs == 1 && (parent->getXsdtype() == n_complexType || parent->getXsdtype() == n_sequence)) { + if (ct->getXsdtype() == n_sequence && getMinOccurs() == 1 && getMaxOccurs() == 1 && (parent->getXsdtype() == n_complexType || parent->getXsdtype() == n_sequence)) { for (List::iterator c = ct->complexfields.begin(); c; c = c->Next) { ComplexType * newField = new ComplexType(*c->Data); parent->complexfields.push_back(newField); @@ -1705,7 +1706,7 @@ void ComplexType::resolveGroup(SimpleType *st) { //If the parent optional, then every field is optional for (List::iterator c = ct->complexfields.begin(); c; c = c->Next) { ComplexType* f = new ComplexType(*c->Data); - if (minOccurs == 0 && !f->enumerated) { + if (getMinOccurs() == 0 && !f->enumerated) { f->isOptional = true; } ((ComplexType*) parent)->complexfields.push_back(f); @@ -1916,8 +1917,8 @@ void ComplexType::resolveComplexTypeExtension() { field->applyReference(*f->Data); field->type.upload(ct->getName().convertedValue + Mstring(".") + f->Data->getName().convertedValue); field->type.no_replace = true; - field->minOccurs = f->Data->minOccurs; - field->maxOccurs = f->Data->maxOccurs; + field->setMinOccurs(f->Data->getMinOccurs()); + field->setMaxOccurs(f->Data->getMaxOccurs()); complexfields.push_front(field); setParent(this, field); } @@ -1951,7 +1952,10 @@ void ComplexType::resolveComplexTypeRestriction() { List::iterator field2 = ct->complexfields.begin(); for (; field2; field2 = field2->Next) { if (field->Data->getName().convertedValue == field2->Data->getName().convertedValue && - field->Data->getType().convertedValue == field2->Data->getType().convertedValue) { + field->Data->getType().convertedValue == field2->Data->getType().convertedValue && + field->Data->complexfields.size() <= field2->Data->complexfields.size() && + hasMatchingFields(field->Data->complexfields, field2->Data->complexfields)) { + // TODO: better algorithm to find matching fields field->Data->applyReference(*field2->Data, false); break; } @@ -1964,6 +1968,25 @@ void ComplexType::resolveComplexTypeRestriction() { } } +bool ComplexType::hasMatchingFields(const List& mainList, const List& subList) const { + List::iterator field = mainList.begin(); + for (; field; field = field->Next){ + List::iterator field2 = subList.begin(); + bool found = false; + for (; field2; field2 = field2->Next) { + if(field->Data->getName().convertedValue == field2->Data->getName().convertedValue && + field->Data->getType().convertedValue == field2->Data->getType().convertedValue) { + found = true; + break; + } + } + if(!found) { + return false; + } + } + return true; +} + void ComplexType::resolveUnion(SimpleType *st) { if (parent != NULL && parent->with_union && xsdtype == n_simpleType && !outside_reference.empty()) { if (st->getXsdtype() != n_NOTSET) { diff --git a/xsdconvert/ComplexType.hh b/xsdconvert/ComplexType.hh index 80a4886..08ad656 100644 --- a/xsdconvert/ComplexType.hh +++ b/xsdconvert/ComplexType.hh @@ -111,6 +111,7 @@ private: void resolveComplexTypeExtension(); void resolveComplexTypeRestriction(); void resolveUnion(SimpleType *st); + bool hasMatchingFields(const List& a, const List& b) const; void printVariant(FILE * file); diff --git a/xsdconvert/RootType.cc b/xsdconvert/RootType.cc index 8958389..19a768b 100644 --- a/xsdconvert/RootType.cc +++ b/xsdconvert/RootType.cc @@ -21,15 +21,17 @@ RootType::RootType(XMLParser * a_parser, TTCN3Module * a_module, const Construct , module(a_module) , name() , type() -, minOccurs(1) -, maxOccurs(1) , variant() , variant_ref() , comment() , construct(a_construct) , origin(from_unknown) , visible(true) -, nameDepList() { +, nameDepList() +, minOccurs(1) +, maxOccurs(1) +, min_mod(false) +, max_mod(false){ switch (a_construct) { case c_schema: case c_annotation: diff --git a/xsdconvert/RootType.hh b/xsdconvert/RootType.hh index 1926b5f..9026d4d 100644 --- a/xsdconvert/RootType.hh +++ b/xsdconvert/RootType.hh @@ -112,8 +112,6 @@ protected: NameType name; NameType type; - unsigned long long int minOccurs; - unsigned long long int maxOccurs; List variant; List variant_ref; List hidden_variant; @@ -126,7 +124,13 @@ protected: /// List of types that depend on this one. /// Used to propagate the effect of name conversion to the dependents List nameDepList; // no responsibility for elements - + +private: + unsigned long long int minOccurs; + unsigned long long int maxOccurs; + bool min_mod; + bool max_mod; + public: RootType(XMLParser * a_parser, TTCN3Module * a_module, const ConstructType a_construct); @@ -175,6 +179,24 @@ public: void setVisible() { visible = true; } + + void setMinOccurs(const unsigned long long int min) { + minOccurs = min; + min_mod = true; + } + + void setMaxOccurs(const unsigned long long int max) { + maxOccurs = max; + max_mod = true; + } + + const bool getMinMod() const { + return min_mod; + } + + const bool getMaxMod() const { + return max_mod; + } const NameType & getName() const { return name; diff --git a/xsdconvert/SimpleType.cc b/xsdconvert/SimpleType.cc index 6f52bc2..73a45fd 100644 --- a/xsdconvert/SimpleType.cc +++ b/xsdconvert/SimpleType.cc @@ -89,8 +89,8 @@ void SimpleType::loadWithValues() { case n_list: type.upload(atts.itemType); setReference(atts.itemType); - minOccurs = 0; - maxOccurs = ULLONG_MAX; + setMinOccurs(0); + setMaxOccurs(ULLONG_MAX); addVariant(V_list); mode = listMode; break; @@ -133,8 +133,8 @@ void SimpleType::loadWithValues() { } case n_length: if (mode == listMode) { - minOccurs = strtoull(atts.value.c_str(), NULL, 0); - maxOccurs = strtoull(atts.value.c_str(), NULL, 0); + setMinOccurs(strtoull(atts.value.c_str(), NULL, 0)); + setMaxOccurs(strtoull(atts.value.c_str(), NULL, 0)); break; } length.facet_minLength = strtoull(atts.value.c_str(), NULL, 0); @@ -143,7 +143,7 @@ void SimpleType::loadWithValues() { break; case n_minLength: if (mode == listMode) { - minOccurs = strtoull(atts.value.c_str(), NULL, 0); + setMinOccurs(strtoull(atts.value.c_str(), NULL, 0)); break; } length.facet_minLength = strtoull(atts.value.c_str(), NULL, 0); @@ -151,7 +151,7 @@ void SimpleType::loadWithValues() { break; case n_maxLength: if (mode == listMode) { - maxOccurs = strtoull(atts.value.c_str(), NULL, 0); + setMaxOccurs(strtoull(atts.value.c_str(), NULL, 0)); break; } length.facet_maxLength = strtoull(atts.value.c_str(), NULL, 0); @@ -771,7 +771,7 @@ void SimpleType::finalModification() { addVariant(V_onlyValueHidden, Mstring("\"text 'true' as '1'\"")); } - isOptional = isOptional || (minOccurs == 0 && maxOccurs == 0); + isOptional = isOptional || (getMinOccurs() == 0 && getMaxOccurs() == 0); // If the type name is the same as the identifier then we have to prefix it // with the module identifier.