Sync with 5.4.3
[deliverable/titan.core.git] / xsdconvert / TTCN3ModuleInventory.cc
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 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 #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"
16
17 extern bool h_flag_used;
18 extern bool q_flag_used;
19
20
21
22 unsigned int TTCN3ModuleInventory::num_errors = 0;
23 unsigned int TTCN3ModuleInventory::num_warnings = 0;
24
25 TTCN3ModuleInventory::TTCN3ModuleInventory()
26 : definedModules()
27 , writtenImports()
28 , typenames() {
29 }
30
31 TTCN3ModuleInventory::~TTCN3ModuleInventory() {
32 for (List<TTCN3Module*>::iterator module = definedModules.begin(); module; module = module->Next) {
33 delete(module->Data);
34 }
35 }
36
37 TTCN3ModuleInventory& TTCN3ModuleInventory::getInstance() {
38 // Singleton, see Meyers, More Effective C++, Item 26 (page 131)
39 static TTCN3ModuleInventory instance;
40 return instance;
41 }
42
43 TTCN3Module * TTCN3ModuleInventory::addModule(const char * xsd_filename, XMLParser * a_parser) {
44 TTCN3Module * module = new TTCN3Module(xsd_filename, a_parser);
45 definedModules.push_back(module);
46 return definedModules.back();
47 }
48
49 void TTCN3ModuleInventory::modulenameConversion() {
50 definedModules.sort(compareModules);
51
52 for (List<TTCN3Module*>::iterator module = definedModules.begin(); module; module = module->Next) {
53 module->Data->TargetNamespace2ModuleName();
54 }
55 }
56
57 void TTCN3ModuleInventory::referenceResolving() {
58 /**
59 * Reference resolving for include and import statements
60 */
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") {
64 type->Data->referenceResolving();
65 }
66 }
67 }
68
69 /**
70 * Reference resolving for all others
71 */
72 bool there_is_unresolved_reference_somewhere = false;
73 do {
74 there_is_unresolved_reference_somewhere = false;
75
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") {
79 type->Data->referenceResolving();
80 if (type->Data->hasUnresolvedReference()) {
81 there_is_unresolved_reference_somewhere = true;
82 }
83 }
84 }
85 }
86 } while (there_is_unresolved_reference_somewhere);
87 }
88
89 void 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) {
92 type->Data->finalModification();
93 }
94 }
95 }
96
97 void TTCN3ModuleInventory::nameConversion() {
98 /**
99 * Sort of types and fields
100 */
101
102 definedModules.sort(compareModules);
103 /********************************************************
104 * Conversion of the name of types
105 * ******************************************************/
106 for (List<TTCN3Module*>::iterator module = definedModules.begin(); module; module = module->Next) {
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
116 for (List<TTCN3Module*>::iterator module2 = module; module2; module2 = module2->Next) {
117 if (module2->Data->getModulename() != module->Data->getModulename()) continue;
118
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;
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
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) {
159 type->Data->nameConversion(nameMode, module->Data->getDeclaredNamespaces());
160 }
161 for (List<RootType*>::iterator type = definedAttributes_inABC.begin(); type; type = type->Next) {
162 type->Data->nameConversion(nameMode, module->Data->getDeclaredNamespaces());
163 }
164 for (List<RootType*>::iterator type = definedSimpleTypes_inABC.begin(); type; type = type->Next) {
165 type->Data->nameConversion(nameMode, module->Data->getDeclaredNamespaces());
166 }
167 for (List<RootType*>::iterator type = definedComplexTypes_inABC.begin(); type; type = type->Next) {
168 type->Data->nameConversion(nameMode, module->Data->getDeclaredNamespaces());
169 }
170 for (List<RootType*>::iterator type = definedAttributeGroups_inABC.begin(); type; type = type->Next) {
171 type->Data->nameConversion(nameMode, module->Data->getDeclaredNamespaces());
172 }
173 for (List<RootType*>::iterator type = definedGroups_inABC.begin(); type; type = type->Next) {
174 type->Data->nameConversion(nameMode, module->Data->getDeclaredNamespaces());
175 }
176 typenames.clear();
177 }
178 /********************************************************
179 * Conversion of the type of types
180 * ******************************************************/
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) {
183 type->Data->nameConversion(typeMode, module->Data->getDeclaredNamespaces());
184 }
185 }
186 /********************************************************
187 * Conversion of the names and the types of the fields
188 * ******************************************************/
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) {
191 type->Data->nameConversion(fieldMode, module->Data->getDeclaredNamespaces());
192 }
193 }
194 }
195
196 void TTCN3ModuleInventory::moduleGeneration() {
197 for (List<TTCN3Module*>::iterator module = definedModules.begin(); module; module = module->Next) {
198 if (module->Data->isnotIntoFile()) {
199 continue;
200 }
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.
209 for (List<TTCN3Module*>::iterator module2 = module; module2; module2 = module2->Next) {
210 if (module2->Data->getModulename() != module->Data->getModulename()) {
211 continue;
212 }
213
214 for (List<NamespaceType>::iterator declNS = module2->Data->getDeclaredNamespaces().begin(); declNS; declNS = declNS->Next) {
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 generate_TTCN3_header(file, module->Data->getModulename().c_str());
235
236 fprintf(file, "//\tGenerated from file(s):\n");
237
238 for (List<TTCN3Module*>::iterator module2 = module; module2; module2 = module2->Next) {
239 if (module2->Data->getModulename() == module->Data->getModulename()) {
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
259 for (List<TTCN3Module*>::iterator module2 = module; module2; module2 = module2->Next) {
260 if (module2->Data->getModulename() == module->Data->getModulename()) {
261 module2->Data->generate_TTCN3_import_statements(file);
262 }
263 }
264
265 writtenImports.clear();
266
267 for (List<TTCN3Module*>::iterator module2 = module; module2; module2 = module2->Next) {
268 if (module2->Data->getModulename() == module->Data->getModulename()) {
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
284 RootType * 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 }
294 if(uri.empty()){
295 //If the targetnamespace is NoTargetNamespace therefore no prefix connector used
296 uri = ref->getModule()->getTargetNamespace();
297 }
298 }else {
299 uri = getNameSpaceByPrefix(ref, uri);
300 }
301 return lookup(name, uri, NULL, w);
302 }
303
304 RootType * 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
311 RootType * TTCN3ModuleInventory::lookup(const ComplexType * reference, wanted w) const {
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
318 RootType * TTCN3ModuleInventory::lookup(const Mstring& name, const Mstring& nsuri,
319 const RootType *reference, wanted w) const {
320 return ::lookup(definedModules, name, nsuri, reference, w);
321 }
322
323 void 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) {
326 module->Data->dump();
327 }
328
329 fprintf(stderr, "Dumping %lu types\n", (unsigned long) typenames.size());
330
331 Item<QualifiedName> *o = typenames.begin();
332 for (; o != NULL; o = o->Next) {
333 fprintf(stderr, "{%s}%s,\n",
334 o->Data.nsuri.c_str(), o->Data.name.c_str());
335 }
336 }
This page took 0.039885 seconds and 5 git commands to generate.