Commit | Line | Data |
---|---|---|
d44e3c4f | 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 | * Delic, Adam | |
11 | * Raduly, Csaba | |
12 | * Szabo, Bence Janos | |
13 | * | |
14 | ******************************************************************************/ | |
970ed795 EL |
15 | #include "RootType.hh" |
16 | ||
17 | #include "TTCN3Module.hh" | |
18 | ||
3abe9331 | 19 | RootType::RootType(XMLParser * a_parser, TTCN3Module * a_module, const ConstructType a_construct) |
970ed795 EL |
20 | : parser(a_parser) |
21 | , module(a_module) | |
22 | , name() | |
23 | , type() | |
970ed795 EL |
24 | , minOccurs(1) |
25 | , maxOccurs(1) | |
26 | , variant() | |
27 | , variant_ref() | |
28 | , comment() | |
29 | , construct(a_construct) | |
30 | , origin(from_unknown) | |
31 | , visible(true) | |
3abe9331 | 32 | , nameDepList() { |
33 | switch (a_construct) { | |
34 | case c_schema: | |
35 | case c_annotation: | |
36 | case c_include: | |
37 | case c_import: | |
38 | //redundant: origin = from_unknown; | |
39 | break; | |
40 | case c_unknown: // because when using fields in complextypes we set construct to c_unknown | |
41 | case c_simpleType: | |
42 | origin = from_simpleType; | |
43 | type.upload(Mstring("anySimpleType")); | |
44 | break; | |
45 | case c_element: | |
46 | origin = from_element; | |
47 | type.upload(Mstring("anyType")); | |
48 | addVariant(V_element); | |
49 | break; | |
50 | case c_attribute: | |
51 | origin = from_attribute; | |
52 | type.upload(Mstring("anySimpleType")); | |
53 | addVariant(V_attribute); | |
54 | break; | |
55 | case c_complexType: | |
56 | origin = from_complexType; | |
57 | type.upload(Mstring("record")); | |
58 | break; | |
59 | case c_group: | |
60 | origin = from_group; | |
61 | type.upload(Mstring("record")); | |
62 | addVariant(V_untagged); | |
63 | break; | |
64 | case c_attributeGroup: | |
65 | origin = from_attributeGroup; | |
66 | type.upload(Mstring("record")); | |
67 | addVariant(V_attributeGroup); | |
68 | visible = false; | |
69 | break; | |
70 | default: | |
71 | break; | |
970ed795 EL |
72 | } |
73 | } | |
74 | ||
3abe9331 | 75 | void RootType::addVariant(const VariantMode var, const Mstring& var_value, const bool into_variant_ref) { |
970ed795 EL |
76 | Mstring variantstring; |
77 | ||
3abe9331 | 78 | switch (var) { |
79 | case V_abstract: | |
80 | variantstring = "\"abstract\""; | |
81 | break; | |
82 | case V_anyAttributes: | |
83 | variantstring = "\"anyAttributes" + var_value + "\""; | |
84 | break; | |
85 | case V_anyElement: | |
86 | variantstring = "\"anyElement" + var_value + "\""; | |
87 | break; | |
88 | case V_attribute: | |
89 | variantstring = "\"attribute\""; | |
90 | break; | |
91 | case V_attributeFormQualified: | |
92 | variantstring = "\"attributeFormQualified\""; | |
93 | break; | |
94 | case V_attributeGroup: | |
95 | variantstring = "\"attributeGroup\""; | |
96 | break; | |
97 | case V_block: | |
98 | variantstring = "\"block\""; | |
99 | break; | |
100 | case V_controlNamespace: | |
101 | variantstring = "\"controlNamespace" + var_value + "\""; | |
102 | break; | |
103 | case V_defaultForEmpty: | |
104 | variantstring = "\"defaultForEmpty as \'" + var_value + "\'\""; // chapter 7.1.5 | |
105 | break; | |
106 | case V_element: | |
107 | variantstring = "\"element\""; | |
108 | break; | |
109 | case V_elementFormQualified: | |
110 | variantstring = "\"elementFormQualified\""; | |
111 | break; | |
112 | case V_embedValues: | |
113 | variantstring = "\"embedValues\""; | |
114 | break; | |
115 | case V_formAs: | |
116 | variantstring = "\"form as " + var_value + "\""; | |
117 | break; | |
118 | case V_list: | |
119 | variantstring = "\"list\""; | |
120 | break; | |
121 | case V_nameAs: | |
122 | variantstring = "\"name as \'" + var_value + "\'\""; | |
123 | break; | |
124 | case V_namespaceAs: | |
125 | { | |
126 | Mstring prefix; | |
127 | Mstring uri; | |
128 | for (List<NamespaceType>::iterator namesp = module->getDeclaredNamespaces().begin(); namesp; namesp = namesp->Next) { | |
129 | if (namesp->Data.uri == var_value) { | |
130 | prefix = namesp->Data.prefix; | |
131 | uri = namesp->Data.uri; | |
132 | break; | |
133 | } | |
134 | } | |
135 | if (prefix.empty() || uri.empty()) { | |
970ed795 EL |
136 | break; |
137 | } | |
3abe9331 | 138 | variantstring = "\"namespace as \'" + uri + "\' prefix \'" + prefix + "\'\""; |
970ed795 EL |
139 | break; |
140 | } | |
3abe9331 | 141 | case V_onlyValue: |
142 | variantstring = var_value; | |
143 | break; | |
144 | case V_onlyValueHidden: | |
145 | hidden_variant.push_back(var_value); | |
146 | break; | |
147 | case V_untagged: | |
148 | variantstring = "\"untagged\""; | |
149 | break; | |
150 | case V_useNil: | |
151 | variantstring = "\"useNil\""; | |
152 | break; | |
153 | case V_useNumber: | |
154 | variantstring = "\"useNumber\""; | |
155 | break; | |
156 | case V_useOrder: | |
157 | variantstring = "\"useOrder\""; | |
158 | break; | |
51fa56b9 | 159 | case V_useType: |
160 | variantstring = "\"useType\""; | |
161 | break; | |
3abe9331 | 162 | case V_useUnion: |
163 | variantstring = "\"useUnion\""; | |
164 | break; | |
165 | case V_whiteSpace: | |
166 | variantstring = "\"whiteSpace " + var_value + "\""; | |
167 | break; | |
168 | case V_fractionDigits: | |
169 | //variantstring = "\"fractionDigits " + var_value + "\""; | |
170 | break; | |
970ed795 EL |
171 | } |
172 | ||
173 | if (!variantstring.empty()) { | |
174 | variant.push_back(variantstring); | |
175 | if (into_variant_ref) { | |
176 | variant_ref.push_back(variantstring); | |
177 | } | |
178 | } | |
179 | } | |
180 | ||
3abe9331 | 181 | void RootType::printVariant(FILE * file) { |
182 | if (!e_flag_used && !variant.empty()) { | |
970ed795 | 183 | fprintf(file, "\nwith {\n"); |
3abe9331 | 184 | for (List<Mstring>::iterator var = variant.end(); var; var = var->Prev) { |
3f84031e | 185 | fprintf(file, " variant %s;\n", var->Data.c_str()); |
970ed795 | 186 | } |
3abe9331 | 187 | for (List<Mstring>::iterator var = hidden_variant.end(); var; var = var->Prev) { |
3f84031e | 188 | fprintf(file, " //variant %s;\n", var->Data.c_str()); |
3abe9331 | 189 | } |
970ed795 | 190 | fprintf(file, "}"); |
3abe9331 | 191 | } else if (!e_flag_used && type.originalValueWoPrefix == Mstring("boolean")) { |
192 | fprintf(file, ";\n//with {\n"); | |
193 | for (List<Mstring>::iterator var = hidden_variant.end(); var; var = var->Prev) { | |
3f84031e | 194 | fprintf(file, " //variant %s;\n", var->Data.c_str()); |
3abe9331 | 195 | } |
196 | fprintf(file, "//}"); | |
970ed795 EL |
197 | } |
198 | } | |
199 | ||
3abe9331 | 200 | void RootType::addComment(const Mstring& text) { |
201 | comment.push_back(Mstring("/* " + text + " */\n")); | |
970ed795 EL |
202 | } |
203 | ||
3abe9331 | 204 | void RootType::printComment(FILE * file, int level) { |
205 | if (!c_flag_used && !comment.empty()) { | |
206 | for (List<Mstring>::iterator c = comment.begin(); c; c = c->Next) { | |
207 | indent(file, level); | |
208 | fprintf(file, "%s", c->Data.c_str()); | |
209 | } | |
970ed795 EL |
210 | } |
211 | } | |
212 | ||
3abe9331 | 213 | void RootType::printMinOccursMaxOccurs(FILE * file, const bool inside_union, |
214 | const bool empty_allowed /* = true */) const { | |
215 | ||
970ed795 EL |
216 | unsigned long long tmp_minOccurs = minOccurs; |
217 | if (minOccurs == 0 && !empty_allowed) tmp_minOccurs = 1ULL; | |
218 | ||
3abe9331 | 219 | if (maxOccurs == 1) { |
970ed795 EL |
220 | if (minOccurs == 0) { |
221 | if (inside_union || name.list_extension) { | |
222 | fputs("record length(", file); | |
223 | if (empty_allowed) fputs("0 .. ", file); | |
224 | // else: length(1..1) is shortened to length(1) | |
225 | fputs("1) of ", file); | |
226 | } | |
227 | // else it's optional which is not printed from here | |
3abe9331 | 228 | } else if (minOccurs == 1) { |
970ed795 | 229 | // min==max==1; do nothing unless... |
3abe9331 | 230 | if (name.convertedValue == "embed_values") { |
231 | fputs("record length(1) of ", file); | |
232 | } | |
970ed795 | 233 | } |
3abe9331 | 234 | } else if (maxOccurs == ULLONG_MAX) { |
970ed795 EL |
235 | if (minOccurs == 0) { |
236 | fputs("record ", file); | |
237 | if (!empty_allowed) fputs("length(1 .. infinity) ", file); | |
238 | fputs("of ", file); | |
3abe9331 | 239 | } else fprintf(file, "record length(%llu .. infinity) of ", tmp_minOccurs); |
240 | } else { | |
241 | if (tmp_minOccurs == maxOccurs) { | |
242 | fprintf(file, "record length(%llu) of ", tmp_minOccurs); | |
243 | } else { | |
244 | fprintf(file, "record length(%llu .. %llu) of ", tmp_minOccurs, maxOccurs); | |
970ed795 | 245 | } |
970ed795 EL |
246 | } |
247 | } | |
3abe9331 | 248 | |
249 | bool RootType::hasVariant(const Mstring& var) const{ | |
250 | for(List<Mstring>::iterator vars = variant.begin(); vars; vars = vars->Next){ | |
251 | if(vars->Data.isFound(var)){ | |
252 | return true; | |
253 | } | |
254 | } | |
51fa56b9 | 255 | for(List<Mstring>::iterator vars = hidden_variant.begin(); vars; vars = vars->Next){ |
256 | if(vars->Data.isFound(var)){ | |
257 | return true; | |
258 | } | |
259 | } | |
3abe9331 | 260 | return false; |
d44e3c4f | 261 | } |