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