Sync with 5.4.1
[deliverable/titan.core.git] / xsdconvert / TTCN3ModuleInventory.cc
CommitLineData
970ed795 1///////////////////////////////////////////////////////////////////////////////
3abe9331 2// Copyright (c) 2000-2015 Ericsson Telecom AB
970ed795
EL
3// All rights reserved. This program and the accompanying materials
4// are made available under the terms of the Eclipse Public License v1.0
5// which accompanies this distribution, and is available at
6// http://www.eclipse.org/legal/epl-v10.html
7///////////////////////////////////////////////////////////////////////////////
8#include "XMLParser.hh"
9#include "TTCN3ModuleInventory.hh"
10
11#include "GeneralFunctions.hh"
12
13#include "TTCN3Module.hh"
14#include "SimpleType.hh"
15#include "ComplexType.hh"
970ed795
EL
16
17extern bool h_flag_used;
18extern bool q_flag_used;
19
20
21
22unsigned int TTCN3ModuleInventory::num_errors = 0;
23unsigned int TTCN3ModuleInventory::num_warnings = 0;
24
970ed795
EL
25TTCN3ModuleInventory::TTCN3ModuleInventory()
26: definedModules()
27, writtenImports()
3abe9331 28, typenames() {
29}
970ed795 30
3abe9331 31TTCN3ModuleInventory::~TTCN3ModuleInventory() {
970ed795
EL
32 for (List<TTCN3Module*>::iterator module = definedModules.begin(); module; module = module->Next) {
33 delete(module->Data);
34 }
35}
36
3abe9331 37TTCN3ModuleInventory& TTCN3ModuleInventory::getInstance() {
970ed795
EL
38 // Singleton, see Meyers, More Effective C++, Item 26 (page 131)
39 static TTCN3ModuleInventory instance;
40 return instance;
41}
42
3abe9331 43TTCN3Module * TTCN3ModuleInventory::addModule(const char * xsd_filename, XMLParser * a_parser) {
970ed795
EL
44 TTCN3Module * module = new TTCN3Module(xsd_filename, a_parser);
45 definedModules.push_back(module);
46 return definedModules.back();
47}
48
3abe9331 49void TTCN3ModuleInventory::modulenameConversion() {
970ed795
EL
50 definedModules.sort(compareModules);
51
3abe9331 52 for (List<TTCN3Module*>::iterator module = definedModules.begin(); module; module = module->Next) {
970ed795
EL
53 module->Data->TargetNamespace2ModuleName();
54 }
55}
56
3abe9331 57void TTCN3ModuleInventory::referenceResolving() {
970ed795
EL
58 /**
59 * Reference resolving for include and import statements
60 */
3abe9331 61 for (List<TTCN3Module*>::iterator module = definedModules.begin(); module; module = module->Next) {
62 for (List<RootType*>::iterator type = module->Data->getDefinedTypes().begin(); type; type = type->Next) {
63 if (type->Data->getName().convertedValue == "import" || type->Data->getName().convertedValue == "include") {
970ed795
EL
64 type->Data->referenceResolving();
65 }
66 }
67 }
68
69 /**
70 * Reference resolving for all others
71 */
72 bool there_is_unresolved_reference_somewhere = false;
3abe9331 73 do {
970ed795
EL
74 there_is_unresolved_reference_somewhere = false;
75
3abe9331 76 for (List<TTCN3Module*>::iterator module = definedModules.begin(); module; module = module->Next) {
77 for (List<RootType*>::iterator type = module->Data->getDefinedTypes().begin(); type; type = type->Next) {
78 if (type->Data->getName().convertedValue != "import" && type->Data->getName().convertedValue != "include") {
970ed795 79 type->Data->referenceResolving();
3abe9331 80 if (type->Data->hasUnresolvedReference()) {
970ed795
EL
81 there_is_unresolved_reference_somewhere = true;
82 }
83 }
84 }
85 }
3abe9331 86 } while (there_is_unresolved_reference_somewhere);
970ed795
EL
87}
88
3abe9331 89void TTCN3ModuleInventory::finalModification() {
90 for (List<TTCN3Module*>::iterator module = definedModules.begin(); module; module = module->Next) {
91 for (List<RootType*>::iterator type = module->Data->getDefinedTypes().begin(); type; type = type->Next) {
970ed795
EL
92 type->Data->finalModification();
93 }
94 }
95}
96
3abe9331 97void TTCN3ModuleInventory::nameConversion() {
970ed795
EL
98 /**
99 * Sort of types and fields
100 */
970ed795
EL
101
102 definedModules.sort(compareModules);
103 /********************************************************
104 * Conversion of the name of types
105 * ******************************************************/
3abe9331 106 for (List<TTCN3Module*>::iterator module = definedModules.begin(); module; module = module->Next) {
970ed795
EL
107 if (module->Data->isnotIntoNameConversion()) continue;
108
109 List<RootType*> definedElements_inABC;
110 List<RootType*> definedAttributes_inABC;
111 List<RootType*> definedSimpleTypes_inABC;
112 List<RootType*> definedComplexTypes_inABC;
113 List<RootType*> definedAttributeGroups_inABC;
114 List<RootType*> definedGroups_inABC;
115
3abe9331 116 for (List<TTCN3Module*>::iterator module2 = module; module2; module2 = module2->Next) {
970ed795
EL
117 if (module2->Data->getModulename() != module->Data->getModulename()) continue;
118
3abe9331 119 for (List<RootType*>::iterator type = module2->Data->getDefinedTypes().begin(); type; type = type->Next) {
120 switch (type->Data->getConstruct()) {
121 case c_simpleType:
122 definedSimpleTypes_inABC.push_back(type->Data);
123 break;
124 case c_element:
125 definedElements_inABC.push_back(type->Data);
126 break;
127 case c_attribute:
128 definedAttributes_inABC.push_back(type->Data);
129 break;
130 case c_complexType:
131 definedComplexTypes_inABC.push_back(type->Data);
132 break;
133 case c_group:
134 definedGroups_inABC.push_back(type->Data);
135 break;
136 case c_attributeGroup:
137 definedAttributeGroups_inABC.push_back(type->Data);
138 break;
139 default:
140 break;
970ed795
EL
141 }
142 }
143 module2->Data->notIntoNameConversion();
144 }
145
146 definedElements_inABC.sort(compareTypes);
147 definedAttributes_inABC.sort(compareTypes);
148 definedSimpleTypes_inABC.sort(compareTypes);
149 definedComplexTypes_inABC.sort(compareTypes);
150 definedAttributeGroups_inABC.sort(compareTypes);
151 definedGroups_inABC.sort(compareTypes);
152
3abe9331 153 typenames.push_back(QualifiedName(module->Data->getTargetNamespace(), module->Data->getModulename()));
154 for(List<const TTCN3Module*>::iterator mod = module->Data->getImportedModules().begin(); mod; mod = mod->Next){
155 typenames.push_back(QualifiedName(module->Data->getTargetNamespace(), mod->Data->getModulename()));
156 }
157
158 for (List<RootType*>::iterator type = definedElements_inABC.begin(); type; type = type->Next) {
970ed795
EL
159 type->Data->nameConversion(nameMode, module->Data->getDeclaredNamespaces());
160 }
3abe9331 161 for (List<RootType*>::iterator type = definedAttributes_inABC.begin(); type; type = type->Next) {
970ed795
EL
162 type->Data->nameConversion(nameMode, module->Data->getDeclaredNamespaces());
163 }
3abe9331 164 for (List<RootType*>::iterator type = definedSimpleTypes_inABC.begin(); type; type = type->Next) {
970ed795
EL
165 type->Data->nameConversion(nameMode, module->Data->getDeclaredNamespaces());
166 }
3abe9331 167 for (List<RootType*>::iterator type = definedComplexTypes_inABC.begin(); type; type = type->Next) {
970ed795
EL
168 type->Data->nameConversion(nameMode, module->Data->getDeclaredNamespaces());
169 }
3abe9331 170 for (List<RootType*>::iterator type = definedAttributeGroups_inABC.begin(); type; type = type->Next) {
970ed795
EL
171 type->Data->nameConversion(nameMode, module->Data->getDeclaredNamespaces());
172 }
3abe9331 173 for (List<RootType*>::iterator type = definedGroups_inABC.begin(); type; type = type->Next) {
970ed795
EL
174 type->Data->nameConversion(nameMode, module->Data->getDeclaredNamespaces());
175 }
3abe9331 176 typenames.clear();
970ed795
EL
177 }
178 /********************************************************
179 * Conversion of the type of types
180 * ******************************************************/
3abe9331 181 for (List<TTCN3Module*>::iterator module = definedModules.begin(); module; module = module->Next) {
182 for (List<RootType*>::iterator type = module->Data->getDefinedTypes().begin(); type; type = type->Next) {
970ed795
EL
183 type->Data->nameConversion(typeMode, module->Data->getDeclaredNamespaces());
184 }
185 }
186 /********************************************************
187 * Conversion of the names and the types of the fields
188 * ******************************************************/
3abe9331 189 for (List<TTCN3Module*>::iterator module = definedModules.begin(); module; module = module->Next) {
190 for (List<RootType*>::iterator type = module->Data->getDefinedTypes().begin(); type; type = type->Next) {
970ed795
EL
191 type->Data->nameConversion(fieldMode, module->Data->getDeclaredNamespaces());
192 }
193 }
194}
195
3abe9331 196void TTCN3ModuleInventory::moduleGeneration() {
197 for (List<TTCN3Module*>::iterator module = definedModules.begin(); module; module = module->Next) {
198 if (module->Data->isnotIntoFile()) {
199 continue;
200 }
970ed795
EL
201
202 List<NamespaceType> used_namespaces;
203 NamespaceType targetns;
204 targetns.uri = module->Data->getTargetNamespace();
205 used_namespaces.push_back(targetns);
206
207 // Now search for other modules with the same module name.
208 // They must have had the same targetNamespace.
3abe9331 209 for (List<TTCN3Module*>::iterator module2 = module; module2; module2 = module2->Next) {
210 if (module2->Data->getModulename() != module->Data->getModulename()) {
211 continue;
212 }
970ed795 213
3abe9331 214 for (List<NamespaceType>::iterator declNS = module2->Data->getDeclaredNamespaces().begin(); declNS; declNS = declNS->Next) {
970ed795
EL
215 used_namespaces.push_back(declNS->Data);
216 }
217 module2->Data->notIntoFile(); // first module gets the TTCN-3 file
218 }
219
220 Mstring filename_s = module->Data->getModulename() + ".ttcn";
221 FILE * file = fopen(filename_s.c_str(), "w");
222 if (file == NULL) {
223 Mstring cannot_write("Cannot write file ");
224 perror((cannot_write + filename_s).c_str());
225 ++num_errors;
226 return;
227 }
228#ifndef NDEBUG
229 // In debug mode, set the output stream to unbuffered.
230 // This allows watching the output as it appears (e.g. with tail -f).
231 setvbuf(file, NULL, _IONBF, 0);
232#endif
233
234 module->Data->generate_TTCN3_header(file);
235
236 fprintf(file, "//\tGenerated from file(s):\n");
237
3abe9331 238 for (List<TTCN3Module*>::iterator module2 = module; module2; module2 = module2->Next) {
239 if (module2->Data->getModulename() == module->Data->getModulename()) {
970ed795
EL
240 module2->Data->generate_TTCN3_fileinfo(file);
241 }
242 }
243
244 fprintf(file,
245 "////////////////////////////////////////////////////////////////////////////////\n"
246 "// Modification header(s):\n"
247 "//-----------------------------------------------------------------------------\n"
248 "// Modified by:\n"
249 "// Modification date:\n"
250 "// Description:\n"
251 "// Modification contact:\n"
252 "//------------------------------------------------------------------------------\n"
253 "////////////////////////////////////////////////////////////////////////////////\n"
254 "\n"
255 "\n");
256
257 module->Data->generate_TTCN3_modulestart(file);
258
3abe9331 259 for (List<TTCN3Module*>::iterator module2 = module; module2; module2 = module2->Next) {
260 if (module2->Data->getModulename() == module->Data->getModulename()) {
970ed795
EL
261 module2->Data->generate_TTCN3_import_statements(file);
262 }
263 }
264
265 writtenImports.clear();
266
3abe9331 267 for (List<TTCN3Module*>::iterator module2 = module; module2; module2 = module2->Next) {
268 if (module2->Data->getModulename() == module->Data->getModulename()) {
970ed795
EL
269 module2->Data->generate_TTCN3_included_types(file);
270 module2->Data->generate_TTCN3_types(file);
271 }
272 }
273
274 fprintf(file, "}\n");
275
276 module->Data->generate_with_statement(file, used_namespaces);
277
278 if (!q_flag_used) fprintf(stderr, "Notify: File '%s' was generated.\n", filename_s.c_str());
279
280 fclose(file);
281 }
282}
283
3abe9331 284RootType * TTCN3ModuleInventory::lookup(const RootType* ref, const Mstring& reference, wanted w) const {
285 Mstring uri = reference.getPrefix(':');
286 const Mstring& name = reference.getValueWithoutPrefix(':');
287 if(uri.empty()){
288 for(List<NamespaceType>::iterator qname = ref->getModule()->getDeclaredNamespaces().begin(); qname; qname = qname->Next){
289 if(qname->Data.prefix.empty()){
290 uri = qname->Data.uri;
291 break;
292 }
293 }
51fa56b9 294 if(uri.empty()){
295 //If the targetnamespace is NoTargetNamespace therefore no prefix connector used
296 uri = ref->getModule()->getTargetNamespace();
297 }
3abe9331 298 }else {
299 uri = getNameSpaceByPrefix(ref, uri);
300 }
301 return lookup(name, uri, NULL, w);
302}
303
304RootType * TTCN3ModuleInventory::lookup(const SimpleType * reference, wanted w) const {
305 const Mstring& uri = reference->getReference().get_uri();
306 const Mstring& name = reference->getReference().get_val();
307
308 return lookup(name, uri, reference, w);
309}
310
311RootType * TTCN3ModuleInventory::lookup(const ComplexType * reference, wanted w) const {
970ed795
EL
312 const Mstring& uri = reference->getReference().get_uri();
313 const Mstring& name = reference->getReference().get_val();
314
315 return lookup(name, uri, reference, w);
316}
317
318RootType * TTCN3ModuleInventory::lookup(const Mstring& name, const Mstring& nsuri,
3abe9331 319 const RootType *reference, wanted w) const {
970ed795
EL
320 return ::lookup(definedModules, name, nsuri, reference, w);
321}
322
3abe9331 323void TTCN3ModuleInventory::dump() const {
324 fprintf(stderr, "Dumping %lu modules.\n", (unsigned long) definedModules.size());
325 for (List<TTCN3Module*>::iterator module = definedModules.begin(); module; module = module->Next) {
970ed795
EL
326 module->Data->dump();
327 }
328
3abe9331 329 fprintf(stderr, "Dumping %lu types\n", (unsigned long) typenames.size());
970ed795
EL
330
331 Item<QualifiedName> *o = typenames.begin();
3abe9331 332 for (; o != NULL; o = o->Next) {
970ed795
EL
333 fprintf(stderr, "{%s}%s,\n",
334 o->Data.nsuri.c_str(), o->Data.name.c_str());
335 }
336}
This page took 0.042894 seconds and 5 git commands to generate.