Commit d6a11d06 authored by Botond Baranyi's avatar Botond Baranyi
Browse files

Added single module generation option for xsd2ttcn and fixed element...


Added single module generation option for xsd2ttcn and fixed element substitution namespaces (bug 536713)

Change-Id: I08ff283d2da85b1857f876f736b97c75bc3d2e20
Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent e633e51e
/*******************************************************************************
* Copyright (c) 2000-2018 Ericsson Telecom AB
*
* XSD to TTCN-3 Translator
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
*
* Contributors:
* Baranyi, Botond
*
*******************************************************************************/
//
// File: XSD_Definitions.ttcn
// Description:
// References:
// Rev:
// Prodnr:
// Updated:
// Contact: http://ttcn.ericsson.se
//
////////////////////////////////////////////////////////////////////////////////
// Modification header(s):
//-----------------------------------------------------------------------------
// Modified by:
// Modification date:
// Description:
// Modification contact:
//------------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
module XSD_Definitions_e {
import from XSD all;
////////////////////////////////////////////////////////////////////////////////
// Generated from file(s):
// - substitution_group_one.xsd
// /* xml version = "1.0" */
// /* targetnamespace = "http://www.somewhere.com/one" */
////////////////////////////////////////////////////////////////////////////////
group http_www_somewhere_com_one {
import from XSD all;
type record HeadType
{
XSD.String str optional
}
with {
variant "abstract";
variant (str) "attribute";
};
type union Head_group
{
HeadType head,
Extended extended
}
with {
variant "untagged";
variant (head) "name as capitalized";
variant (head) "form as qualified";
variant (head) "abstract";
variant (extended) "name as capitalized";
variant (extended) "namespace as 'http://www.somewhere.com/two' prefix 'two'";
};
}
with {
encode "XML";
variant "namespace as 'http://www.somewhere.com/one' prefix 'one'";
variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'";
variant "elementFormQualified";
}
////////////////////////////////////////////////////////////////////////////////
// Generated from file(s):
// - substitution_group_two.xsd
// /* xml version = "1.0" */
// /* targetnamespace = "http://www.somewhere.com/two" */
////////////////////////////////////////////////////////////////////////////////
group http_www_somewhere_com_two {
import from XSD all;
type ExtendedType Extended
with {
variant "element";
};
type record ExtendedType
{
XSD.String str optional,
XSD.Integer num
}
with {
variant (str) "attribute";
};
}
with {
encode "XML";
variant "namespace as 'http://www.somewhere.com/two' prefix 'two'";
variant "controlNamespace 'http://www.w3.org/2001/XMLSchema-instance' prefix 'xsi'";
variant "elementFormQualified";
}
}
......@@ -66,6 +66,7 @@ with {
variant (subsgroup) "form as qualified";
variant (subsgroup) "abstract";
variant (replace_) "name as 'replace'";
variant (replace_) "namespace as 'www.example.org/substitutiongroup/ref' prefix 'this'";
};
......
......@@ -144,6 +144,8 @@
<File path="../xsd/attrib_enum.xsd" />
<File path="../xsd/substitutiongroup_main.xsd" />
<File path="../xsd/substitutiongroup_ref.xsd" />
<File path="../xsd/substitution_group_one.xsd" />
<File path="../xsd/substitution_group_two.xsd" />
<File path="../xsd/simpletype_base.xsd" />
<File path="../xsd/type_substitution.xsd" />
<File path="../xsd/type_substitution_chain.xsd" />
......@@ -389,6 +391,7 @@
<File path="../XmlTest_expectedTtcns/www_example_org_attrib_enum_e.ttcn" />
<File path="../XmlTest_expectedTtcns/www_example_org_substitutiongroup_ref_e.ttcn" />
<File path="../XmlTest_expectedTtcns/www_example_org_substitutiongroup_main_e.ttcn" />
<File path="../XmlTest_expectedTtcns/XSD_Definitions_e.ttcn" />
<File path="../XmlTest_expectedTtcns/www_example_org_simpletype_base_e.ttcn" />
<File path="../XmlTest_expectedTtcns/www_example_org_type_substitution_e.ttcn" />
<File path="../XmlTest_expectedTtcns/www_example_org_type_substitution_chain_e.ttcn" />
......
......@@ -2613,6 +2613,18 @@ group Elements{
testcase tc_element_nillable_RemarkNillable_nilTrue_encDec() runs on xmlTest_CT {
f_encDecTest_RemarkNillable2();
}//tc_
testcase tc_substitution_group_merged() runs on xmlTest_CT {
f_shellCommandWithVerdict(xsd2ttcn_command & " -o substitution_group_one.xsd substitution_group_two.xsd",
"", c_shell_successWithoutWarningAndError);
if(getverdict == pass) {
f_compareFiles(
"XSD_Definitions_e.ttcn",
"XSD_Definitions.ttcn", c_numOfDiff);
}
}
}//Element
......@@ -2888,6 +2900,7 @@ control {
execute(tc_element_nillable_RemarkNillable_nilFalse_encDec());
execute(tc_element_nillable_RemarkNillable_nilTrue_encDec());
execute(tc_substitution_group_merged());
}
} with {
......
<?xml version="1.0"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:one="http://www.somewhere.com/one"
targetNamespace="http://www.somewhere.com/one"
version="3.1.1" elementFormDefault="qualified">
<element name="Head" type="one:HeadType" abstract="true"/>
<complexType name="HeadType" abstract="true">
<attribute name="str" type="string" use="optional"/>
</complexType>
</schema>
<?xml version="1.0"?>
<xs:schema targetNamespace="http://www.somewhere.com/two"
xmlns:two="http://www.somewhere.com/two"
xmlns:one="http://www.somewhere.com/one"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="3.1.1" elementFormDefault="qualified">
<xs:import namespace="http://www.somewhere.com/one" schemaLocation="substitution_group_one.xsd"/>
<xs:element name="Extended" type="two:ExtendedType"
substitutionGroup="one:Head"/>
<xs:complexType name="ExtendedType">
<xs:complexContent>
<xs:extension base="one:HeadType">
<xs:sequence>
<xs:element name="num" type="xs:integer"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
......@@ -22,6 +22,7 @@
#include "TTCN3ModuleInventory.hh"
#include "Annotation.hh"
#include "Constant.hh"
#include "converter.hh"
#include <assert.h>
......@@ -2357,6 +2358,31 @@ void ComplexType::addSubstitution(SimpleType * st){
element->addVariant(V_block);
}
}
if (st->getModule()->getTargetNamespace() != module->getTargetNamespace() &&
st->getModule()->getTargetNamespace() != "NoTargetNamespace") {
element->addVariant(V_namespaceAs, st->getModule()->getTargetNamespace());
}
if (!o_flag_used && st->getModule() != module &&
!isBuiltInType(st->getType().convertedValue)) {
bool import_found = false;
for (List<const TTCN3Module*>::iterator imp = module->getImportedModules().begin();
imp != module->getImportedModules().end(); ++imp) {
if (imp->Data == st->getModule()) {
import_found = true;
break;
}
}
if (!import_found) {
printWarning(st->getModule()->getSchemaname(), st->getName().convertedValue,
Mstring("Type `") + st->getName().convertedValue + Mstring("' is used "
"in a substitution group in module `") + module->getModulename() +
Mstring("', which does not import the type's module. This may lead to "
"errors in the generated code. For a safe solution, please use the "
"single module command line option (-o) or disable element "
"substitution (-g)."));
TTCN3ModuleInventory::incrNumWarnings();
}
}
}
element->setNameValue(st->getName().convertedValue);
......
......@@ -38,6 +38,8 @@
extern bool e_flag_used;
extern bool z_flag_used;
unsigned int TTCN3Module::static_const_counter = 1;
TTCN3Module::TTCN3Module(const char * a_filename, XMLParser * a_parser)
: parser(a_parser)
, schemaname()
......@@ -272,13 +274,13 @@ void TTCN3Module::generate_TTCN3_fileinfo(FILE * file) {
void TTCN3Module::generate_TTCN3_modulestart(FILE * file) {
fprintf(file,
"module %s {\n"
"%s %s {\n"
"\n"
"\n"
"import from XSD all;\n"
"\n"
"\n",
modulename.c_str()
o_flag_used ? "group" : "module", modulename.c_str()
);
}
......
......@@ -19,6 +19,7 @@
#include "GeneralTypes.hh"
#include "GeneralFunctions.hh"
#include "TTCN3ModuleInventory.hh"
#include "converter.hh"
class TTCN3ModuleInventory;
class RootType;
......@@ -98,6 +99,8 @@ class TTCN3Module {
bool moduleNotIntoNameConversion;
unsigned int const_counter;
static unsigned int static_const_counter;
TTCN3Module & operator=(const TTCN3Module &); // not implemented
TTCN3Module(const TTCN3Module &); // not implemented
......@@ -271,11 +274,16 @@ public:
friend bool compareModules(TTCN3Module * lhs, TTCN3Module * rhs);
unsigned int getConstCounter() {
return const_counter;
return o_flag_used ? static_const_counter : const_counter;
}
void increaseConstCounter() {
++const_counter;
if (o_flag_used) {
++static_const_counter;
}
else {
++const_counter;
}
}
void dump() const;
......
......@@ -237,6 +237,32 @@ void TTCN3ModuleInventory::nameConversion() {
}
void TTCN3ModuleInventory::moduleGeneration() {
FILE * file = NULL;
if (o_flag_used) {
file = fopen("XSD_Definitions.ttcn", "w");
if (file == NULL) {
perror("Cannot open file XSD_Definitions.ttcn for writing.");
++num_errors;
return;
}
generate_TTCN3_header(file, "XSD_Definitions");
fprintf(file,
"// Modification header(s):\n"
"//-----------------------------------------------------------------------------\n"
"// Modified by:\n"
"// Modification date:\n"
"// Description:\n"
"// Modification contact:\n"
"//------------------------------------------------------------------------------\n"
"////////////////////////////////////////////////////////////////////////////////\n"
"\n"
"\n"
"module XSD_Definitions {\n"
"\n"
"\n"
"import from XSD all;\n");
}
for (List<TTCN3Module*>::iterator module = definedModules.begin(); module; module = module->Next) {
if (module->Data->isnotIntoFile()) {
continue;
......@@ -261,12 +287,14 @@ void TTCN3ModuleInventory::moduleGeneration() {
}
Mstring filename_s = module->Data->getModulename() + ".ttcn";
FILE * file = fopen(filename_s.c_str(), "w");
if (file == NULL) {
Mstring cannot_write("Cannot write file ");
perror((cannot_write + filename_s).c_str());
++num_errors;
return;
if (!o_flag_used) {
file = fopen(filename_s.c_str(), "w");
if (file == NULL) {
Mstring cannot_write("Cannot write file ");
perror((cannot_write + filename_s).c_str());
++num_errors;
return;
}
}
#ifndef NDEBUG
// In debug mode, set the output stream to unbuffered.
......@@ -274,7 +302,14 @@ void TTCN3ModuleInventory::moduleGeneration() {
setvbuf(file, NULL, _IONBF, 0);
#endif
generate_TTCN3_header(file, module->Data->getModulename().c_str());
if (!o_flag_used) {
generate_TTCN3_header(file, module->Data->getModulename().c_str());
}
if (o_flag_used) {
fprintf(file, "\n\n"
"////////////////////////////////////////////////////////////////////////////////\n");
}
fprintf(file, "//\tGenerated from file(s):\n");
......@@ -283,25 +318,31 @@ void TTCN3ModuleInventory::moduleGeneration() {
module2->Data->generate_TTCN3_fileinfo(file);
}
}
fprintf(file,
"////////////////////////////////////////////////////////////////////////////////\n"
"// Modification header(s):\n"
"//-----------------------------------------------------------------------------\n"
"// Modified by:\n"
"// Modification date:\n"
"// Description:\n"
"// Modification contact:\n"
"//------------------------------------------------------------------------------\n"
"////////////////////////////////////////////////////////////////////////////////\n"
"\n"
"\n");
"////////////////////////////////////////////////////////////////////////////////\n");
if (!o_flag_used) {
fprintf(file,
"// Modification header(s):\n"
"//-----------------------------------------------------------------------------\n"
"// Modified by:\n"
"// Modification date:\n"
"// Description:\n"
"// Modification contact:\n"
"//------------------------------------------------------------------------------\n"
"////////////////////////////////////////////////////////////////////////////////\n"
"\n"
"\n");
}
module->Data->generate_TTCN3_modulestart(file);
for (List<TTCN3Module*>::iterator module2 = module; module2; module2 = module2->Next) {
if (module2->Data->getModulename() == module->Data->getModulename()) {
module2->Data->generate_TTCN3_import_statements(file);
if (!o_flag_used) {
for (List<TTCN3Module*>::iterator module2 = module; module2; module2 = module2->Next) {
if (module2->Data->getModulename() == module->Data->getModulename()) {
module2->Data->generate_TTCN3_import_statements(file);
}
}
}
......@@ -318,8 +359,20 @@ void TTCN3ModuleInventory::moduleGeneration() {
module->Data->generate_with_statement(file, used_namespaces);
if (!q_flag_used) fprintf(stderr, "Notify: File '%s' was generated.\n", filename_s.c_str());
if (!o_flag_used) {
if (!q_flag_used) {
fprintf(stderr, "Notify: File '%s' was generated.\n", filename_s.c_str());
}
fclose(file);
}
}
if (o_flag_used) {
fprintf(file, "\n\n}\n");
if (!q_flag_used) {
fprintf(stderr, "Notify: File 'XSD_Definitions.ttcn' was generated.\n");
}
fclose(file);
}
}
......
......@@ -38,6 +38,7 @@ bool g_flag_used = true;
bool h_flag_used = false;
bool m_flag_used = false;
bool n_flag_used = false; // Undocumented. Internal use only with makefilegen
bool o_flag_used = false;
bool p_flag_used = false;
bool s_flag_used = false;
bool t_flag_used = false;
......@@ -74,7 +75,7 @@ int main(int argc, char **argv) {
char c;
opterr = 0;
while ((c = getopt(argc, argv, "cdef:ghJ:mnpqstvwxz")) != -1) {
while ((c = getopt(argc, argv, "cdef:ghJ:mnopqstvwxz")) != -1) {
switch (c) {
case 'c':
c_flag_used = true;
......@@ -102,6 +103,9 @@ int main(int argc, char **argv) {
case 'n':
n_flag_used = true;
break;
case 'o':
o_flag_used = true;
break;
case 'p':
p_flag_used = true;
break;
......@@ -244,7 +248,7 @@ static void printProductinfo() {
static void printUsage(const char * argv0) {
fprintf(stderr, "\n"
"usage: %s [-ceghmpstVwx] [-f file] [-J file] schema.xsd ...\n"
"usage: %s [-ceghmopstVwx] [-f file] [-J file] schema.xsd ...\n"
" or %s -v\n"
"\n"
"OPTIONS:\n"
......@@ -254,6 +258,7 @@ static void printUsage(const char * argv0) {
" -g: generate TTCN-3 code disallowing element substitution\n"
" -h: generate TTCN-3 code allowing type substitution\n"
" -m: generate only the UsefulTtcn3Types and XSD predefined modules\n"
" -o: generate all definitions into one module (called XSD_Definitions)\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"
......
......@@ -21,6 +21,7 @@ extern bool g_flag_used;
extern bool h_flag_used;
extern bool m_flag_used;
extern bool n_flag_used; // Undocumented. Internal use only with makefilegen
extern bool o_flag_used;
extern bool p_flag_used;
extern bool s_flag_used;
extern bool t_flag_used;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment