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