Commit | Line | Data |
---|---|---|
970ed795 EL |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Copyright (c) 2000-2014 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 "ImportStatement.hh" | |
9 | ||
10 | #include "GeneralFunctions.hh" | |
11 | #include "TTCN3Module.hh" | |
12 | #include "TTCN3ModuleInventory.hh" | |
13 | ||
14 | extern bool c_flag_used; | |
15 | ||
16 | ImportStatement::ImportStatement(XMLParser * a_parser, TTCN3Module * a_module, ConstructType a_construct) | |
17 | : RootType(a_parser, a_module, a_construct) | |
18 | , from_namespace() | |
19 | , from_schemaLocation() | |
20 | , source_module() | |
21 | {} | |
22 | ||
23 | void ImportStatement::loadWithValues() | |
24 | { | |
25 | const XMLParser::TagAttributes & attr = parser->getActualTagAttributes(); | |
26 | ||
27 | switch (parser->getActualTagName()) | |
28 | { | |
29 | case XMLParser::n_import: | |
30 | name.upload(Mstring("import")); | |
31 | type.upload(Mstring("import")); | |
32 | from_namespace = attr.namespace_; | |
33 | from_schemaLocation = attr.schemaLocation; | |
34 | break; | |
35 | case XMLParser::n_include: | |
36 | name.upload(Mstring("include")); | |
37 | type.upload(Mstring("include")); | |
38 | from_namespace = attr.namespace_; | |
39 | from_schemaLocation = attr.schemaLocation; | |
40 | break; | |
41 | case XMLParser::n_label: | |
42 | addComment(Mstring("LABEL:")); | |
43 | break; | |
44 | case XMLParser::n_definition: | |
45 | addComment(Mstring("DEFINITION:")); | |
46 | break; | |
47 | ||
48 | default: | |
49 | break; | |
50 | } | |
51 | } | |
52 | ||
53 | const Mstring XMLSchema("http://www.w3.org/2001/XMLSchema"); | |
54 | ||
55 | void ImportStatement::referenceResolving(void) | |
56 | { | |
57 | if (from_namespace == XMLSchema) { | |
58 | visible = false; | |
59 | return; | |
60 | } | |
61 | ||
62 | TTCN3ModuleInventory& modules = TTCN3ModuleInventory::getInstance(); | |
63 | ||
64 | for (List<TTCN3Module*>::iterator mod = modules.getModules().begin(); mod; mod = mod->Next) | |
65 | { | |
66 | if (module == mod->Data) { | |
67 | // it's the module that *contains* the import statement | |
68 | continue; | |
69 | } | |
70 | // Try the namespace first | |
71 | if (from_namespace == mod->Data->getTargetNamespace()) { | |
72 | source_module = mod->Data; | |
73 | break; | |
74 | } | |
75 | // Fallback: try the schemaLocation attribute | |
76 | if (!from_schemaLocation.empty()) { | |
77 | if (from_schemaLocation == mod->Data->getSchemaname()) { | |
78 | source_module = mod->Data; | |
79 | from_namespace = mod->Data->getTargetNamespace(); | |
80 | // do not break; give a chance to other modules to match the namespace | |
81 | } | |
82 | } | |
83 | } | |
84 | ||
85 | if (!source_module) // still not found | |
86 | { | |
87 | if (from_schemaLocation.empty()) | |
88 | { | |
89 | printWarning(module->getSchemaname(), getName().convertedValue, | |
90 | "The \'" + from_namespace + "\' specified in the \'namespace\' attribute" | |
91 | " is not resolvable."); | |
92 | modules.incrNumWarnings(); | |
93 | } | |
94 | else // schemaLocation is not empty | |
95 | { | |
96 | if (from_schemaLocation.isFound("http://") || from_schemaLocation.isFound("urn:")) { | |
97 | printWarning(module->getSchemaname(), getName().convertedValue, | |
98 | "It is not supported using a URI (\'" + from_schemaLocation + | |
99 | "\') in the \'schemalocation\' attribute to get access to a file."); | |
100 | modules.incrNumWarnings(); | |
101 | } | |
102 | else { | |
103 | printWarning(module->getSchemaname(), getName().convertedValue, | |
104 | "The \'" + from_schemaLocation + "\' specified in the \'schemaLocation\' attribute" | |
105 | " is not resolvable."); | |
106 | modules.incrNumWarnings(); | |
107 | } | |
108 | } | |
109 | visible = false; | |
110 | } | |
111 | else module->addImportedModule(source_module); | |
112 | } | |
113 | ||
114 | void ImportStatement::printToFile(FILE * file) | |
115 | { | |
116 | if (!visible) return; | |
117 | ||
118 | if (from_namespace == module->getTargetNamespace()) return; | |
119 | // Not include or import in this case: including is automatic because modules have the same targetnamespace | |
120 | ||
121 | printComment(file); | |
122 | ||
123 | switch (getConstruct()) | |
124 | { | |
125 | case c_import: { | |
126 | bool found = false; | |
127 | for (List<TTCN3Module*>::iterator wImport = TTCN3ModuleInventory::getInstance().getWrittenImports().begin(); wImport; wImport = wImport->Next) | |
128 | { | |
129 | if (wImport->Data == source_module) { | |
130 | found = true; | |
131 | break; | |
132 | } | |
133 | } | |
134 | if (!found) { | |
135 | fprintf(file, "import from %s all;\n\n\n", source_module->getModulename().c_str()); | |
136 | TTCN3ModuleInventory::getInstance().getWrittenImports().push_back(source_module); | |
137 | } | |
138 | break; } | |
139 | case c_include: { | |
140 | for (List<TTCN3Module*>::iterator mod = TTCN3ModuleInventory::getInstance().getModules().begin(); mod; mod = mod->Next) | |
141 | { | |
142 | if (mod->Data->getSchemaname() == from_schemaLocation) | |
143 | { | |
144 | mod->Data->generate_TTCN3_types(file); | |
145 | break; | |
146 | } | |
147 | } | |
148 | break; } | |
149 | default: | |
150 | break; | |
151 | } | |
152 | } | |
153 | ||
154 | void ImportStatement::dump(unsigned int depth) const | |
155 | { | |
156 | fprintf(stderr, "%*s Import statement at %p, ns='%s' loc='%s'\n", depth * 2, "", | |
157 | (const void*)this, from_namespace.c_str(), from_schemaLocation.c_str()); | |
158 | fprintf(stderr, "%*s import from %s into %s\n", depth * 2 + 2, "", | |
159 | (source_module ? source_module->getModulename().c_str() : "**unknown**"), | |
160 | module->getModulename().c_str()); | |
161 | } | |
162 |