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