Sync with 5.4.2
[deliverable/titan.core.git] / compiler2 / union.c
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 <string.h>
9
10 #include "../common/memory.h"
11 #include "datatypes.h"
12 #include "union.h"
13 #include "encdec.h"
14
15 #include "main.hh"
16 #include "ttcn3/compiler.h"
17
18 /** used in the RAW_decode functions generation to store information
19 * about the temporal variables
20 * type is the type of the variable
21 * typedescr is the type's descriptor
22 * start_pos is where the decoding should begin
23 * it is >= 0 if known at compile time, otherwise -1
24 * use_counter stores how many times this type will be used
25 * if it is >1 than we create the variable "globally" so that that
26 * we don't need to create it again in the next component's decode try
27 * if it is ==1 than it is a local variable only referred at one place
28 * we create it only where it is needed, so if at runtime the decoding
29 * comes to a conclusion before the use of this variable, then its
30 * overhead won't slow down the decoding
31 * decoded_for_element is the index of the element in the union for which
32 * this variable was last used for
33 * if it is -1 if the variable hasn't been decoded yet
34 * only in this case it is needed to generate the code to do the decoding
35 * if it is >=0 than we use it generate the conditions
36 * if it doesn't equal to the actual component's index, then we have to
37 * generate the condition and the decoding... parts to it.
38 * if it equals the actual component's index, then we only add its test
39 * to the actual condition
40 */
41 typedef struct{
42 const char* type;
43 const char* typedescr;
44 int start_pos;
45 int use_counter;
46 int decoded_for_element;
47 }temporal_variable;
48
49 void defUnionClass(struct_def const *sdef, output_struct *output)
50 {
51 size_t i;
52 const char *name = sdef->name, *dispname = sdef->dispname;
53 const char *at_field = sdef->kind==ANYTYPE ? "AT_" : "";
54 /* at_field is used to prefix the name of accessor member functions
55 * for the anytype, otherwise the generated "INTEGER()" will look like
56 * a constructor, upsetting the C++ compiler. AT_INTEGER() is ok. */
57 char *def = NULL, *src = NULL;
58 boolean ber_needed = sdef->isASN1 && enable_ber();
59 boolean raw_needed = sdef->hasRaw && enable_raw();
60 boolean text_needed = sdef->hasText && enable_text();
61 boolean xer_needed = sdef->hasXer && enable_xer();
62 boolean json_needed = sdef->hasJson && enable_json();
63
64 char *selection_type, *unbound_value, *selection_prefix;
65 selection_type = mcopystr("union_selection_type");
66 unbound_value = mcopystr("UNBOUND_VALUE");
67 selection_prefix = mcopystr("ALT");
68
69
70 /* class declaration */
71 output->header.class_decls = mputprintf(output->header.class_decls,
72 "class %s;\n", name);
73
74 /* class definition and source code */
75
76 /* class header and data fields*/
77 def = mputprintf(def,
78 #ifndef NDEBUG
79 "// written by defUnionClass in " __FILE__ " at %d\n"
80 #endif
81 "class %s : public Base_Type {\n"
82 #ifndef NDEBUG
83 , __LINE__
84 #endif
85 , name);
86 /* selection type (enum) definition */
87 def = mputstr(def, "public:\n"
88 "enum union_selection_type { UNBOUND_VALUE = 0");
89 for (i = 0; i < sdef->nElements; i++) {
90 def = mputprintf(def, ", ALT_%s = %lu", sdef->elements[i].name,
91 (unsigned long) (i + 1));
92 }
93 def = mputstr(def, " };\n"
94 "private:\n");
95
96 def = mputprintf(def, "%s union_selection;\n"
97 "union {\n", selection_type);
98 for (i = 0; i < sdef->nElements; i++) {
99 def = mputprintf(def, "%s *field_%s;\n", sdef->elements[i].type,
100 sdef->elements[i].name);
101 }
102 def = mputstr(def, "};\n");
103
104 if(ber_needed && sdef->ot) {
105 def=mputstr(def, "ASN_BER_TLV_t tlv_opentype;\n");
106 }
107
108 if (use_runtime_2) {
109 def=mputstr(def, "Erroneous_descriptor_t* err_descr;\n");
110 }
111
112 /* copy_value function */
113 def = mputprintf(def, "void copy_value(const %s& other_value);\n", name);
114 src = mputprintf(src, "void %s::copy_value(const %s& other_value)\n"
115 "{\n"
116 "switch (other_value.union_selection) {\n", name, name);
117 for (i = 0; i < sdef->nElements; i++) {
118 src = mputprintf(src, "case %s_%s:\n"
119 "field_%s = new %s(*other_value.field_%s);\n"
120 "break;\n", selection_prefix, sdef->elements[i].name,
121 sdef->elements[i].name, sdef->elements[i].type, sdef->elements[i].name);
122 }
123 src = mputprintf(src, "default:\n"
124 "TTCN_error(\"Assignment of an unbound union value of type %s.\");\n"
125 "}\n"
126 "union_selection = other_value.union_selection;\n", dispname);
127
128 if (use_runtime_2) {
129 src = mputstr(src, "err_descr = other_value.err_descr;\n");
130 }
131
132 src = mputstr(src, "}\n\n");
133
134 /* default constructor */
135 def = mputprintf(def, "\npublic:\n"
136 "%s();\n", name);
137 src = mputprintf(src, "%s::%s()%s\n"
138 "{\n"
139 "union_selection = %s;\n"
140 "}\n\n", name, name,
141 use_runtime_2 ? ": err_descr(NULL)" : "",
142 unbound_value);
143
144 /* copy constructor */
145 def = mputprintf(def, "%s(const %s& other_value);\n", name, name);
146 src = mputprintf(src, "%s::%s(const %s& other_value)\n"
147 ": Base_Type()" /* call the *default* constructor as before */
148 "{\n"
149 "copy_value(other_value);\n"
150 "}\n\n", name, name, name);
151
152 /* destructor */
153 def = mputprintf(def, "~%s();\n", name);
154 src = mputprintf(src, "%s::~%s()\n"
155 "{\n"
156 "clean_up();\n"
157 "}\n\n", name, name);
158
159 /* assignment operator */
160 def = mputprintf(def, "%s& operator=(const %s& other_value);\n", name, name);
161 src = mputprintf(src, "%s& %s::operator=(const %s& other_value)\n"
162 "{\n"
163 "if (this != &other_value) {\n"
164 "clean_up();\n"
165 "copy_value(other_value);\n"
166 "}\n"
167 "return *this;\n"
168 "}\n\n", name, name, name);
169
170 /* comparison operator */
171 def = mputprintf(def, "boolean operator==(const %s& other_value) const;\n",
172 name);
173 src = mputprintf(src, "boolean %s::operator==(const %s& other_value) const\n"
174 "{\n"
175 "if (union_selection == %s) TTCN_error(\"The left operand of comparison "
176 "is an unbound value of union type %s.\");\n"
177 "if (other_value.union_selection == %s) TTCN_error(\"The right operand of "
178 "comparison is an unbound value of union type %s.\");\n"
179 "if (union_selection != other_value.union_selection) return FALSE;\n"
180 "switch (union_selection) {\n", name, name, unbound_value, dispname,
181 unbound_value, dispname);
182 for (i = 0; i < sdef->nElements; i++) {
183 src = mputprintf(src, "case %s_%s:\n"
184 "return *field_%s == *other_value.field_%s;\n", selection_prefix,
185 sdef->elements[i].name, sdef->elements[i].name, sdef->elements[i].name);
186 }
187 src = mputstr(src, "default:\n"
188 "return FALSE;\n"
189 "}\n"
190 "}\n\n");
191
192 /* != and () operator */
193 def = mputprintf(def, "inline boolean operator!=(const %s& other_value) "
194 "const { return !(*this == other_value); }\n", name);
195
196 /* field access functions */
197 for (i = 0; i < sdef->nElements; i++) {
198 def = mputprintf(def, "%s& %s%s();\n", sdef->elements[i].type,
199 at_field, sdef->elements[i].name);
200 src = mputprintf(src, "%s& %s::%s%s()\n"
201 "{\n"
202 "if (union_selection != %s_%s) {\n"
203 "clean_up();\n"
204 "field_%s = new %s;\n"
205 "union_selection = %s_%s;\n"
206 "}\n"
207 "return *field_%s;\n"
208 "}\n\n", sdef->elements[i].type, name, at_field, sdef->elements[i].name,
209 selection_prefix, sdef->elements[i].name, sdef->elements[i].name,
210 sdef->elements[i].type, selection_prefix, sdef->elements[i].name,
211 sdef->elements[i].name);
212
213 def = mputprintf(def, "const %s& %s%s() const;\n", sdef->elements[i].type,
214 at_field, sdef->elements[i].name);
215 src = mputprintf(src, "const %s& %s::%s%s() const\n"
216 "{\n"
217 "if (union_selection != %s_%s) TTCN_error(\"Using non-selected field "
218 "%s in a value of union type %s.\");\n"
219 "return *field_%s;\n"
220 "}\n\n",
221 sdef->elements[i].type, name, at_field, sdef->elements[i].name, selection_prefix,
222 sdef->elements[i].name, sdef->elements[i].dispname, dispname,
223 sdef->elements[i].name);
224 }
225
226 /* get_selection function */
227 def = mputprintf(def, "inline %s get_selection() const "
228 "{ return union_selection; }\n", selection_type);
229
230 /* ischosen function */
231 def = mputprintf(def, "boolean ischosen(%s checked_selection) const;\n",
232 selection_type);
233 src = mputprintf(src, "boolean %s::ischosen(%s checked_selection) const\n"
234 "{\n"
235 "if (checked_selection == %s) TTCN_error(\"Internal error: Performing "
236 "ischosen() operation on an invalid field of union type %s.\");\n"
237 "if (union_selection == %s) TTCN_error(\"Performing ischosen() operation "
238 "on an unbound value of union type %s.\");\n"
239 "return union_selection == checked_selection;\n"
240 "}\n\n", name, selection_type, unbound_value, dispname, unbound_value,
241 dispname);
242
243 /* is_bound function */
244 def = mputstr (def, "boolean is_bound() const;\n");
245 src = mputprintf(src, "boolean %s::is_bound() const\n"
246 "{\n"
247 " return union_selection != %s;\n"
248 "}\n\n", name, unbound_value);
249
250 /* is_value function */
251 def = mputstr (def, "boolean is_value() const;\n");
252 src = mputprintf(src, "boolean %s::is_value() const\n"
253 "{\n"
254 "switch (union_selection) {\n"
255 "case %s: return FALSE;\n",
256 name, unbound_value);
257 for (i = 0; i < sdef->nElements; ++i) {
258 src = mputprintf(src, "case %s_%s: return field_%s->is_value();\n",
259 selection_prefix, sdef->elements[i].name, sdef->elements[i].name);
260 }
261 src = mputstr(src, "default: TTCN_error(\"Invalid selection in union is_bound\");"
262 "}\n"
263 "}\n\n");
264
265 /* clean_up function */
266 def = mputstr (def, "void clean_up();\n");
267 src = mputprintf(src, "void %s::clean_up()\n"
268 "{\n"
269 "switch (union_selection) {\n",
270 name);
271 for (i = 0; i < sdef->nElements; ++i) {
272 src = mputprintf(src, "case %s_%s:\n"
273 " delete field_%s;\n"
274 " break;\n",
275 selection_prefix, sdef->elements[i].name, sdef->elements[i].name);
276 }
277 src = mputprintf(src, "default:\n"
278 " break;\n"
279 "}\n"
280 "union_selection = %s;\n"
281 "}\n\n", unbound_value);
282
283 if (use_runtime_2) {
284 def = mputstr(def,
285 "boolean is_equal(const Base_Type* other_value) const;\n"
286 "void set_value(const Base_Type* other_value);\n"
287 "Base_Type* clone() const;\n"
288 "const TTCN_Typedescriptor_t* get_descriptor() const;\n"
289 "void set_err_descr(Erroneous_descriptor_t* p_err_descr) { err_descr=p_err_descr; }\n"
290 "Erroneous_descriptor_t* get_err_descr() const { return err_descr; }\n");
291 src = mputprintf(src,
292 "boolean %s::is_equal(const Base_Type* other_value) const "
293 "{ return *this == *(static_cast<const %s*>(other_value)); }\n"
294 "void %s::set_value(const Base_Type* other_value) "
295 "{ *this = *(static_cast<const %s*>(other_value)); }\n"
296 "Base_Type* %s::clone() const { return new %s(*this); }\n"
297 "const TTCN_Typedescriptor_t* %s::get_descriptor() const "
298 "{ return &%s_descr_; }\n",
299 name, name,
300 name, name,
301 name, name,
302 name, name);
303 } else {
304 def = mputstr(def,
305 "inline boolean is_present() const { return is_bound(); }\n");
306 }
307
308 /* log function */
309 def = mputstr(def, "void log() const;\n");
310 src = mputprintf(src, "void %s::log() const\n"
311 "{\n"
312 "switch (union_selection) {\n", name);
313 for (i = 0; i < sdef->nElements; i++) {
314 src = mputprintf(src, "case %s_%s:\n"
315 "TTCN_Logger::log_event_str(\"{ %s := \");\n"
316 "field_%s->log();\n"
317 "TTCN_Logger::log_event_str(\" }\");\n"
318 "break;\n", selection_prefix, sdef->elements[i].name,
319 sdef->elements[i].dispname, sdef->elements[i].name);
320 }
321 src = mputstr(src, "default:\n"
322 "TTCN_Logger::log_event_unbound();\n"
323 "}\n");
324 if (use_runtime_2) {
325 src = mputstr(src, "if (err_descr) err_descr->log();\n");
326 }
327 src = mputstr(src, "}\n\n");
328
329 /* set_param function */
330 def = mputstr(def, "void set_param(Module_Param& param);\n");
331 src = mputprintf(src, "void %s::set_param(Module_Param& param)\n"
332 "{\n"
333 " if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&\n"
334 " param.get_id()->next_name()) {\n"
335 // Haven't reached the end of the module parameter name
336 // => the name refers to one of the fields, not to the whole union
337 " char* param_field = param.get_id()->get_current_name();\n"
338 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
339 " param.error(\"Unexpected array index in module parameter, expected a valid field\"\n"
340 " \" name for union type `%s'\");\n"
341 " }\n"
342 " ", name, dispname);
343 for (i = 0; i < sdef->nElements; i++) {
344 src = mputprintf(src,
345 "if (strcmp(\"%s\", param_field) == 0) {\n"
346 " %s%s().set_param(param);\n"
347 " return;\n"
348 " } else ",
349 sdef->elements[i].dispname, at_field, sdef->elements[i].name);
350 }
351 src = mputprintf(src,
352 "param.error(\"Field `%%s' not found in union type `%s'\", param_field);\n"
353 " }\n"
354 " param.basic_check(Module_Param::BC_VALUE, \"union value\");\n"
355 " Module_Param_Ptr m_p = &param;\n"
356 " if (param.get_type() == Module_Param::MP_Reference) {\n"
357 " m_p = param.get_referenced_param();\n"
358 " }\n"
359 " if (m_p->get_type()==Module_Param::MP_Value_List && m_p->get_size()==0) return;\n"
360 " if (m_p->get_type()!=Module_Param::MP_Assignment_List) {\n"
361 " param.error(\"union value with field name was expected\");\n"
362 " }\n"
363 " Module_Param* mp_last = m_p->get_elem(m_p->get_size()-1);\n", dispname);
364
365 for (i = 0; i < sdef->nElements; i++) {
366 src = mputprintf(src,
367 " if (!strcmp(mp_last->get_id()->get_name(), \"%s\")) {\n"
368 " %s%s().set_param(*mp_last);\n"
369 " return;\n"
370 " }\n", sdef->elements[i].dispname, at_field, sdef->elements[i].name);
371 }
372 src = mputprintf(src,
373 " mp_last->error(\"Field %%s does not exist in type %s.\", mp_last->get_id()->get_name());\n"
374 "}\n\n", dispname);
375
376 /* get param function */
377 def = mputstr(def, "Module_Param* get_param(Module_Param_Name& param_name) const;\n");
378 src = mputprintf(src,
379 "Module_Param* %s::get_param(Module_Param_Name& param_name) const\n"
380 "{\n"
381 " if (!is_bound()) {\n"
382 " return new Module_Param_Unbound();\n"
383 " }\n"
384 " if (param_name.next_name()) {\n"
385 // Haven't reached the end of the module parameter name
386 // => the name refers to one of the fields, not to the whole union
387 " char* param_field = param_name.get_current_name();\n"
388 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
389 " TTCN_error(\"Unexpected array index in module parameter reference, \"\n"
390 " \"expected a valid field name for union type `%s'\");\n"
391 " }\n"
392 " ", name, dispname);
393 for (i = 0; i < sdef->nElements; i++) {
394 src = mputprintf(src,
395 "if (strcmp(\"%s\", param_field) == 0) {\n"
396 " return %s%s().get_param(param_name);\n"
397 " } else ",
398 sdef->elements[i].dispname, at_field, sdef->elements[i].name);
399 }
400 src = mputprintf(src,
401 "TTCN_error(\"Field `%%s' not found in union type `%s'\", param_field);\n"
402 " }\n"
403 " Module_Param* mp_field = NULL;\n"
404 " switch(union_selection) {\n"
405 , name);
406 for (i = 0; i < sdef->nElements; ++i) {
407 src = mputprintf(src,
408 " case %s_%s:\n"
409 " mp_field = field_%s->get_param(param_name);\n"
410 " mp_field->set_id(new Module_Param_FieldName(mcopystr(\"%s\")));\n"
411 " break;\n"
412 , selection_prefix, sdef->elements[i].name
413 , sdef->elements[i].name, sdef->elements[i].dispname);
414 }
415 src = mputstr(src,
416 " default:\n"
417 " break;\n"
418 " }\n"
419 " Module_Param_Assignment_List* m_p = new Module_Param_Assignment_List();\n"
420 " m_p->add_elem(mp_field);\n"
421 " return m_p;\n"
422 "}\n\n");
423
424 /* set implicit omit function, recursive */
425 def = mputstr(def, " void set_implicit_omit();\n");
426 src = mputprintf(src,
427 "void %s::set_implicit_omit()\n{\n"
428 "switch (union_selection) {\n", name);
429 for (i = 0; i < sdef->nElements; i++) {
430 src = mputprintf(src,
431 "case %s_%s:\n"
432 "field_%s->set_implicit_omit(); break;\n",
433 selection_prefix, sdef->elements[i].name, sdef->elements[i].name);
434 }
435 src = mputstr(src, "default: break;\n}\n}\n\n");
436
437 /* encode_text function */
438 def = mputstr(def, "void encode_text(Text_Buf& text_buf) const;\n");
439 src = mputprintf(src, "void %s::encode_text(Text_Buf& text_buf) const\n"
440 "{\n"
441 "text_buf.push_int(union_selection);\n"
442 "switch (union_selection) {\n", name);
443 for (i = 0; i < sdef->nElements; i++) {
444 src = mputprintf(src, "case %s_%s:\n"
445 "field_%s->encode_text(text_buf);\n"
446 "break;\n", selection_prefix, sdef->elements[i].name,
447 sdef->elements[i].name);
448 }
449 src = mputprintf(src, "default:\n"
450 "TTCN_error(\"Text encoder: Encoding an unbound value of union type "
451 "%s.\");\n"
452 "}\n"
453 "}\n\n", dispname);
454
455 /* decode_text function */
456 def = mputstr(def, "void decode_text(Text_Buf& text_buf);\n");
457 src = mputprintf(src, "void %s::decode_text(Text_Buf& text_buf)\n"
458 "{\n"
459 "switch ((%s)text_buf.pull_int().get_val()) {\n", name, selection_type);
460 for (i = 0; i < sdef->nElements; i++) {
461 src = mputprintf(src, "case %s_%s:\n"
462 "%s%s().decode_text(text_buf);\n"
463 "break;\n", selection_prefix, sdef->elements[i].name,
464 at_field, sdef->elements[i].name);
465 }
466 src = mputprintf(src, "default:\n"
467 "TTCN_error(\"Text decoder: Unrecognized union selector was received "
468 "for type %s.\");\n"
469 "}\n"
470 "}\n\n", dispname);
471
472 if(ber_needed || raw_needed || text_needed || xer_needed || json_needed)
473 def_encdec(name, &def, &src, ber_needed, raw_needed, text_needed,
474 xer_needed, json_needed, TRUE);
475
476 /* BER functions */
477 if(ber_needed) {
478 def = mputstr(def, "private:\n"
479 "boolean BER_decode_set_selection(const ASN_BER_TLV_t& p_tlv);\n"
480 "public:\n"
481 "boolean BER_decode_isMyMsg(const TTCN_Typedescriptor_t& p_td, "
482 "const ASN_BER_TLV_t& p_tlv);\n");
483
484 /* BER_encode_TLV() */
485 src = mputprintf(src,
486 #ifndef NDEBUG
487 "// written by %s in " __FILE__ " at %d\n"
488 #endif
489 "ASN_BER_TLV_t *%s::BER_encode_TLV("
490 "const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const\n"
491 "{\n"
492 #ifndef NDEBUG
493 , __FUNCTION__, __LINE__
494 #endif
495 , name);
496 if (use_runtime_2) {
497 src = mputstr(src,
498 " if (err_descr) return BER_encode_TLV_negtest(err_descr, p_td, p_coding);\n");
499 }
500 src = mputstr(src,
501 " BER_chk_descr(p_td);\n"
502 " ASN_BER_TLV_t *new_tlv;\n"
503 " TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n"
504 " TTCN_EncDec_ErrorContext ec_1;\n"
505 " switch (union_selection) {\n");
506 for (i = 0; i < sdef->nElements; i++) {
507 src = mputprintf(src, " case %s_%s:\n"
508 " ec_1.set_msg(\"%s': \");\n"
509 " new_tlv = field_%s->BER_encode_TLV(%s_descr_, p_coding);\n"
510 " break;\n", selection_prefix, sdef->elements[i].name,
511 sdef->elements[i].dispname,
512 sdef->elements[i].name, sdef->elements[i].typedescrname);
513 } /* for i */
514 src = mputprintf(src, " case %s:\n"
515 " new_tlv = BER_encode_chk_bound(FALSE);\n"
516 " break;\n"
517 " default:\n"
518 " TTCN_EncDec_ErrorContext::error_internal(\"Unknown selection.\");\n"
519 " new_tlv = NULL;\n"
520 " }\n" /* switch */
521 " return ASN_BER_V2TLV(new_tlv, p_td, p_coding);\n"
522 "}\n\n", unbound_value);
523
524 if (use_runtime_2) { /* BER_encode_TLV_negtest() */
525 def = mputstr(def,
526 "ASN_BER_TLV_t* BER_encode_TLV_negtest(const Erroneous_descriptor_t* p_err_descr, const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const;\n");
527 src = mputprintf(src,
528 "ASN_BER_TLV_t *%s::BER_encode_TLV_negtest(const Erroneous_descriptor_t* p_err_descr, "
529 "const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const\n"
530 "{\n"
531 " BER_chk_descr(p_td);\n"
532 " ASN_BER_TLV_t *new_tlv = NULL;\n"
533 " TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n"
534 " TTCN_EncDec_ErrorContext ec_1;\n"
535 " const Erroneous_values_t* err_vals = NULL;\n"
536 " const Erroneous_descriptor_t* emb_descr = NULL;\n"
537 " switch (union_selection) {\n", name);
538 for (i = 0; i < sdef->nElements; i++) {
539 src = mputprintf(src, " case %s_%s:\n"
540 " err_vals = p_err_descr->get_field_err_values(%d);\n"
541 " emb_descr = p_err_descr->get_field_emb_descr(%d);\n"
542 " if (err_vals && err_vals->value) {\n"
543 " if (err_vals->value->errval) {\n"
544 " ec_1.set_msg(\"%s'(erroneous value): \");\n"
545 " if (err_vals->value->raw) {\n"
546 " new_tlv = err_vals->value->errval->BER_encode_negtest_raw();\n"
547 " } else {\n"
548 " if (err_vals->value->type_descr==NULL) TTCN_error(\"internal error: erroneous value typedescriptor missing\");\n"
549 " new_tlv = err_vals->value->errval->BER_encode_TLV(*err_vals->value->type_descr, p_coding);\n"
550 " }\n"
551 " }\n"
552 " } else {\n"
553 " ec_1.set_msg(\"%s': \");\n"
554 " if (emb_descr) new_tlv = field_%s->BER_encode_TLV_negtest(emb_descr, %s_descr_, p_coding);\n"
555 " else new_tlv = field_%s->BER_encode_TLV(%s_descr_, p_coding);\n"
556 " }\n"
557 " break;\n", selection_prefix, sdef->elements[i].name,
558 (int)i, (int)i, sdef->elements[i].dispname, sdef->elements[i].dispname,
559 sdef->elements[i].name, sdef->elements[i].typedescrname,
560 sdef->elements[i].name, sdef->elements[i].typedescrname);
561 } /* for i */
562 src = mputprintf(src, " case %s:\n"
563 " new_tlv = BER_encode_chk_bound(FALSE);\n"
564 " break;\n"
565 " default:\n"
566 " TTCN_EncDec_ErrorContext::error_internal(\"Unknown selection.\");\n"
567 " new_tlv = NULL;\n"
568 " }\n" /* switch */
569 " if (new_tlv==NULL) new_tlv=ASN_BER_TLV_t::construct(NULL);\n"
570 " return ASN_BER_V2TLV(new_tlv, p_td, p_coding);\n"
571 "}\n\n", unbound_value);
572 }
573
574 /* BER_decode_set_selection() */
575 src = mputprintf(src, "boolean %s::BER_decode_set_selection("
576 "const ASN_BER_TLV_t& p_tlv)\n"
577 "{\n"
578 " clean_up();\n", name);
579 for (i = 0; i < sdef->nElements; i++) {
580 src = mputprintf(src, " field_%s = new %s;\n"
581 " union_selection = %s_%s;\n"
582 " if (field_%s->BER_decode_isMyMsg(%s_descr_, p_tlv)) return TRUE;\n"
583 " delete field_%s;\n", sdef->elements[i].name, sdef->elements[i].type,
584 selection_prefix, sdef->elements[i].name, sdef->elements[i].name,
585 sdef->elements[i].typedescrname, sdef->elements[i].name);
586 } /* for i */
587 src = mputprintf(src, " union_selection = %s;\n"
588 " return FALSE;\n"
589 "}\n\n", unbound_value);
590
591 /* BER_decode_isMyMsg() */
592 src = mputprintf(src, "boolean %s::BER_decode_isMyMsg("
593 "const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv)\n"
594 "{\n"
595 " if (p_td.ber->n_tags == 0) {\n"
596 " %s tmp_type;\n"
597 " return tmp_type.BER_decode_set_selection(p_tlv);\n"
598 " } else return Base_Type::BER_decode_isMyMsg(p_td, p_tlv);\n"
599 "}\n\n", name, name);
600
601 /* BER_decode_TLV() */
602 src = mputprintf(src, "boolean %s::BER_decode_TLV("
603 "const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, "
604 "unsigned L_form)\n"
605 "{\n"
606 " BER_chk_descr(p_td);\n"
607 " ASN_BER_TLV_t stripped_tlv;\n"
608 " BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);\n"
609 " TTCN_EncDec_ErrorContext ec_0(\"While decoding '%s' type: \");\n",
610 name, dispname);
611 if (sdef->ot) {
612 src = mputprintf(src, " if (!BER_decode_TLV_CHOICE(*p_td.ber, "
613 "stripped_tlv, L_form, tlv_opentype)) {\n"
614 " tlv_opentype.Tlen = 0;\n"
615 " return FALSE;\n"
616 " }\n"
617 " clean_up();\n"
618 " union_selection = %s;\n", unbound_value);
619 } else {
620 src = mputstr(src, " ASN_BER_TLV_t tmp_tlv;\n"
621 " if (!BER_decode_TLV_CHOICE(*p_td.ber, stripped_tlv, L_form, "
622 "tmp_tlv) || "
623 "!BER_decode_CHOICE_selection(BER_decode_set_selection(tmp_tlv), "
624 "tmp_tlv)) return FALSE;\n"
625 " TTCN_EncDec_ErrorContext ec_1(\"Alternative '\");\n"
626 " TTCN_EncDec_ErrorContext ec_2;\n"
627 " switch (union_selection) {\n");
628 for(i = 0; i < sdef->nElements; i++) {
629 src = mputprintf(src, " case %s_%s:\n"
630 " ec_2.set_msg(\"%s': \");\n"
631 " field_%s->BER_decode_TLV(%s_descr_, tmp_tlv, L_form);\n"
632 " break;\n", selection_prefix, sdef->elements[i].name,
633 sdef->elements[i].dispname,
634 sdef->elements[i].name, sdef->elements[i].typedescrname);
635 } /* for i */
636 src = mputstr(src, " default:\n"
637 " return FALSE;\n"
638 " }\n");
639 if (sdef->opentype_outermost) {
640 src = mputstr(src,
641 " TTCN_EncDec_ErrorContext ec_1(\"While decoding opentypes: \");\n"
642 " TTCN_Type_list p_typelist;\n"
643 " BER_decode_opentypes(p_typelist, L_form);\n");
644 } /* if sdef->opentype_outermost */
645 }
646 src = mputstr(src, " return TRUE;\n"
647 "}\n\n");
648
649 if (sdef->ot || sdef->has_opentypes) { /* theoretically, these are
650 mutually exlusive */
651 /* BER_decode_opentypes() */
652 def = mputstr(def, "void BER_decode_opentypes("
653 "TTCN_Type_list& p_typelist, unsigned L_form);\n");
654 src = mputprintf(src, "void %s::BER_decode_opentypes("
655 "TTCN_Type_list& p_typelist, unsigned L_form)\n"
656 "{\n", name);
657 if (sdef->ot) {
658 AtNotationList_t *anl = &sdef->ot->anl;
659 OpentypeAlternativeList_t *oal = &sdef->ot->oal;
660 src = mputprintf(src,
661 " if (union_selection != %s) return;\n"
662 " TTCN_EncDec_ErrorContext ec_0(\"While decoding open type '%s': "
663 "\");\n", unbound_value, dispname);
664 if (oal->nElements > 0) {
665 size_t oal_i, anl_i;
666 char *s2;
667 /* variable declarations - the referenced components */
668 for (anl_i = 0; anl_i < anl->nElements; anl_i++) {
669 AtNotation_t *an = anl->elements + anl_i;
670 src = mputprintf(src, " const %s& f_%lu = static_cast<const %s*>"
671 "(p_typelist.get_nth(%lu))->%s;\n", an->type_name,
672 (unsigned long) (anl_i + 1), an->parent_typename,
673 (unsigned long) an->parent_level, an->sourcecode);
674 } /* for anl_i */
675 src = mputstr(src, " {\n"
676 " TTCN_EncDec_ErrorContext ec_1(\"Alternative '\");\n"
677 " TTCN_EncDec_ErrorContext ec_2;\n");
678 s2 = mprintf("%*s", (int)(anl->nElements + 2) * 2, "");
679 for (oal_i = 0; oal_i < oal->nElements; oal_i++) {
680 size_t if_level;
681 OpentypeAlternative_t *oa = oal->elements + oal_i;
682 if (oal_i > 0) {
683 for (if_level = 0; if_level < anl->nElements; if_level++)
684 if (oa->const_valuenames[if_level]) break;
685 for (i = anl->nElements; i > if_level; i--)
686 src = mputprintf(src, "%*s}\n", (int)(i + 1) * 2, "");
687 } /* if oal_i */
688 else if_level = 0;
689 for (anl_i = if_level; anl_i < anl->nElements; anl_i++) {
690 src = mputprintf(src, "%*s%sif (f_%lu == %s) {\n",
691 (int)(anl_i + 2) * 2, "",
692 oal_i && anl_i <= if_level ? "else " : "",
693 (unsigned long) (anl_i + 1), oa->const_valuenames[anl_i]);
694 } /* for anl_i */
695 src = mputprintf(src, "%sunion_selection = %s_%s;\n"
696 "%sfield_%s = new %s;\n"
697 "%sec_2.set_msg(\"%s': \");\n"
698 "%sfield_%s->BER_decode_TLV(%s_descr_, tlv_opentype, L_form);\n",
699 s2, selection_prefix, oa->alt, s2, oa->alt, oa->alt_typename, s2,
700 oa->alt_dispname, s2, oa->alt, oa->alt_typedescrname);
701 } /* for oal_i */
702 Free(s2);
703 if (oal->nElements > 0)
704 for (i = anl->nElements; i > 0; i--)
705 src = mputprintf(src, "%*s}\n", (int)(i+1)*2, "");
706 src = mputprintf(src, " }\n"
707 " if (union_selection == %s) {\n"
708 " ec_0.error(TTCN_EncDec::ET_DEC_OPENTYPE, \"Cannot decode "
709 "open type: broken component relation constraint.\");\n"
710 " if (TTCN_EncDec::get_error_behavior("
711 "TTCN_EncDec::ET_DEC_OPENTYPE) != TTCN_EncDec::EB_IGNORE) {\n"
712 " TTCN_Logger::log_str(TTCN_WARNING, \"The value%s of"
713 " constraining component%s:\");\n", unbound_value,
714 anl->nElements > 1 ? "s" : "", anl->nElements > 1 ? "s" : "");
715 for (anl_i = 0; anl_i < anl->nElements; anl_i++) {
716 AtNotation_t *an = anl->elements + anl_i;
717 src = mputprintf(src,
718 " TTCN_Logger::begin_event(TTCN_WARNING);\n"
719 " TTCN_Logger::log_event_str(\"Component '%s': \");\n"
720 " f_%lu.log();\n"
721 " TTCN_Logger::end_event();\n", an->dispname,
722 (unsigned long) (anl_i + 1));
723 } /* for anl_i */
724 src = mputstr(src, " }\n"
725 " }\n");
726 } /* if oal->nElements>0 */
727 else {
728 src = mputstr(src, " ec_0.error(TTCN_EncDec::ET_DEC_OPENTYPE, "
729 "\"Cannot decode open type: the constraining object set is "
730 "empty.\");\n");
731 } /* oal->nElements==0 */
732 } /* if sdef->ot */
733 else { /* if !sdef->ot (but has_opentypes) */
734 src = mputstr(src,
735 " p_typelist.push(this);\n"
736 " TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n"
737 " TTCN_EncDec_ErrorContext ec_1;\n"
738 " switch (union_selection) {\n");
739 for (i = 0; i < sdef->nElements; i++) {
740 src = mputprintf(src, " case %s_%s:\n"
741 " ec_1.set_msg(\"%s': \");\n"
742 " field_%s->BER_decode_opentypes(p_typelist, L_form);\n"
743 " break;\n", selection_prefix, sdef->elements[i].name,
744 sdef->elements[i].dispname, sdef->elements[i].name);
745 } /* for i */
746 src = mputstr(src, " default:\n"
747 " break;\n"
748 " }\n"
749 " p_typelist.pop();\n");
750 } /* if has opentypes */
751 src = mputstr(src, "}\n"
752 "\n");
753 } /* if sdef->ot || sdef->has_opentypes */
754 } /* if ber_needed */
755
756 if (raw_needed) {
757 size_t nTemp_variables = 0;
758 temporal_variable* temp_variable_list = NULL;
759 int* tag_type = (int*) Malloc(sdef->nElements*sizeof(int));
760 memset(tag_type, 0, sdef->nElements * sizeof(int));
761 if (sdef->hasRaw) { /* fill tag_type. 0-No tag, >0 index of the tag + 1 */
762 for (i = 0; i < sdef->raw.taglist.nElements; i++) {
763 if (sdef->raw.taglist.list[i].nElements) {
764 boolean found = FALSE;
765 size_t v;
766 for (v = 0; v < sdef->raw.taglist.list[i].nElements; v++) {
767 if (sdef->raw.taglist.list[i].fields[v].start_pos >= 0) {
768 found = TRUE;
769 break;
770 }
771 }
772 if (found)
773 tag_type[sdef->raw.taglist.list[i].fieldnum] = i + 1;
774 else
775 tag_type[sdef->raw.taglist.list[i].fieldnum] = -i - 1;
776 }
777 }
778 }
779 src = mputprintf(src, "int %s::RAW_decode(\n"
780 "const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, \n"
781 "raw_order_t top_bit_ord, boolean no_err, int sel_field, boolean)\n"
782 "{\n"
783 " int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);\n"
784 " limit-=prepaddlength;\n"
785 " int decoded_length=0;\n"
786 " int starting_pos=p_buf.get_pos_bit();\n"
787 " if(sel_field!=-1){\n"
788 " switch(sel_field){\n", name);
789 for (i = 0; i < sdef->nElements; i++) {
790 src = mputprintf(src,
791 " case %lu:\n"
792 " decoded_length = %s().RAW_decode(%s_descr_, p_buf, limit, "
793 "top_bit_ord, no_err);\n"
794 " break;\n", (unsigned long) i, sdef->elements[i].name,
795 sdef->elements[i].typedescrname);
796 }
797 src = mputstr(src, " default: break;\n"
798 " }\n"
799 " return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + "
800 "prepaddlength;\n"
801 " } else {\n");
802 /* only generate this variable if it will be used */
803 for (i = 0; i < sdef->nElements; i++) {
804 if ((tag_type[i] > 0)
805 && (sdef->raw.taglist.list + tag_type[i] - 1)->nElements) {
806 src = mputstr(src, " boolean already_failed = FALSE;\n");
807 break;
808 }
809 }
810
811 /* precalculate what we know about the temporal variables*/
812 for (i = 0; i < sdef->nElements; i++) {
813 if ((tag_type[i] > 0)
814 && (sdef->raw.taglist.list + tag_type[i] - 1)->nElements) {
815 rawAST_coding_taglist* cur_choice = sdef->raw.taglist.list + tag_type[i] - 1;
816 size_t j;
817 for (j = 0; j < cur_choice->nElements; j++) {
818 rawAST_coding_field_list *fieldlist = cur_choice->fields + j;
819 if (fieldlist->start_pos >= 0) {
820 size_t k;
821 boolean found = FALSE;
822 for (k = 0; k < nTemp_variables; k++) {
823 if (temp_variable_list[k].start_pos == fieldlist->start_pos
824 && !strcmp(temp_variable_list[k].typedescr,
825 fieldlist->fields[fieldlist->nElements - 1].typedescr)) {
826 temp_variable_list[k].use_counter++;
827 fieldlist->temporal_variable_index = k;
828 found = TRUE;
829 break;
830 }
831 }
832 if (!found) {
833 temp_variable_list
834 = (temporal_variable*) Realloc(temp_variable_list,
835 (nTemp_variables + 1) * sizeof(*temp_variable_list));
836 temp_variable_list[nTemp_variables].type
837 = fieldlist->fields[fieldlist->nElements - 1].type;
838 temp_variable_list[nTemp_variables].typedescr
839 = fieldlist->fields[fieldlist->nElements - 1].typedescr;
840 temp_variable_list[nTemp_variables].start_pos
841 = fieldlist->start_pos;
842 temp_variable_list[nTemp_variables].use_counter = 1;
843 temp_variable_list[nTemp_variables].decoded_for_element
844 = -1;
845 fieldlist->temporal_variable_index = nTemp_variables;
846 nTemp_variables++;
847 }
848 }
849 }
850 }
851 }
852
853 for (i = 0; i < nTemp_variables; i++) {
854 if (temp_variable_list[i].use_counter > 1) {
855 src = mputprintf(src, " %s temporal_%lu;\n"
856 " int decoded_%lu_length;\n", temp_variable_list[i].type,
857 (unsigned long) i, (unsigned long) i);
858 }
859 }
860
861 for (i = 0; i < sdef->nElements; i++) { /* fields with tag */
862 if ((tag_type[i] > 0)
863 && (sdef->raw.taglist.list + tag_type[i] - 1)->nElements) {
864 rawAST_coding_taglist* cur_choice = sdef->raw.taglist.list
865 + tag_type[i] - 1;
866 size_t j;
867 src = mputstr(src, " already_failed = FALSE;\n");
868 /* first check the fields we can precode
869 * try to decode those key variables whose position we know
870 * this way we might be able to step over bad values faster
871 */
872 for (j = 0; j < cur_choice->nElements; j++) {
873 rawAST_coding_field_list *cur_field_list = cur_choice->fields + j;
874 if (cur_field_list->start_pos >= 0) {
875 size_t k;
876 size_t variable_index = cur_field_list->temporal_variable_index;
877 if (temp_variable_list[variable_index].decoded_for_element == i) continue;
878 src = mputstr(src, " if (!already_failed) {\n");
879 if (temp_variable_list[variable_index].use_counter == 1) {
880 src = mputprintf(src, " %s temporal_%lu;\n"
881 " int decoded_%lu_length;\n",
882 temp_variable_list[variable_index].type,
883 (unsigned long) variable_index, (unsigned long) variable_index);
884 }
885 if (temp_variable_list[variable_index].decoded_for_element
886 == -1) {
887 src = mputprintf(src,
888 " p_buf.set_pos_bit(starting_pos + %d);\n"
889 " decoded_%lu_length = temporal_%lu.RAW_decode("
890 "%s_descr_, p_buf, limit, top_bit_ord, TRUE);\n",
891 cur_field_list->start_pos, (unsigned long) variable_index,
892 (unsigned long) variable_index,
893 temp_variable_list[variable_index].typedescr);
894 }
895 temp_variable_list[variable_index].decoded_for_element = i;
896 src = mputprintf(src, " if (decoded_%lu_length > 0) {\n"
897 " if (temporal_%lu == %s", (unsigned long) variable_index,
898 (unsigned long) variable_index, cur_field_list->value);
899 for (k = j + 1; k < cur_choice->nElements; k++) {
900 if (cur_choice->fields[k].temporal_variable_index
901 == variable_index) {
902 src = mputprintf(src, " || temporal_%lu == %s",
903 (unsigned long) variable_index, cur_choice->fields[k].value);
904 }
905 }
906 src = mputprintf(src, ") {\n"
907 " p_buf.set_pos_bit(starting_pos);\n"
908 " decoded_length = %s().RAW_decode(%s_descr_, p_buf, "
909 "limit, top_bit_ord, TRUE);\n"
910 " if (decoded_length > 0) {\n", sdef->elements[i].name,
911 sdef->elements[i].typedescrname);
912 src = mputstr(src, " if (");
913 src = genRawFieldChecker(src, cur_choice, TRUE);
914 src = mputstr(src, ") {\n"
915 " return decoded_length + "
916 "p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;\n"
917 " }else already_failed = TRUE;\n"
918 " }\n"
919 " }\n"
920 " }\n"
921 " }\n");
922 }
923 }
924 /* if there is one tag key whose position we don't know
925 * and we couldn't decide yet if the element can be decoded or not
926 * than we have to decode it.
927 * note that this is not actually a cycle because of the break
928 */
929 for (j = 0; j < cur_choice->nElements; j++) {
930 if (cur_choice->fields[j].start_pos < 0) {
931 src = mputprintf(src, " if (already_failed) {\n"
932 " p_buf.set_pos_bit(starting_pos);\n"
933 " decoded_length = %s().RAW_decode(%s_descr_, p_buf, limit, "
934 "top_bit_ord, TRUE);\n"
935 " if (decoded_length > 0) {\n", sdef->elements[i].name,
936 sdef->elements[i].typedescrname);
937 src = mputstr(src, " if (");
938 src = genRawFieldChecker(src, cur_choice, TRUE);
939 src = mputstr(src, ") {\n"
940 " return decoded_length + "
941 "p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;\n"
942 " }\n"
943 " }\n"
944 " }\n");
945 break;
946 }
947 }
948 }
949 }
950 Free(temp_variable_list);
951 for (i = 0; i < sdef->nElements; i++) { /* fields with only variable tag */
952 if ((tag_type[i] < 0)
953 && (sdef->raw.taglist.list - tag_type[i] - 1)->nElements) {
954 rawAST_coding_taglist* cur_choice = sdef->raw.taglist.list
955 - tag_type[i] - 1;
956 src = mputprintf(src, " p_buf.set_pos_bit(starting_pos);\n"
957 " decoded_length = %s().RAW_decode(%s_descr_, p_buf, limit, "
958 "top_bit_ord, TRUE);\n"
959 " if (decoded_length >= 0) {\n", sdef->elements[i].name,
960 sdef->elements[i].typedescrname);
961 src = mputstr(src, " if (");
962 src = genRawFieldChecker(src, cur_choice, TRUE);
963 src = mputstr(src, ") {\n"
964 " return decoded_length + "
965 "p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;\n"
966 " }\n"
967 " }\n");
968 }
969 }/**/
970 for (i = 0; i < sdef->nElements; i++) { /* fields without tag */
971 if (!tag_type[i]) {
972 src = mputprintf(src, " p_buf.set_pos_bit(starting_pos);\n"
973 " decoded_length = %s().RAW_decode(%s_descr_, p_buf, limit, "
974 "top_bit_ord, TRUE);\n"
975 " if (decoded_length >= 0) {\n", sdef->elements[i].name,
976 sdef->elements[i].typedescrname);
977 src = mputstr(src, " return decoded_length + "
978 "p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;\n"
979 " }\n");
980 }
981 }/**/
982 src = mputstr(src, " }\n"
983 " clean_up();\n"
984 " return -1;\n"
985 "}\n\n");
986 /* encoder */
987 src = mputprintf(src, "int %s::RAW_encode("
988 "const TTCN_Typedescriptor_t&%s, RAW_enc_tree& myleaf) const\n"
989 "{\n", name, use_runtime_2 ? " p_td" : "");
990 if (use_runtime_2) {
991 src = mputstr(src, " if (err_descr) return RAW_encode_negtest(err_descr, p_td, myleaf);\n");
992 }
993 src = mputprintf(src,
994 " int encoded_length = 0;\n"
995 " myleaf.isleaf = FALSE;\n"
996 " myleaf.body.node.num_of_nodes = %lu;"
997 " myleaf.body.node.nodes = init_nodes_of_enc_tree(%lu);\n"
998 " memset(myleaf.body.node.nodes, 0, %lu * sizeof(RAW_enc_tree *));\n"
999 " switch (union_selection) {\n", (unsigned long)sdef->nElements,
1000 (unsigned long)sdef->nElements, (unsigned long)sdef->nElements);
1001 for (i = 0; i < sdef->nElements; i++) {
1002 int t_type = tag_type[i] > 0 ? tag_type[i] : -tag_type[i];
1003 src = mputprintf(src, " case %s_%s:\n"
1004 " myleaf.body.node.nodes[%lu] = new RAW_enc_tree(TRUE, &myleaf, "
1005 "&myleaf.curr_pos, %lu, %s_descr_.raw);\n"
1006 " encoded_length = field_%s->RAW_encode(%s_descr_, "
1007 "*myleaf.body.node.nodes[%lu]);\n"
1008 " myleaf.body.node.nodes[%lu]->coding_descr = &%s_descr_;\n",
1009 selection_prefix, sdef->elements[i].name, (unsigned long) i,
1010 (unsigned long) i, sdef->elements[i].typedescrname,
1011 sdef->elements[i].name, sdef->elements[i].typedescrname,
1012 (unsigned long) i, (unsigned long) i, sdef->elements[i].typedescrname);
1013 if (t_type && (sdef->raw.taglist.list + t_type - 1)->nElements) {
1014 rawAST_coding_taglist* cur_choice = sdef->raw.taglist.list + t_type - 1;
1015 src = mputstr(src, " if (");
1016 src = genRawFieldChecker(src, cur_choice, FALSE);
1017 src = mputstr(src, ") {\n");
1018 src = genRawTagChecker(src, cur_choice);
1019 src = mputstr(src, " }\n");
1020 }
1021 src = mputstr(src, " break;\n");
1022 }
1023 src = mputstr(src, " default:\n"
1024 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "
1025 "\"Encoding an unbound value.\");\n"
1026 " }\n"
1027 " return encoded_length;\n"
1028 "}\n\n");
1029 if (use_runtime_2) {
1030 def = mputstr(def, "int RAW_encode_negtest(const Erroneous_descriptor_t *, "
1031 "const TTCN_Typedescriptor_t&, RAW_enc_tree&) const;\n");
1032 src = mputprintf(src, "int %s::RAW_encode_negtest(const Erroneous_descriptor_t *p_err_descr, "
1033 "const TTCN_Typedescriptor_t& /*p_td*/, RAW_enc_tree& myleaf) const\n"
1034 "{\n"
1035 " const Erroneous_values_t *err_vals = NULL;\n"
1036 " const Erroneous_descriptor_t *emb_descr = NULL;\n"
1037 " int encoded_length = 0;\n"
1038 " myleaf.isleaf = FALSE;\n"
1039 " myleaf.body.node.num_of_nodes = %lu;\n"
1040 " myleaf.body.node.nodes = init_nodes_of_enc_tree(%lu);\n"
1041 " memset(myleaf.body.node.nodes, 0, %lu * sizeof(RAW_enc_tree *));\n"
1042 " switch (union_selection) {\n", name, (unsigned long)sdef->nElements,
1043 (unsigned long)sdef->nElements, (unsigned long)sdef->nElements);
1044 for (i = 0; i < sdef->nElements; i++) {
1045 int t_type = tag_type[i] > 0 ? tag_type[i] : -tag_type[i];
1046 src = mputprintf(src,
1047 " case %s_%s: {\n",
1048 selection_prefix, sdef->elements[i].name);
1049 if (t_type && (sdef->raw.taglist.list + t_type - 1)->nElements) {
1050 src = mputstr(src, " bool negtest_confl_tag = false;\n");
1051 }
1052 src = mputprintf(src,
1053 " err_vals = p_err_descr->get_field_err_values(%d);\n"
1054 " emb_descr = p_err_descr->get_field_emb_descr(%d);\n"
1055 " if (err_vals && err_vals->value) {\n"
1056 " if (err_vals->value->raw) {\n"
1057 " myleaf.body.node.nodes[%lu] =\n"
1058 " new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, %lu, "
1059 "err_vals->value->errval->get_descriptor()->raw);\n"
1060 " encoded_length = err_vals->value->errval->RAW_encode_negtest_raw(*myleaf.body.node.nodes[%lu]);\n"
1061 " myleaf.body.node.nodes[%lu]->coding_descr = err_vals->value->errval->get_descriptor();\n"
1062 " } else {\n"
1063 " if (err_vals->value->errval) {\n"
1064 " if (err_vals->value->type_descr == NULL)\n"
1065 " TTCN_error(\"internal error: erroneous value typedescriptor missing\");\n"
1066 " myleaf.body.node.nodes[%lu] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, %lu, err_vals->value->type_descr->raw);\n"
1067 " encoded_length = err_vals->value->errval->RAW_encode(*err_vals->value->type_descr, *myleaf.body.node.nodes[%lu]);\n"
1068 " myleaf.body.node.nodes[%lu]->coding_descr = err_vals->value->type_descr;\n"
1069 " }\n"
1070 " }\n",
1071 (int)i, (int)i,
1072 (unsigned long)i, (unsigned long)i,
1073 (unsigned long)i, (unsigned long)i, (unsigned long)i,
1074 (unsigned long)i, (unsigned long)i, (unsigned long)i);
1075 if (t_type && (sdef->raw.taglist.list + t_type - 1)->nElements) {
1076 /* Avoid TAGs. */
1077 src = mputprintf(src, " negtest_confl_tag = true;\n");
1078 }
1079 src = mputprintf(src,
1080 " } else {\n"
1081 " myleaf.body.node.nodes[%lu] = new RAW_enc_tree(TRUE, "
1082 "&myleaf, &myleaf.curr_pos, %lu, %s_descr_.raw);\n"
1083 " if (emb_descr) {\n",
1084 (unsigned long)i, (unsigned long)i, sdef->elements[i].typedescrname);
1085 if (t_type && (sdef->raw.taglist.list + t_type - 1)->nElements) {
1086 /* Avoid TAGs. */
1087 src = mputprintf(src, " negtest_confl_tag = true;\n");
1088 }
1089 src = mputprintf(src,
1090 " encoded_length = field_%s->RAW_encode_negtest(emb_descr, %s_descr_, *myleaf.body.node.nodes[%lu]);\n"
1091 " } else encoded_length = field_%s->RAW_encode(%s_descr_, *myleaf.body.node.nodes[%lu]);\n"
1092 " myleaf.body.node.nodes[%lu]->coding_descr = &%s_descr_;\n"
1093 " }\n",
1094 sdef->elements[i].name, sdef->elements[i].typedescrname,
1095 (unsigned long)i, sdef->elements[i].name,
1096 sdef->elements[i].typedescrname, (unsigned long)i, (unsigned long)i,
1097 sdef->elements[i].typedescrname);
1098 if (t_type && (sdef->raw.taglist.list + t_type - 1)->nElements) {
1099 rawAST_coding_taglist *cur_choice = sdef->raw.taglist.list + t_type - 1;
1100 src = mputprintf(src,
1101 " if (negtest_confl_tag) {\n"
1102 " TTCN_EncDec_ErrorContext e_c;\n"
1103 " e_c.set_msg(\"Field '%s': \");\n"
1104 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1105 " \"Conflicting negative testing attributes, TAG attribute "
1106 "will be ignored\");\n"
1107 " }\n"
1108 " if (!negtest_confl_tag && (", sdef->elements[i].name);
1109 src = genRawFieldChecker(src, cur_choice, FALSE);
1110 src = mputstr(src, ")) {\n");
1111 src = genRawTagChecker(src, cur_choice);
1112 src = mputstr(src, " }\n");
1113 }
1114 src = mputstr(src, " break; }\n");
1115 }
1116 src = mputstr(src, " default:\n"
1117 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "
1118 "\"Encoding an unbound value.\");\n"
1119 " }\n"
1120 " return encoded_length;\n"
1121 "}\n\n");
1122 }
1123 Free(tag_type);
1124 } /* if raw_needed */
1125
1126 if (text_needed) {
1127 src = mputprintf(src, "int %s::TEXT_encode("
1128 "const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const\n"
1129 "{\n", name);
1130 if (use_runtime_2) {
1131 src = mputstr(src, " if (err_descr) return TEXT_encode_negtest(err_descr, p_td, p_buf);\n");
1132 }
1133 src = mputstr(src, " int encoded_length=0;\n"
1134 " if (p_td.text->begin_encode) {\n"
1135 " p_buf.put_cs(*p_td.text->begin_encode);\n"
1136 " encoded_length += p_td.text->begin_encode->lengthof();\n"
1137 " }\n"
1138 " switch(union_selection){\n");
1139 for (i = 0; i < sdef->nElements; i++) {
1140 src = mputprintf(src, " case %s_%s:\n"
1141 " encoded_length += field_%s->TEXT_encode(%s_descr_,p_buf);\n"
1142 " break;\n", selection_prefix, sdef->elements[i].name,
1143 sdef->elements[i].name, sdef->elements[i].typedescrname);
1144 }
1145 src = mputstr(src, " default:\n"
1146 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "
1147 "\"Encoding an unbound value.\");\n"
1148 " break;\n"
1149 " }\n"
1150 " if (p_td.text->end_encode) {\n"
1151 " p_buf.put_cs(*p_td.text->end_encode);\n"
1152 " encoded_length += p_td.text->end_encode->lengthof();\n"
1153 " }\n"
1154 " return encoded_length;\n"
1155 "}\n\n");
1156 if (use_runtime_2) {/*TEXT_encde_negtest()*/
1157 def = mputstr(def,
1158 "int TEXT_encode_negtest(const Erroneous_descriptor_t* p_err_descr, const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const;\n");
1159 src = mputprintf(src, "int %s::TEXT_encode_negtest("
1160 "const Erroneous_descriptor_t* p_err_descr, const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const\n"
1161 "{\n"
1162 " int encoded_length=0;\n"
1163 " const Erroneous_values_t* err_vals = NULL;\n"
1164 " const Erroneous_descriptor_t* emb_descr = NULL;\n"
1165 " if (p_td.text->begin_encode) {\n"
1166 " p_buf.put_cs(*p_td.text->begin_encode);\n"
1167 " encoded_length += p_td.text->begin_encode->lengthof();\n"
1168 " }\n"
1169 " switch(union_selection){\n", name);
1170 for (i = 0; i < sdef->nElements; i++) {
1171 src = mputprintf(src, " case %s_%s:\n"
1172 " err_vals = p_err_descr->get_field_err_values(%d);\n"
1173 " emb_descr = p_err_descr->get_field_emb_descr(%d);\n"
1174 " if (err_vals && err_vals->value){\n"
1175 " if (err_vals->value->errval) {\n"
1176 " if(err_vals->value->raw){\n"
1177 " encoded_length += err_vals->value->errval->encode_raw(p_buf);\n"
1178 " }else{\n"
1179 " if (err_vals->value->type_descr==NULL) TTCN_error(\"internal error: erroneous value typedescriptor missing\");\n"
1180 " encoded_length += err_vals->value->errval->TEXT_encode(*err_vals->value->type_descr,p_buf);\n"
1181 " }\n"
1182 " }\n"
1183 " }else{\n"
1184 " if (emb_descr) encoded_length += field_%s->TEXT_encode_negtest(emb_descr,%s_descr_,p_buf);\n"
1185 " else field_%s->TEXT_encode(%s_descr_,p_buf);\n"
1186 " }\n"
1187 " break;\n", selection_prefix, sdef->elements[i].name,(int)i,(int)i,
1188 sdef->elements[i].name, sdef->elements[i].typedescrname, sdef->elements[i].name, sdef->elements[i].typedescrname);
1189 }
1190 src = mputstr(src, " default:\n"
1191 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "
1192 "\"Encoding an unbound value.\");\n"
1193 " break;\n"
1194 " }\n"
1195 " if (p_td.text->end_encode) {\n"
1196 " p_buf.put_cs(*p_td.text->end_encode);\n"
1197 " encoded_length += p_td.text->end_encode->lengthof();\n"
1198 " }\n"
1199 " return encoded_length;\n"
1200 "}\n\n");
1201 }
1202
1203 src = mputprintf(src, "int %s::TEXT_decode("
1204 "const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, "
1205 "Limit_Token_List& limit, boolean no_err, boolean)\n"
1206 "{\n"
1207 " int decoded_length = 0;\n"
1208 " if(p_td.text->begin_decode){\n"
1209 " int tl = p_td.text->begin_decode->match_begin(p_buf);\n"
1210 " if (tl >= 0) {\n"
1211 " decoded_length += tl;\n"
1212 " p_buf.increase_pos(tl);\n"
1213 " } else {\n"
1214 " if (no_err) return -1;\n"
1215 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR, "
1216 "\"The specified token '%%s' not found for '%%s': \", "
1217 "(const char*)(*p_td.text->begin_decode), p_td.name);\n"
1218 " return 0;\n"
1219 " }\n"
1220 " }\n"
1221 " if (p_buf.get_read_len() < 1 && no_err) return -1;\n"
1222 "%s"
1223 " int ml = 0;\n"
1224 " boolean found = FALSE;\n"
1225 " if (p_td.text->end_decode) {\n"
1226 " limit.add_token(p_td.text->end_decode);\n"
1227 " ml++;\n"
1228 " }\n", name, sdef->nElements > 1 ? " size_t pos = p_buf.get_pos();\n" : "");
1229 if (sdef->nElements > 0) {
1230 src = mputprintf(src,
1231 " int str_len = %s().TEXT_decode(%s_descr_, p_buf, limit, true);\n"
1232 " if (str_len >= 0) found = TRUE;\n", sdef->elements[0].name,
1233 sdef->elements[0].typedescrname);
1234 }
1235 for (i = 1; i < sdef->nElements; i++) {
1236 src = mputprintf(src, " if (!found) {\n"
1237 " p_buf.set_pos(pos);\n"
1238 " str_len = %s().TEXT_decode(%s_descr_, p_buf, limit, true);\n"
1239 " if (str_len >= 0) found = TRUE;\n"
1240 " }\n", sdef->elements[i].name, sdef->elements[i].typedescrname);
1241 }
1242 src = mputstr(src, " limit.remove_tokens(ml);\n"
1243 " if (found) {\n"
1244 " decoded_length += str_len;\n"
1245 " if (p_td.text->end_decode) {\n"
1246 " int tl = p_td.text->end_decode->match_begin(p_buf);\n"
1247 " if (tl >= 0){\n"
1248 " decoded_length += tl;\n"
1249 " p_buf.increase_pos(tl);\n"
1250 " } else {\n"
1251 " if (no_err) return -1;\n"
1252 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR, "
1253 "\"The specified token '%s' not found for '%s': \", "
1254 "(const char*)(*p_td.text->end_decode), p_td.name);\n"
1255 " }\n"
1256 " }\n"
1257 " } else {\n"
1258 " if (no_err) return -1;\n"
1259 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR, "
1260 "\"No union member found for '%s': \", p_td.name);\n"
1261 " clean_up();\n"
1262 " }\n"
1263 " return decoded_length;\n"
1264 "}\n");
1265 }
1266
1267 if (xer_needed) { /* XERSTUFF encoder functions for union */
1268 def = mputstr(def,
1269 "char **collect_ns(const XERdescriptor_t& p_td, size_t& num, bool& def_ns) const;\n");
1270
1271 src=mputprintf(src,
1272 "boolean %s::can_start(const char *name, const char *uri,"
1273 " const XERdescriptor_t& xd, unsigned int flavor) {\n"
1274 " boolean exer = is_exer(flavor);\n"
1275 " if (!exer || (!(xd.xer_bits & UNTAGGED) && !(flavor & (USE_NIL|(exer ? XER_LIST : XER_RECOF))))) "
1276 /* If the union has no own tag, there is nothing to check. */
1277 "return check_name(name, xd, exer)" /* if false, return immediately */
1278 " && (!exer || (flavor & USE_TYPE_ATTR) || check_namespace(uri, xd));\n"
1279 /* else check the ns, unless Basic XER (which has no namespaces, ever)
1280 * or USE_TYPE (where we only have a name from the type id attribute) */
1281 , name
1282 );
1283 src = mputstr(src, " flavor &= ~XER_RECOF;\n");
1284
1285 /* An untagged union can start with the start tag of any alternative */
1286 for (i = 0; i < sdef->nElements; i++) {
1287 src=mputprintf(src,
1288 " if (%s::can_start(name, uri, %s_xer_, flavor)) return true;\n"
1289 , sdef->elements[i].type, sdef->elements[i].typegen
1290 );
1291 }
1292 src = mputstr(src, " return false;\n}\n\n");
1293
1294 src = mputprintf(src,
1295 "char ** %s::collect_ns(const XERdescriptor_t& p_td, size_t& num, bool& def_ns) const {\n"
1296 " size_t num_collected;\n"
1297 " char **collected_ns = Base_Type::collect_ns(p_td, num_collected, def_ns);\n"
1298 /* Two-level new memory allocated */
1299 " char **new_ns;\n"
1300 " size_t num_new;\n"
1301 " boolean need_type = FALSE;\n"
1302 " try {\n"
1303 " bool def_ns_1 = false;\n"
1304 " switch (union_selection) {\n"
1305 , name
1306 );
1307 for (i = 0; i < sdef->nElements; i++) {
1308 src = mputprintf(src,
1309 " case %s_%s:\n"
1310 " new_ns = field_%s->collect_ns(%s_xer_, num_new, def_ns_1);\n"
1311 " def_ns = def_ns || def_ns_1;\n" /* alas, no ||= */
1312 " merge_ns(collected_ns, num_collected, new_ns, num_new);\n"
1313 /* merge_ns() deallocated new_ns and duplicated strings,
1314 * copied the new ones into the expanded new_ns */
1315 , selection_prefix, sdef->elements[i].name
1316 , sdef->elements[i].name
1317 , sdef->elements[i].typegen
1318 );
1319 /* Type id attribute not needed for the first field in case of USE-TYPE */
1320 if (sdef->xerUseUnion || i > 0) src = mputprintf(src,
1321 " need_type = (%s_xer_.namelens[1] > 2);\n"
1322 , sdef->elements[i].typegen);
1323 src = mputstr(src, " break;\n");
1324 }
1325
1326 src = mputstr(src,
1327 " default: break;\n"
1328 " }\n" /* switch */
1329 " if ((p_td.xer_bits & USE_TYPE_ATTR) && !(p_td.xer_bits & XER_ATTRIBUTE) && need_type) {\n"
1330 /* control ns for type attribute */
1331 " collected_ns = (char**)Realloc(collected_ns, sizeof(char*) * ++num_collected);\n"
1332 " const namespace_t *c_ns = p_td.my_module->get_controlns();\n"
1333 " collected_ns[num_collected-1] = mprintf(\" xmlns:%s='%s'\", c_ns->px, c_ns->ns);\n"
1334 " }\n"
1335 " }\n"
1336 " catch (...) {\n"
1337 /* Probably a TC_Error thrown from field_%s->collect_ns() if e.g.
1338 * encoding an unbound value. */
1339 " while (num_collected > 0) Free(collected_ns[--num_collected]);\n"
1340 " Free(collected_ns);\n"
1341 " throw;\n"
1342 " }\n"
1343 " num = num_collected;\n"
1344 " return collected_ns;\n"
1345 "}\n\n"
1346 );
1347
1348 src = mputprintf(src, /* XERSTUFF XER_encode for union */
1349 "int %s::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
1350 "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const\n"
1351 "{\n"
1352 "%s"
1353 " if (%s==union_selection) {\n"
1354 " TTCN_error(\"Attempt to XER-encode an unbound union value.\");\n"
1355 " return 0;\n"
1356 " }\n"
1357 " TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n"
1358 " TTCN_EncDec_ErrorContext ec_1;\n"
1359 " int encoded_length=(int)p_buf.get_len();\n"
1360 , name
1361 , (use_runtime_2 ? " if (err_descr) return XER_encode_negtest"
1362 "(err_descr, p_td, p_buf, p_flavor, p_indent, 0);\n" : "")
1363 , unbound_value
1364 );
1365
1366 if (sdef->xerUseTypeAttr) {
1367 src = mputstr(src,
1368 " const boolean e_xer = is_exer(p_flavor);\n"
1369 " char *type_atr = NULL;\n"
1370 " if (e_xer && (p_td.xer_bits & USE_TYPE_ATTR)) {\n"
1371 " char *type_name = 0;\n"
1372 " const namespace_t *control_ns;\n"
1373 " switch (union_selection) {\n");
1374 /* In case of USE-TYPE the first field won't need the type attribute */
1375 int start_at = sdef->xerUseUnion ? 0 : 1;
1376 for (i = start_at; i < sdef->nElements; i++) {
1377 src = mputprintf(src,
1378 " case %s_%s:\n"
1379 " if (%s_xer_.my_module != 0 && %s_xer_.ns_index != -1 &&\n"
1380 " %s_xer_.namelens[1] > 2) {\n"
1381 /* add the namespace prefix to the type attribute (if the name is not empty) */
1382 " const namespace_t *my_ns = %s_xer_.my_module->get_ns(%s_xer_.ns_index);\n"
1383 " if (my_ns->px[0] != 0) {\n"
1384 " type_name = mprintf(\"%%s:\", my_ns->px);\n"
1385 " }\n"
1386 " }\n"
1387 " type_name = mputstrn(type_name, %s_xer_.names[1], %s_xer_.namelens[1] - 2);\n"
1388 " %s\n"
1389 , selection_prefix, sdef->elements[i].name
1390 , sdef->elements[i].typegen, sdef->elements[i].typegen
1391 , sdef->elements[i].typegen, sdef->elements[i].typegen
1392 , sdef->elements[i].typegen, sdef->elements[i].typegen
1393 , sdef->elements[i].typegen
1394 , i < sdef->nElements - 1 ? "goto write_atr;" : "" /* no break */
1395 );
1396 }
1397 src = mputprintf(src,
1398 "%s" /* label only if more than two elements total */
1399 " if (mstrlen(type_name) > 0) {\n" /* 38.3.8, no atr if NAME AS "" */
1400 " control_ns = p_td.my_module->get_controlns();\n"
1401 " type_atr = mcopystr(\" \");\n"
1402 " type_atr = mputstr(type_atr, control_ns->px);\n"
1403 " type_atr = mputstr(type_atr, \":type='\");\n"
1404 " type_atr = mputstr(type_atr, type_name);\n"
1405 " type_atr = mputc (type_atr, '\\'');\n"
1406 " Free(type_name);\n"
1407 " }\n"
1408 " break;\n"
1409 " default: break;\n"
1410 " }\n" /* switch */
1411 " p_flavor &= ~XER_RECOF;\n"
1412 " }\n" /* if e_xer */
1413 , (sdef->nElements > start_at + 1 ? "write_atr:\n" : "")
1414
1415
1416 );
1417 } /* if UseTypeAttr */
1418 src = mputprintf(src,
1419 " unsigned int flavor_1 = p_flavor;\n"
1420 " if (is_exer(p_flavor)) flavor_1 &= ~XER_RECOF;\n"
1421 " bool omit_tag = begin_xml(p_td, p_buf, flavor_1, p_indent, false, "
1422 "(collector_fn)&%s::collect_ns%s);\n"
1423 , sdef->name
1424 , sdef->xerUseTypeAttr ? ", type_atr" : "");
1425 src = mputprintf(src,
1426 " unsigned int flavor_0 = (p_flavor & XER_MASK)%s;\n"
1427 " switch (union_selection) {\n"
1428 , sdef->xerUseTypeAttr ? " | USE_TYPE_ATTR" : "");
1429 for (i = 0; i < sdef->nElements; i++) {
1430 src = mputprintf(src, " case %s_%s:\n"
1431 " ec_1.set_msg(\"%s': \");\n"
1432 " field_%s->XER_encode(%s_xer_, p_buf, flavor_0, "
1433 "p_indent + (!p_indent || !omit_tag), 0);\n"
1434 " break;\n",
1435 selection_prefix, sdef->elements[i].name,
1436 sdef->elements[i].dispname,
1437 sdef->elements[i].name, sdef->elements[i].typegen);
1438 }
1439 src = mputprintf(src, " case %s:\n"
1440 " (void)flavor_0;\n" /* warning reduction for empty union */
1441 " break;\n"
1442 " } //switch\n"
1443 , unbound_value);
1444 if (sdef->xerUseTypeAttr) {
1445 src = mputstr(src, " if (p_buf.get_data()[p_buf.get_len()-1] != '\\n') flavor_1 |= SIMPLE_TYPE;\n");
1446 }
1447 src = mputstr(src,
1448 " end_xml(p_td, p_buf, flavor_1, p_indent, 0);\n"
1449 " return (int)p_buf.get_len() - encoded_length;\n"
1450 "}\n\n");
1451
1452 if (use_runtime_2) {
1453 def = mputstr(def,
1454 "int XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, "
1455 "const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
1456 "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const;\n");
1457 src = mputprintf(src, /* XERSTUFF XER_encode for union */
1458 "int %s::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, "
1459 "const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
1460 "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const\n"
1461 "{\n"
1462 " if (%s==union_selection) {\n"
1463 " TTCN_error(\"Attempt to XER-encode an unbound union value.\");\n"
1464 " return 0;\n"
1465 " }\n"
1466 " TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n"
1467 " TTCN_EncDec_ErrorContext ec_1;\n"
1468 " int encoded_length=(int)p_buf.get_len();\n"
1469 , name
1470 , unbound_value
1471 );
1472 if (sdef->xerUseTypeAttr) {
1473 src = mputstr(src,
1474 " const boolean e_xer = is_exer(p_flavor);\n"
1475 " char *type_atr = NULL;\n"
1476 " if (e_xer && (p_td.xer_bits & USE_TYPE_ATTR)) {\n"
1477 " char *type_name = 0;\n"
1478 " const namespace_t *control_ns;\n"
1479 " switch (union_selection) {\n");
1480 int start_at = sdef->xerUseUnion ? 0 : 1;
1481 for (i = start_at; i < sdef->nElements; i++) {
1482 src = mputprintf(src,
1483 " case %s_%s:\n"
1484 " if (%s_xer_.my_module != 0 && %s_xer_.ns_index != -1 &&\n"
1485 " %s_xer_.namelens[1] > 2) {\n"
1486 /* add the namespace prefix to the type attribute (if the name is not empty) */
1487 " const namespace_t *my_ns = %s_xer_.my_module->get_ns(%s_xer_.ns_index);\n"
1488 " if (my_ns->px[0] != 0) {\n"
1489 " type_name = mprintf(\"%%s:\", my_ns->px);\n"
1490 " }\n"
1491 " }\n"
1492 " type_name = mputstrn(type_name, %s_xer_.names[1], %s_xer_.namelens[1] - 2);\n"
1493 " %s\n"
1494 , selection_prefix, sdef->elements[i].name
1495 , sdef->elements[i].typegen, sdef->elements[i].typegen
1496 , sdef->elements[i].typegen, sdef->elements[i].typegen
1497 , sdef->elements[i].typegen, sdef->elements[i].typegen
1498 , sdef->elements[i].typegen
1499 , i < sdef->nElements - 1 ? "goto write_atr;" : "" /* no break */
1500 );
1501 }
1502 src = mputprintf(src,
1503 "%s" /* label only if more than two elements total */
1504 " if (mstrlen(type_name) > 0) {\n" /* 38.3.8, no atr if NAME AS "" */
1505 " control_ns = p_td.my_module->get_controlns();\n"
1506 " type_atr = mcopystr(\" \");\n"
1507 " type_atr = mputstr(type_atr, control_ns->px);\n"
1508 " type_atr = mputstr(type_atr, \":type='\");\n"
1509 " type_atr = mputstr(type_atr, type_name);\n"
1510 " type_atr = mputc (type_atr, '\\'');\n"
1511 " Free(type_name);\n"
1512 " }\n"
1513 " break;\n"
1514 " default: break;\n"
1515 " }\n" /* switch */
1516 " p_flavor &= ~XER_RECOF;\n"
1517 " }\n" /* if e_xer */
1518 , (sdef->nElements > start_at + 1 ? "write_atr:\n" : "")
1519 );
1520 } /* if UseTypeAttr */
1521
1522 src = mputprintf(src,
1523 " bool omit_tag = begin_xml(p_td, p_buf, p_flavor, p_indent, false, "
1524 "(collector_fn)&%s::collect_ns%s);\n"
1525 , sdef->name
1526 , sdef->xerUseTypeAttr ? ", type_atr" : "");
1527 /* begin_xml will Free type_atr */
1528 src = mputprintf(src,
1529 " unsigned int flavor_0 = (p_flavor & XER_MASK)%s;\n"
1530 " const Erroneous_values_t* err_vals = NULL;\n"
1531 " const Erroneous_descriptor_t* emb_descr = NULL;\n"
1532 " switch (union_selection) {\n"
1533 , sdef->xerUseTypeAttr ? " | USE_TYPE_ATTR" : "");
1534 for (i = 0; i < sdef->nElements; i++) {
1535 src = mputprintf(src, " case %s_%s:\n"
1536 " err_vals = p_err_descr->get_field_err_values(%lu);\n"
1537 " emb_descr = p_err_descr->get_field_emb_descr(%lu);\n"
1538 " if (err_vals && err_vals->value) {\n"
1539 " if (err_vals->value->errval) {\n"
1540 " ec_1.set_msg(\"%s'(erroneous value): \");\n"
1541 " if (err_vals->value->raw) {\n"
1542 " err_vals->value->errval->encode_raw(p_buf);\n"
1543 " } else {\n"
1544 " if (err_vals->value->type_descr==NULL) TTCN_error"
1545 "(\"internal error: erroneous value typedescriptor missing\");\n"
1546 " else err_vals->value->errval->XER_encode("
1547 "*err_vals->value->type_descr->xer, p_buf, flavor_0, "
1548 "p_indent + (!p_indent || !omit_tag), 0);\n"
1549 " }\n"
1550 " }\n"
1551 " } else {\n"
1552 " ec_1.set_msg(\"%s': \");\n"
1553 " if (emb_descr) field_%s->XER_encode_negtest(emb_descr, "
1554 "%s_xer_, p_buf, flavor_0, p_indent + (!p_indent || !omit_tag), 0);\n"
1555 " else field_%s->XER_encode(%s_xer_, p_buf, flavor_0, "
1556 "p_indent + (!p_indent || !omit_tag), 0);\n"
1557 " }\n"
1558 " break;\n",
1559 selection_prefix, sdef->elements[i].name, /* case label */
1560 (unsigned long)i, (unsigned long)i,
1561 sdef->elements[i].dispname, /* set_msg (erroneous) */
1562 sdef->elements[i].dispname, /* set_msg */
1563 sdef->elements[i].name, sdef->elements[i].typegen,
1564 sdef->elements[i].name, sdef->elements[i].typegen /* field_%s, %s_descr */
1565 );
1566 }
1567 src = mputprintf(src, " case %s:\n"
1568 " (void)flavor_0;\n" /* warning reduction for empty union */
1569 " break;\n"
1570 " } //switch\n"
1571 " end_xml(p_td, p_buf, p_flavor, p_indent, 0);\n"
1572 " return (int)p_buf.get_len() - encoded_length;\n"
1573 "}\n\n"
1574 , unbound_value);
1575 }
1576
1577 #ifndef NDEBUG
1578 src = mputprintf(src, "// %s has%s%s%s%s%s%s%s%s%s\n"
1579 "// written by %s in " __FILE__ " at %d\n"
1580 , name
1581 , (sdef->xerUntagged ? " UNTAGGED" : "")
1582 , (sdef->xerUntaggedOne ? "1" : "")
1583 , (sdef->xerUseNilPossible ? " USE_NIL?" : "")
1584 , (sdef->xerUseOrderPossible ? " USE_ORDER?" : "")
1585 , (sdef->xerUseQName ? " USE_QNAME" : "")
1586 , (sdef->xerUseTypeAttr ? " USE_TYPE_ATTR" : "")
1587 , (sdef->xerUseUnion ? " USE-UNION" : "")
1588 , (sdef->xerHasNamespaces ? " namespace" : "")
1589 , (sdef->xerEmbedValuesPossible ? " EMBED?" : "")
1590 , __FUNCTION__, __LINE__
1591 );
1592 #endif
1593 src = mputprintf(src, /* XERSTUFF decoder functions for union */
1594 "int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader,"
1595 " unsigned int p_flavor, embed_values_dec_struct_t*)\n"
1596 "{\n"
1597 " int e_xer = is_exer(p_flavor);\n"
1598 " int type = 0;\n" /* None */
1599 " int rd_ok=1, xml_depth=-1;\n"
1600 "%s%s"
1601 " int xerbits = p_td.xer_bits;\n"
1602 " if (p_flavor & XER_TOPLEVEL) xerbits &= ~UNTAGGED;\n"
1603 " if (xerbits & USE_TYPE_ATTR) p_flavor &= ~XER_RECOF;\n"
1604 " boolean own_tag = !(e_xer && ((xerbits & (ANY_ELEMENT | UNTAGGED)) "
1605 "|| (p_flavor & (USE_NIL|(e_xer ? XER_LIST : XER_RECOF)))));\n"
1606 " if ((e_xer || !is_record_of(p_flavor)) && own_tag)\n"
1607 /* Loop until the start tag */
1608 " %sfor (rd_ok = p_reader.Ok(); rd_ok == 1; rd_ok = p_reader.Read()) {\n"
1609 " type = p_reader.NodeType();\n"
1610 " if (type == XML_READER_TYPE_ELEMENT) {\n"
1611 " verify_name(p_reader, p_td, e_xer);\n"
1612 " xml_depth = p_reader.Depth();\n"
1613 , name
1614 , sdef->xerUseTypeAttr ? " char * typeatr = 0;\n" : ""
1615 , sdef->xerUseUnion ? " boolean attribute = (p_td.xer_bits & XER_ATTRIBUTE) ? true : false;\n" : ""
1616 , sdef->xerUseUnion ? "if (!attribute) " : ""
1617 );
1618 if (sdef->xerUseTypeAttr) {
1619 src = mputprintf(src,
1620 " int other_attributes = 0;\n"
1621 " if (e_xer) {\n"
1622 " for (rd_ok = p_reader.MoveToFirstAttribute(); rd_ok == 1;"
1623 " rd_ok = p_reader.MoveToNextAttribute()) {\n"
1624 " if (p_reader.IsNamespaceDecl()) continue;\n"
1625 " const char *attr_name = (const char*)p_reader.Name();\n"
1626 " if (!strcmp(attr_name, \"%s:type\"))\n"
1627 " {\n"
1628 " typeatr = mcopystr((const char*)p_reader.Value());\n"
1629 " }\n"
1630 " else ++other_attributes;\n"
1631 " }\n" /* for */
1632 " rd_ok = p_reader.MoveToElement() | 1;\n"
1633 , sdef->control_ns_prefix);
1634 if (!sdef->xerUseUnion) {
1635 /* USE-TYPE: No type attribute means the first alternative */
1636 src = mputprintf(src,
1637 " if (typeatr == NULL) {\n"
1638 " typeatr = mcopystrn(%s_xer_.names[1], %s_xer_.namelens[1] - 2);\n"
1639 " }\n"
1640 , sdef->elements[0].typegen
1641 , sdef->elements[0].typegen);
1642 }
1643 src = mputstr(src,
1644 " }\n" /* if exer */);
1645 }
1646
1647 src = mputprintf(src,
1648 " if (!(e_xer && (p_td.xer_bits & USE_TYPE_ATTR)%s)\n"
1649 " && !p_reader.IsEmptyElement()) rd_ok = p_reader.Read();\n"
1650 " break;\n"
1651 " }\n"
1652 " }\n"
1653 " unsigned int flavor_1 = (p_flavor & XER_MASK);\n" /* also, not toplevel */
1654 /* Loop until the content. Normally an element, unless UNTAGGED
1655 * USE-UNION or some other shenanigans. */
1656 " %s%sfor (rd_ok = p_reader.Ok(); rd_ok == 1; rd_ok = p_reader.Read()) {\n"
1657 " type = p_reader.NodeType();\n"
1658 " %sif (type == XML_READER_TYPE_ELEMENT) break;\n"
1659 " else if (type == XML_READER_TYPE_END_ELEMENT) break;\n"
1660 " }\n"
1661 " if (rd_ok) {\n"
1662 " TTCN_EncDec_ErrorContext ec_1(\"Alternative '\");\n"
1663 " TTCN_EncDec_ErrorContext ec_2;\n"
1664 " const char *elem_name;\n"
1665 " const char *ns_uri = 0;\n"
1666 , sdef->xerUseTypeAttr ? " && other_attributes > 0" : ""
1667 , sdef->xerUseTypeAttr ? "if (!e_xer) " : ""
1668 , sdef->xerUseUnion ? "if (!attribute) " : ""
1669 , sdef->xerUseTypeAttr ?
1670 "if (e_xer) { if (type == XML_READER_TYPE_TEXT) break; }\n"
1671 " else " : ""
1672 );
1673
1674 if (sdef->xerUseTypeAttr) {
1675 src = mputstr(src,
1676 " if (e_xer) {\n" /* USE-TYPE => no XML element, use typeatr */
1677 " char *token_1 = strtok(typeatr, \":\");\n" /* extract the namespace (if any) */
1678 " char *token_2 = strtok(NULL, \":\");\n"
1679 " if (token_2) {\n" /* namespace found */
1680 " elem_name = token_2;\n"
1681 " ns_uri = get_ns_uri_from_prefix(token_1, p_td);\n"
1682 " }\n"
1683 " else {\n" /* no namespace */
1684 " elem_name = token_1;\n"
1685 " }\n"
1686 " flavor_1 |= USE_TYPE_ATTR;\n"
1687 " }\n"
1688 " else" /* no newline, gobbles up the next {} */);
1689 }
1690 src = mputstr(src,
1691 " {\n"
1692 " elem_name = (const char*)p_reader.LocalName();\n"
1693 " ns_uri = (const char*)p_reader.NamespaceUri();\n"
1694 " }\n");
1695
1696 if (sdef->xerUseUnion) {
1697 src = mputstr(src,
1698 " int matched = -1;\n"
1699 " if (typeatr == NULL) flavor_1 |= EXIT_ON_ERROR;\n"
1700 " for (;;) {\n");
1701 /* TODO unify the two alternatives */
1702 for (i = 0; i < sdef->nElements; i++) {
1703 src = mputprintf(src,
1704 /* If decoding EXER, there is no tag to apply check_name
1705 *
1706 */
1707 " if ((e_xer && (typeatr == NULL || !(p_td.xer_bits & USE_TYPE_ATTR))) "
1708 "|| can_start(elem_name, ns_uri, %s_xer_, flavor_1)) {\n"
1709 " ec_2.set_msg(\"%s': \");\n"
1710 " if (%s==union_selection) {\n"
1711 " matched = %d;\n"
1712 " %s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n"
1713 " }\n"
1714 " if (field_%s->is_bound()) break; else clean_up();\n"
1715 " }\n",
1716 sdef->elements[i].typegen,
1717 sdef->elements[i].dispname,
1718 unbound_value, (int)i,
1719 sdef->elements[i].name, sdef->elements[i].typegen,
1720 sdef->elements[i].name);
1721 }
1722 src = mputstr(src,
1723 " if (typeatr == NULL) {\n"
1724 /* No type attribute found and none of the fields managed to decode the value (USE-UNION only) */
1725 " ec_1.set_msg(\" \");\n"
1726 " ec_2.set_msg(\" \");\n"
1727 " const char* value = (const char*)p_reader.Value();\n"
1728 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
1729 " \"'%s' could not be decoded by any of the union's fields.\", value);\n"
1730 " } else if (matched >= 0) {\n"
1731 /* Alternative found, but it couldn't be decoded */
1732 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
1733 " \"Failed to decode field.\");\n"
1734 " } else {\n"
1735 /* Type attribute found, but it didn't match any of the fields */
1736 " ec_1.set_msg(\" \");\n"
1737 " ec_2.set_msg(\" \");\n"
1738 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
1739 " \"'%s' does not match any alternative.\", elem_name);\n"
1740 " }\n"
1741 " if (xml_depth >= 0) for (; rd_ok == 1 "
1742 "&& p_reader.Depth() > xml_depth; rd_ok = p_reader.Read()) ;\n"
1743 " break;\n"
1744 " }\n"); /* for ever */
1745 }
1746 else /* not USE-UNION */
1747 {
1748 if (sdef->exerMaybeEmptyIndex >= 0) {
1749 /* There is a field which can be empty XML. Add code to detect this
1750 * and jump to the appropriate field which can decode "nothing". */
1751 src = mputstr(src,
1752 " if (type!=XML_READER_TYPE_ELEMENT || "
1753 "(own_tag && p_reader.IsEmptyElement())) goto empty_xml;\n");
1754 /* If the choice itself is untagged, then an empty element belongs to
1755 * one of the fields and does not mean that the choice is empty */
1756 }
1757 /* FIXME some hashing should be implemented */
1758 /* The field which can be empty should be checked last, otherwise we create an infinity loop with memory bomb.
1759 * So move that field to the last elseif branch*/
1760 for (i = 0; i < sdef->nElements; i++) {
1761 if(sdef->exerMaybeEmptyIndex != i){
1762 src = mputprintf(src,
1763 " %sif (%s::can_start(elem_name, ns_uri, %s_xer_, flavor_1) || (%s_xer_.xer_bits & ANY_ELEMENT)) {\n"
1764 " ec_2.set_msg(\"%s': \");\n"
1765 " if (e_xer && (%s_xer_.xer_bits & BLOCKED)) {\n"
1766 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
1767 " \"Attempting to decode blocked or abstract field.\");\n"
1768 " }\n"
1769 " %s%s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n"
1770 " if (!%s%s().is_bound()) {\n"
1771 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, \"Failed to decode field.\");\n"
1772 " }\n"
1773 " }\n",
1774 i && !(i==1 && sdef->exerMaybeEmptyIndex==0) ? "else " : "", /* print "if(" if generate code for the first field or if the first field is the MaybeEmpty field and we generate the code for the second one*/
1775 sdef->elements[i].type, sdef->elements[i].typegen, sdef->elements[i].typegen,
1776 sdef->elements[i].dispname,
1777 sdef->elements[i].typegen,
1778 at_field, sdef->elements[i].name, sdef->elements[i].typegen,
1779 at_field, sdef->elements[i].name);
1780 }
1781 }
1782 if(sdef->exerMaybeEmptyIndex>=0 ){
1783 i=sdef->exerMaybeEmptyIndex;
1784 src = mputprintf(src,
1785 " %sif ((e_xer && (type==XML_READER_TYPE_END_ELEMENT || !own_tag)) || %s::can_start(elem_name, ns_uri, %s_xer_, flavor_1) || (%s_xer_.xer_bits & ANY_ELEMENT)) {\n"
1786 "empty_xml: ec_2.set_msg(\"%s': \");\n"
1787 " if (e_xer && (%s_xer_.xer_bits & BLOCKED)) {\n"
1788 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
1789 " \"Attempting to decode blocked or abstract field.\");\n"
1790 " }\n"
1791 " %s%s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n"
1792 " if (!%s%s().is_bound()) {\n"
1793 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, \"Failed to decode field.\");\n"
1794 " }\n"
1795 " }\n",
1796 sdef->nElements>0 ? "else " : "",
1797 sdef->elements[i].type, sdef->elements[i].typegen, sdef->elements[i].typegen,
1798 sdef->elements[i].dispname,
1799 sdef->elements[i].typegen,
1800 at_field, sdef->elements[i].name, sdef->elements[i].typegen,
1801 at_field, sdef->elements[i].name);
1802 }
1803 if (!sdef->isOptional) {
1804 src = mputstr(src,
1805 " else {\n"
1806 " ec_1.set_msg(\" \");\n"
1807 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, "
1808 "\"'%s' does not match any alternative\", elem_name);\n"
1809 " if (xml_depth >= 0) for (; rd_ok == 1 "
1810 "&& p_reader.Depth() > xml_depth; rd_ok = p_reader.Read()) ;\n"
1811 " }\n"
1812 );
1813 }
1814 }
1815
1816 src = mputprintf(src,
1817 " }\n" /* end if(rd_ok) */
1818 " if (%s(e_xer || !is_record_of(p_flavor)) && own_tag)\n"
1819 " for (; rd_ok == 1; rd_ok = p_reader.Read()) {\n"
1820 " type = p_reader.NodeType();\n"
1821 " if (type == XML_READER_TYPE_END_ELEMENT) {\n"
1822 " verify_end(p_reader, p_td, xml_depth, e_xer);\n"
1823 " rd_ok = p_reader.Read(); // one last time\n"
1824 " break;\n"
1825 " }\n"
1826 " }\n"
1827 "%s"
1828 " return 1;\n"
1829 "}\n\n", sdef->xerUseUnion ? "!attribute && " : "",
1830 sdef->xerUseTypeAttr ? " Free(typeatr);\n" : "");
1831 }
1832 if (json_needed) {
1833 // JSON encode
1834 src = mputprintf(src,
1835 "int %s::JSON_encode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok) const\n"
1836 "{\n", name);
1837 if (use_runtime_2) {
1838 src = mputstr(src, " if (err_descr) return JSON_encode_negtest(err_descr, p_td, p_tok);\n");
1839 }
1840 if (!sdef->jsonAsValue) {
1841 src = mputstr(src, " int enc_len = p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);\n\n");
1842 } else {
1843 src = mputstr(src, " int enc_len = 0;\n\n");
1844 }
1845 src = mputstr(src, " switch(union_selection) {\n");
1846
1847 for (i = 0; i < sdef->nElements; ++i) {
1848 src = mputprintf(src, " case %s_%s:\n", selection_prefix, sdef->elements[i].name);
1849 if (!sdef->jsonAsValue) {
1850 src = mputprintf(src, " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"%s\");\n"
1851 , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname);
1852 }
1853 src = mputprintf(src,
1854 " enc_len += field_%s->JSON_encode(%s_descr_, p_tok);\n"
1855 " break;\n"
1856 , sdef->elements[i].name, sdef->elements[i].typedescrname);
1857 }
1858 src = mputprintf(src,
1859 " default:\n"
1860 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, \n"
1861 " \"Encoding an unbound value of type %s.\");\n"
1862 " return -1;\n"
1863 " }\n\n"
1864 , dispname);
1865 if (!sdef->jsonAsValue) {
1866 src = mputstr(src, " enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);\n");
1867 }
1868 src = mputstr(src,
1869 " return enc_len;\n"
1870 "}\n\n");
1871
1872 if (use_runtime_2) {
1873 // JSON encode for negative testing
1874 def = mputstr(def,
1875 "int JSON_encode_negtest(const Erroneous_descriptor_t*, "
1876 "const TTCN_Typedescriptor_t&, JSON_Tokenizer&) const;\n");
1877 src = mputprintf(src,
1878 "int %s::JSON_encode_negtest(const Erroneous_descriptor_t* p_err_descr, "
1879 "const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const\n"
1880 "{\n", name);
1881 if (!sdef->jsonAsValue) {
1882 src = mputstr(src, " int enc_len = p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);\n\n");
1883 } else {
1884 src = mputstr(src, " int enc_len = 0;\n\n");
1885 }
1886 src = mputstr(src,
1887 " const Erroneous_values_t* err_vals = NULL;\n"
1888 " const Erroneous_descriptor_t* emb_descr = NULL;\n"
1889 " switch(union_selection) {\n");
1890
1891 for (i = 0; i < sdef->nElements; ++i) {
1892 src = mputprintf(src,
1893 " case %s_%s:\n"
1894 " err_vals = p_err_descr->get_field_err_values(%d);\n"
1895 " emb_descr = p_err_descr->get_field_emb_descr(%d);\n"
1896 " if (NULL != err_vals && NULL != err_vals->value) {\n"
1897 " if (NULL != err_vals->value->errval) {\n"
1898 " if(err_vals->value->raw){\n"
1899 " enc_len += err_vals->value->errval->JSON_encode_negtest_raw(p_tok);\n"
1900 " } else {\n"
1901 " if (NULL == err_vals->value->type_descr) {\n"
1902 " TTCN_error(\"internal error: erroneous value typedescriptor missing\");\n"
1903 " }\n"
1904 , selection_prefix, sdef->elements[i].name, (int)i, (int)i);
1905 if (!sdef->jsonAsValue) {
1906 src = mputprintf(src, " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"%s\");\n"
1907 , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname);
1908 }
1909 src = mputstr(src,
1910 " enc_len += err_vals->value->errval->JSON_encode(*err_vals->value->type_descr, p_tok);\n"
1911 " }\n"
1912 " }\n"
1913 " } else {\n");
1914 if (!sdef->jsonAsValue) {
1915 src = mputprintf(src, " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"%s\");\n"
1916 , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname);
1917 }
1918 src = mputprintf(src,
1919 " if (NULL != emb_descr) {\n"
1920 " enc_len += field_%s->JSON_encode_negtest(emb_descr, %s_descr_, p_tok);\n"
1921 " } else {\n"
1922 " enc_len += field_%s->JSON_encode(%s_descr_, p_tok);\n"
1923 " }\n"
1924 " }\n"
1925 " break;\n"
1926 , sdef->elements[i].name, sdef->elements[i].typedescrname
1927 , sdef->elements[i].name, sdef->elements[i].typedescrname);
1928 }
1929 src = mputprintf(src,
1930 " default:\n"
1931 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, \n"
1932 " \"Encoding an unbound value of type %s.\");\n"
1933 " return -1;\n"
1934 " }\n\n"
1935 , dispname);
1936 if (!sdef->jsonAsValue) {
1937 src = mputstr(src, " enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);\n");
1938 }
1939 src = mputstr(src,
1940 " return enc_len;\n"
1941 "}\n\n");
1942 }
1943
1944 // JSON decode
1945 src = mputprintf(src,
1946 "int %s::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent)\n"
1947 "{\n"
1948 " json_token_t j_token = JSON_TOKEN_NONE;\n"
1949 , name);
1950 if (sdef->jsonAsValue) {
1951 src = mputstr(src,
1952 " size_t buf_pos = p_tok.get_buf_pos();\n"
1953 " p_tok.get_next_token(&j_token, NULL, NULL);\n"
1954 " int ret_val = 0;\n"
1955 " switch(j_token) {\n"
1956 " case JSON_TOKEN_NUMBER: {\n");
1957 for (i = 0; i < sdef->nElements; ++i) {
1958 if (JSON_NUMBER & sdef->elements[i].jsonValueType) {
1959 src = mputprintf(src,
1960 " p_tok.set_buf_pos(buf_pos);\n"
1961 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
1962 " if (0 <= ret_val) {\n"
1963 " return ret_val;\n"
1964 " }\n"
1965 , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname);
1966 }
1967 }
1968 src = mputstr(src,
1969 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"number\");\n"
1970 " clean_up();\n"
1971 " return JSON_ERROR_FATAL;\n"
1972 " }\n"
1973 " case JSON_TOKEN_STRING: {\n");
1974 for (i = 0; i < sdef->nElements; ++i) {
1975 if (JSON_STRING & sdef->elements[i].jsonValueType) {
1976 src = mputprintf(src,
1977 " p_tok.set_buf_pos(buf_pos);\n"
1978 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
1979 " if (0 <= ret_val) {\n"
1980 " return ret_val;\n"
1981 " }\n"
1982 , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname);
1983 }
1984 }
1985 src = mputstr(src,
1986 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"string\");\n"
1987 " clean_up();\n"
1988 " return JSON_ERROR_FATAL;\n"
1989 " }\n"
1990 " case JSON_TOKEN_LITERAL_TRUE:\n"
1991 " case JSON_TOKEN_LITERAL_FALSE: {\n");
1992 for (i = 0; i < sdef->nElements; ++i) {
1993 if (JSON_BOOLEAN & sdef->elements[i].jsonValueType) {
1994 src = mputprintf(src,
1995 " p_tok.set_buf_pos(buf_pos);\n"
1996 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
1997 " if (0 <= ret_val) {\n"
1998 " return ret_val;\n"
1999 " }\n"
2000 , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname);
2001 }
2002 }
2003 src = mputstr(src,
2004 " char* literal_str = mprintf(\"literal (%s)\",\n"
2005 " (JSON_TOKEN_LITERAL_TRUE == j_token) ? \"true\" : \"false\");\n"
2006 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, literal_str);\n"
2007 " Free(literal_str);\n"
2008 " clean_up();\n"
2009 " return JSON_ERROR_FATAL;\n"
2010 " }\n"
2011 " case JSON_TOKEN_ARRAY_START: {\n");
2012 for (i = 0; i < sdef->nElements; ++i) {
2013 if (JSON_ARRAY & sdef->elements[i].jsonValueType) {
2014 src = mputprintf(src,
2015 " p_tok.set_buf_pos(buf_pos);\n"
2016 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
2017 " if (0 <= ret_val) {\n"
2018 " return ret_val;\n"
2019 " }\n"
2020 , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname);
2021 }
2022 }
2023 src = mputstr(src,
2024 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"array\");\n"
2025 " clean_up();\n"
2026 " return JSON_ERROR_FATAL;\n"
2027 " }\n"
2028 " case JSON_TOKEN_OBJECT_START: {\n");
2029 for (i = 0; i < sdef->nElements; ++i) {
2030 if (JSON_OBJECT & sdef->elements[i].jsonValueType) {
2031 src = mputprintf(src,
2032 " p_tok.set_buf_pos(buf_pos);\n"
2033 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
2034 " if (0 <= ret_val) {\n"
2035 " return ret_val;\n"
2036 " }\n"
2037 , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname);
2038 }
2039 }
2040 src = mputstr(src,
2041 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"object\");\n"
2042 " clean_up();\n"
2043 " return JSON_ERROR_FATAL;\n"
2044 " }\n"
2045 " case JSON_TOKEN_LITERAL_NULL: {\n");
2046 for (i = 0; i < sdef->nElements; ++i) {
2047 if (JSON_NULL & sdef->elements[i].jsonValueType) {
2048 src = mputprintf(src,
2049 " p_tok.set_buf_pos(buf_pos);\n"
2050 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
2051 " if (0 <= ret_val) {\n"
2052 " return ret_val;\n"
2053 " }\n"
2054 , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname);
2055 }
2056 }
2057 src = mputstr(src,
2058 " clean_up();\n"
2059 // the caller might be able to decode the null value if it's an optional field
2060 // only return an invalid token error, not a fatal error
2061 " return JSON_ERROR_INVALID_TOKEN;\n"
2062 " }\n"
2063 " case JSON_TOKEN_ERROR:\n"
2064 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, \"\");\n"
2065 " return JSON_ERROR_FATAL;\n"
2066 " default:\n"
2067 " return JSON_ERROR_INVALID_TOKEN;\n"
2068 " }\n"
2069 " return 0;\n"
2070 "}\n\n");
2071 } else { // not "as value"
2072 src = mputprintf(src,
2073 " int dec_len = p_tok.get_next_token(&j_token, NULL, NULL);\n"
2074 " if (JSON_TOKEN_ERROR == j_token) {\n"
2075 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, \"\");\n"
2076 " return JSON_ERROR_FATAL;\n"
2077 " }\n"
2078 " else if (JSON_TOKEN_OBJECT_START != j_token) {\n"
2079 " return JSON_ERROR_INVALID_TOKEN;\n"
2080 " }\n\n"
2081 " char* fld_name = 0;\n"
2082 " size_t name_len = 0;\n"
2083 " dec_len += p_tok.get_next_token(&j_token, &fld_name, &name_len);\n"
2084 " if (JSON_TOKEN_NAME != j_token) {\n"
2085 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_NAME_TOKEN_ERROR);\n"
2086 " return JSON_ERROR_FATAL;\n"
2087 " } else {\n"
2088 " union_selection = %s;\n "
2089 , unbound_value);
2090 for (i = 0; i < sdef->nElements; ++i) {
2091 src = mputprintf(src,
2092 "if (0 == strncmp(fld_name, \"%s\", name_len)) {\n"
2093 " int ret_val = %s%s().JSON_decode(%s_descr_, p_tok, p_silent);\n"
2094 " if (0 > ret_val) {\n"
2095 " if (JSON_ERROR_INVALID_TOKEN) {\n"
2096 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, \"%s\");\n"
2097 " }\n"
2098 " return JSON_ERROR_FATAL;\n"
2099 " } else {\n"
2100 " dec_len += ret_val;\n"
2101 " }\n"
2102 " } else "
2103 , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname
2104 , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname
2105 , sdef->elements[i].dispname);
2106 }
2107 src = mputstr(src,
2108 "{\n"
2109 " char* fld_name2 = mcopystrn(fld_name, name_len);\n"
2110 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_INVALID_NAME_ERROR, fld_name2);\n"
2111 " Free(fld_name2);\n"
2112 " return JSON_ERROR_FATAL;\n"
2113 " }\n"
2114 " }\n\n"
2115 " dec_len += p_tok.get_next_token(&j_token, NULL, NULL);\n"
2116 " if (JSON_TOKEN_OBJECT_END != j_token) {\n"
2117 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR, \"\");\n"
2118 " return JSON_ERROR_FATAL;\n"
2119 " }\n\n"
2120 " return dec_len;\n"
2121 "}\n\n");
2122 }
2123 }
2124
2125 /* end of class definition */
2126 def = mputstr(def, "};\n\n");
2127
2128 output->header.class_defs = mputstr(output->header.class_defs, def);
2129 Free(def);
2130
2131 output->source.methods = mputstr(output->source.methods, src);
2132 Free(src);
2133
2134 Free(selection_type);
2135 Free(unbound_value);
2136 Free(selection_prefix);
2137 }
2138
2139
2140 void defUnionTemplate(const struct_def *sdef, output_struct *output)
2141 {
2142 int i;
2143 const char *name = sdef->name, *dispname = sdef->dispname;
2144 const char *at_field = sdef->kind==ANYTYPE ? "AT_" : "";
2145 char *def = NULL, *src = NULL;
2146
2147 char *selection_type, *unbound_value, *selection_prefix;
2148 selection_type = mprintf("%s::union_selection_type", name);
2149 unbound_value = mprintf("%s::UNBOUND_VALUE", name);
2150 selection_prefix = mprintf("%s::ALT", name);
2151
2152 /* template class */
2153
2154 output->header.class_decls = mputprintf(output->header.class_decls,
2155 "class %s_template;\n", name);
2156
2157 /* template class header and data members */
2158 def = mputprintf(def, "class %s_template : public Base_Template {\n"
2159 "union {\n"
2160 "struct {\n"
2161 "%s union_selection;\n"
2162 "union {\n", name, selection_type);
2163 for (i = 0; i < sdef->nElements; i++) {
2164 def = mputprintf(def, "%s_template *field_%s;\n",
2165 sdef->elements[i].type, sdef->elements[i].name);
2166 }
2167 def = mputprintf(def, "};\n"
2168 "} single_value;\n"
2169 "struct {\n"
2170 "unsigned int n_values;\n"
2171 "%s_template *list_value;\n"
2172 "} value_list;\n"
2173 "};\n", name);
2174 if (use_runtime_2) {
2175 def = mputstr(def,
2176 "Erroneous_descriptor_t* err_descr;\n");
2177 }
2178
2179 /* copy_value function */
2180 def = mputprintf(def, "void copy_value(const %s& other_value);\n\n", name);
2181 src = mputprintf(src, "void %s_template::copy_value(const %s& other_value)\n"
2182 "{\n"
2183 "single_value.union_selection = other_value.get_selection();\n"
2184 "switch (single_value.union_selection) {\n", name, name);
2185 for (i = 0; i<sdef->nElements; i++) {
2186 src = mputprintf(src, "case %s_%s:\n"
2187 "single_value.field_%s = new %s_template(other_value.%s%s());\n"
2188 "break;\n", selection_prefix, sdef->elements[i].name,
2189 sdef->elements[i].name, sdef->elements[i].type,
2190 at_field, sdef->elements[i].name);
2191 }
2192 src = mputprintf(src, "default:\n"
2193 "TTCN_error(\"Initializing a template with an unbound value of type "
2194 "%s.\");\n"
2195 "}\n"
2196 "set_selection(SPECIFIC_VALUE);\n"
2197 "%s"
2198 "}\n\n", dispname,
2199 use_runtime_2 ? "err_descr = other_value.get_err_descr();\n" : "");
2200
2201 /* copy_template function */
2202 def = mputprintf(def, "void copy_template(const %s_template& "
2203 "other_value);\n", name);
2204 src = mputprintf(src, "void %s_template::copy_template(const "
2205 "%s_template& other_value)\n"
2206 "{\n"
2207 "switch (other_value.template_selection) {\n"
2208 "case SPECIFIC_VALUE:\n"
2209 "single_value.union_selection = "
2210 "other_value.single_value.union_selection;\n"
2211 "switch (single_value.union_selection) {\n", name, name);
2212 for (i = 0; i < sdef->nElements; i++) {
2213 src = mputprintf(src, "case %s_%s:\n"
2214 "single_value.field_%s = "
2215 "new %s_template(*other_value.single_value.field_%s);\n"
2216 "break;\n", selection_prefix, sdef->elements[i].name,
2217 sdef->elements[i].name, sdef->elements[i].type, sdef->elements[i].name);
2218 }
2219 src = mputprintf(src, "default:\n"
2220 "TTCN_error(\"Internal error: Invalid union selector in a specific value "
2221 "when copying a template of type %s.\");\n"
2222 "}\n"
2223 "case OMIT_VALUE:\n"
2224 "case ANY_VALUE:\n"
2225 "case ANY_OR_OMIT:\n"
2226 "break;\n"
2227 "case VALUE_LIST:\n"
2228 "case COMPLEMENTED_LIST:\n"
2229 "value_list.n_values = other_value.value_list.n_values;\n"
2230 "value_list.list_value = new %s_template[value_list.n_values];\n"
2231 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
2232 "list_count++)\n"
2233 "value_list.list_value[list_count].copy_template("
2234 "other_value.value_list.list_value[list_count]);\n"
2235 "break;\n"
2236 "default:\n"
2237 "TTCN_error(\"Copying an uninitialized template of union type %s.\");\n"
2238 "}\n"
2239 "set_selection(other_value);\n"
2240 "%s"
2241 "}\n\n", dispname, name, dispname,
2242 use_runtime_2 ? "err_descr = other_value.err_descr;\n" : "");
2243
2244 /* default constructor */
2245 def = mputprintf(def, "\npublic:\n"
2246 "%s_template();\n", name);
2247 src = mputprintf(src, "%s_template::%s_template()%s\n"
2248 "{\n"
2249 "}\n\n", name, name,
2250 use_runtime_2 ? ": err_descr(NULL)" : "");
2251
2252 /* constructor (template_sel) */
2253 def = mputprintf(def, "%s_template(template_sel other_value);\n", name);
2254 src = mputprintf(src, "%s_template::%s_template(template_sel other_value)\n"
2255 " : Base_Template(other_value)%s\n"
2256 "{\n"
2257 "check_single_selection(other_value);\n"
2258 "}\n\n", name, name,
2259 use_runtime_2 ? ", err_descr(NULL)" : "");
2260
2261 /* constructor (value) */
2262 def = mputprintf(def, "%s_template(const %s& other_value);\n", name, name);
2263 src = mputprintf(src, "%s_template::%s_template(const %s& other_value)\n"
2264 "{\n"
2265 "copy_value(other_value);\n"
2266 "}\n\n", name, name, name);
2267
2268 /* constructor (optional value) */
2269 def = mputprintf(def, "%s_template(const OPTIONAL<%s>& other_value);\n", name,
2270 name);
2271 src = mputprintf(src, "%s_template::%s_template(const OPTIONAL<%s>& "
2272 "other_value)\n"
2273 "{\n"
2274 "switch (other_value.get_selection()) {\n"
2275 "case OPTIONAL_PRESENT:\n"
2276 "copy_value((const %s&)other_value);\n"
2277 "break;\n"
2278 "case OPTIONAL_OMIT:\n"
2279 "set_selection(OMIT_VALUE);\n"
2280 "%s"
2281 "break;\n"
2282 "default:\n"
2283 "TTCN_error(\"Creating a template of union type %s from an unbound "
2284 "optional field.\");\n"
2285 "}\n"
2286 "}\n\n", name, name, name, name,
2287 use_runtime_2 ? "err_descr = NULL;\n" : "",
2288 dispname);
2289
2290 /* copy constructor */
2291 def = mputprintf(def, "%s_template(const %s_template& other_value);\n", name,
2292 name);
2293 src = mputprintf(src, "%s_template::%s_template(const %s_template& "
2294 "other_value)\n"
2295 ": Base_Template()" /* yes, the base class _default_ constructor */
2296 "{\n"
2297 "copy_template(other_value);\n"
2298 "}\n\n", name, name, name);
2299
2300 /* destructor */
2301 def = mputprintf(def, "~%s_template();\n", name);
2302 src = mputprintf(src, "%s_template::~%s_template()\n"
2303 "{\n"
2304 "clean_up();\n"
2305 "}\n\n", name, name);
2306
2307 /* clean_up function */
2308 def = mputstr(def, "void clean_up();\n");
2309 src = mputprintf(src, "void %s_template::clean_up()\n"
2310 "{\n"
2311 "switch (template_selection) {\n"
2312 "case SPECIFIC_VALUE:\n"
2313 "switch (single_value.union_selection) {\n", name);
2314 for (i = 0; i < sdef->nElements; i++) {
2315 src = mputprintf(src, "case %s_%s:\n"
2316 "delete single_value.field_%s;\n",
2317 selection_prefix, sdef->elements[i].name, sdef->elements[i].name);
2318 if (i < sdef->nElements - 1) src = mputstr(src, "break;\n");
2319 }
2320 src = mputstr(src, "default:\n"
2321 "break;\n"
2322 "}\n"
2323 "break;\n"
2324 "case VALUE_LIST:\n"
2325 "case COMPLEMENTED_LIST:\n"
2326 "delete [] value_list.list_value;\n"
2327 "default:\n"
2328 "break;\n"
2329 "}\n"
2330 "template_selection = UNINITIALIZED_TEMPLATE;\n"
2331 "}\n\n");
2332
2333 /* assignment operator (template_sel) */
2334 def = mputprintf(def, "%s_template& operator=(template_sel other_value);\n",
2335 name);
2336 src = mputprintf(src,
2337 "%s_template& %s_template::operator=(template_sel "
2338 "other_value)\n"
2339 "{\n"
2340 "check_single_selection(other_value);\n"
2341 "clean_up();\n"
2342 "set_selection(other_value);\n"
2343 "%s"
2344 "return *this;\n"
2345 "}\n\n", name, name, use_runtime_2 ? "err_descr = NULL;\n" : "");
2346
2347 /* assignment operator (value) */
2348 def = mputprintf(def, "%s_template& operator=(const %s& other_value);\n",
2349 name, name);
2350 src = mputprintf(src, "%s_template& %s_template::operator=(const %s& "
2351 "other_value)\n"
2352 "{\n"
2353 "clean_up();\n"
2354 "copy_value(other_value);\n"
2355 "return *this;\n"
2356 "}\n\n", name, name, name);
2357
2358 /* assignment operator <- optional value */
2359 def = mputprintf(def, "%s_template& operator=(const OPTIONAL<%s>& "
2360 "other_value);\n", name, name);
2361 src = mputprintf(src,
2362 "%s_template& %s_template::operator=(const OPTIONAL<%s>& other_value)\n"
2363 "{\n"
2364 "clean_up();\n"
2365 "switch (other_value.get_selection()) {\n"
2366 "case OPTIONAL_PRESENT:\n"
2367 "copy_value((const %s&)other_value);\n"
2368 "break;\n"
2369 "case OPTIONAL_OMIT:\n"
2370 "set_selection(OMIT_VALUE);\n"
2371 "%s"
2372 "break;\n"
2373 "default:\n"
2374 "TTCN_error(\"Assignment of an unbound optional field to a template of "
2375 "union type %s.\");\n"
2376 "}\n"
2377 "return *this;\n"
2378 "}\n\n", name, name, name, name,
2379 use_runtime_2 ? "err_descr = NULL;\n" : "", dispname);
2380
2381 /* assignment operator (template) */
2382 def = mputprintf(def, "%s_template& operator=(const %s_template& "
2383 "other_value);\n", name, name);
2384 src = mputprintf(src,
2385 "%s_template& %s_template::operator=(const %s_template& other_value)\n"
2386 "{\n"
2387 "if (&other_value != this) {\n"
2388 "clean_up();\n"
2389 "copy_template(other_value);\n"
2390 "}\n"
2391 "return *this;\n"
2392 "}\n\n", name, name, name);
2393
2394 /* match function */
2395 def = mputprintf(def, "boolean match(const %s& other_value, boolean legacy "
2396 "= FALSE) const;\n", name);
2397 src = mputprintf(src, "boolean %s_template::match(const %s& other_value, "
2398 "boolean legacy) const\n"
2399 "{\n"
2400 "if (!other_value.is_bound()) return FALSE;\n"
2401 "switch (template_selection) {\n"
2402 "case ANY_VALUE:\n"
2403 "case ANY_OR_OMIT:\n"
2404 "return TRUE;\n"
2405 "case OMIT_VALUE:\n"
2406 "return FALSE;\n"
2407 "case SPECIFIC_VALUE:\n"
2408 "{\n"
2409 "%s value_selection = other_value.get_selection();\n"
2410 "if (value_selection == %s) return FALSE;\n"
2411 "if (value_selection != single_value.union_selection) return FALSE;\n"
2412 "switch (value_selection) {\n", name, name, selection_type, unbound_value);
2413 for (i = 0; i < sdef->nElements; i++) {
2414 src = mputprintf(src, "case %s_%s:\n"
2415 "return single_value.field_%s->match(other_value.%s%s(), legacy);\n",
2416 selection_prefix, sdef->elements[i].name, sdef->elements[i].name,
2417 at_field, sdef->elements[i].name);
2418 }
2419 src = mputprintf(src, "default:\n"
2420 "TTCN_error(\"Internal error: Invalid selector in a specific value when "
2421 "matching a template of union type %s.\");\n"
2422 "}\n"
2423 "}\n"
2424 "case VALUE_LIST:\n"
2425 "case COMPLEMENTED_LIST:\n"
2426 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
2427 "list_count++)\n"
2428 "if (value_list.list_value[list_count].match(other_value, legacy)) "
2429 "return template_selection == VALUE_LIST;\n"
2430 "return template_selection == COMPLEMENTED_LIST;\n"
2431 "default:\n"
2432 "TTCN_error (\"Matching an uninitialized template of union type %s.\");\n"
2433 "}\n"
2434 "return FALSE;\n"
2435 "}\n\n", dispname, dispname);
2436
2437 /* isvalue */
2438 def = mputstr(def, "boolean is_value() const;");
2439 src = mputprintf(src, "boolean %s_template::is_value() const\n"
2440 "{\n"
2441 "if (template_selection != SPECIFIC_VALUE || is_ifpresent) return false;\n"
2442 "switch (single_value.union_selection) {\n"
2443 , name);
2444 for (i = 0; i < sdef->nElements; i++) {
2445 src = mputprintf(src, "case %s_%s:\n"
2446 "return single_value.field_%s->is_value();\n", selection_prefix,
2447 sdef->elements[i].name, sdef->elements[i].name);
2448 }
2449 src = mputprintf(src, "default:\n"
2450 "TTCN_error(\"Internal error: Invalid selector in a specific value when "
2451 "performing is_value operation on a template of union type %s.\");\n"
2452 "}\n"
2453 "}\n\n", dispname);
2454
2455 /* valueof member function */
2456 def = mputprintf(def, "%s valueof() const;\n", name);
2457 src = mputprintf(src, "%s %s_template::valueof() const\n"
2458 "{\n"
2459 "if (template_selection != SPECIFIC_VALUE || is_ifpresent)\n"
2460 "TTCN_error(\"Performing valueof or send operation on a non-specific "
2461 "template of union type %s.\");\n"
2462 "%s ret_val;\n"
2463 "switch (single_value.union_selection) {\n", name, name, dispname, name);
2464 for (i = 0; i < sdef->nElements; i++) {
2465 src = mputprintf(src, "case %s_%s:\n"
2466 "ret_val.%s%s() = single_value.field_%s->valueof();\n"
2467 "break;\n", selection_prefix, sdef->elements[i].name,
2468 at_field, sdef->elements[i].name, sdef->elements[i].name);
2469 }
2470 src = mputprintf(src, "default:\n"
2471 "TTCN_error(\"Internal error: Invalid selector in a specific value when "
2472 "performing valueof operation on a template of union type %s.\");\n"
2473 "}\n"
2474 "%s"
2475 "return ret_val;\n"
2476 "}\n\n", dispname,
2477 use_runtime_2 ? "ret_val.set_err_descr(err_descr);\n" : "");
2478
2479 /* list_item(int) function */
2480 def = mputprintf(def, "%s_template& list_item(unsigned int list_index) "
2481 "const;\n", name);
2482 src = mputprintf(src,
2483 "%s_template& %s_template::list_item(unsigned int list_index) const\n"
2484 "{\n"
2485 "if (template_selection != VALUE_LIST && "
2486 "template_selection != COMPLEMENTED_LIST) TTCN_error(\"Internal error: "
2487 "Accessing a list element of a non-list template of union type %s.\");\n"
2488 "if (list_index >= value_list.n_values) "
2489 "TTCN_error(\"Internal error: Index overflow in a value list template "
2490 "of union type %s.\");\n"
2491 "return value_list.list_value[list_index];\n"
2492 "}\n", name, name, dispname, dispname);
2493
2494 /* void set_type(template_sel, int) function */
2495 def = mputstr(def, "void set_type(template_sel template_type, "
2496 "unsigned int list_length);\n");
2497 src = mputprintf(src,
2498 "void %s_template::set_type(template_sel template_type, "
2499 "unsigned int list_length)\n"
2500 "{\n"
2501 "if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST) "
2502 "TTCN_error (\"Internal error: Setting an invalid list for a template "
2503 "of union type %s.\");\n"
2504 "clean_up();\n"
2505 "set_selection(template_type);\n"
2506 "value_list.n_values = list_length;\n"
2507 "value_list.list_value = new %s_template[list_length];\n"
2508 "}\n\n", name, dispname, name);
2509
2510 /* field access functions */
2511 for (i = 0; i < sdef->nElements; i++) {
2512 def = mputprintf(def, "%s_template& %s%s();\n", sdef->elements[i].type,
2513 at_field, sdef->elements[i].name);
2514 src = mputprintf(src, "%s_template& %s_template::%s%s()\n"
2515 "{\n"
2516 "if (template_selection != SPECIFIC_VALUE || "
2517 "single_value.union_selection != %s_%s) {\n"
2518 "template_sel old_selection = template_selection;\n"
2519 "clean_up();\n"
2520 "if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) "
2521 "single_value.field_%s = new %s_template(ANY_VALUE);\n"
2522 "else single_value.field_%s = new %s_template;\n"
2523 "single_value.union_selection = %s_%s;\n"
2524 "set_selection(SPECIFIC_VALUE);\n"
2525 "}\n"
2526 "return *single_value.field_%s;\n"
2527 "}\n\n", sdef->elements[i].type, name, at_field, sdef->elements[i].name,
2528 selection_prefix, sdef->elements[i].name, sdef->elements[i].name,
2529 sdef->elements[i].type, sdef->elements[i].name, sdef->elements[i].type,
2530 selection_prefix, sdef->elements[i].name, sdef->elements[i].name);
2531
2532 def = mputprintf(def, "const %s_template& %s%s() const;\n",
2533 sdef->elements[i].type, at_field, sdef->elements[i].name);
2534 src = mputprintf(src, "const %s_template& %s_template::%s%s() const\n"
2535 "{\n"
2536 "if (template_selection != SPECIFIC_VALUE) TTCN_error(\"Accessing field "
2537 "%s in a non-specific template of union type %s.\");\n"
2538 "if (single_value.union_selection != %s_%s) "
2539 "TTCN_error(\"Accessing non-selected field %s in a template of union "
2540 "type %s.\");\n"
2541 "return *single_value.field_%s;\n"
2542 "}\n\n", sdef->elements[i].type, name, at_field, sdef->elements[i].name,
2543 sdef->elements[i].dispname, dispname, selection_prefix,
2544 sdef->elements[i].name, sdef->elements[i].dispname, dispname,
2545 sdef->elements[i].name);
2546 }
2547
2548 /* ischosen function */
2549 def = mputprintf(def, "boolean ischosen(%s checked_selection) const;\n",
2550 selection_type);
2551 src = mputprintf(src, "boolean %s_template::ischosen(%s checked_selection) "
2552 "const\n"
2553 "{\n"
2554 "if (checked_selection == %s) TTCN_error(\"Internal error: Performing "
2555 "ischosen() operation on an invalid field of union type %s.\");\n"
2556 "switch (template_selection) {\n"
2557 "case SPECIFIC_VALUE:\n"
2558 "if (single_value.union_selection == %s) TTCN_error(\"Internal error: "
2559 "Invalid selector in a specific value when performing ischosen() "
2560 "operation on a template of union type %s.\");\n"
2561 "return single_value.union_selection == checked_selection;\n"
2562 "case VALUE_LIST:\n"
2563 "{\n"
2564 "if (value_list.n_values < 1)\n"
2565 "TTCN_error(\"Internal error: Performing ischosen() operation on a "
2566 "template of union type %s containing an empty list.\");\n"
2567 "boolean ret_val = "
2568 "value_list.list_value[0].ischosen(checked_selection);\n"
2569 "boolean all_same = TRUE;\n"
2570 "for (unsigned int list_count = 1; list_count < value_list.n_values; "
2571 "list_count++) {\n"
2572 "if (value_list.list_value[list_count].ischosen(checked_selection) != "
2573 "ret_val) {\n"
2574 "all_same = FALSE;\n"
2575 "break;\n"
2576 "}\n"
2577 "}\n"
2578 "if (all_same) return ret_val;\n"
2579 "}\n"
2580 "case ANY_VALUE:\n"
2581 "case ANY_OR_OMIT:\n"
2582 "case OMIT_VALUE:\n"
2583 "case COMPLEMENTED_LIST:\n"
2584 "TTCN_error(\"Performing ischosen() operation on a template of union type "
2585 "%s, which does not determine unambiguously the chosen field of the "
2586 "matching values.\");\n"
2587 "default:\n"
2588 "TTCN_error(\"Performing ischosen() operation on an uninitialized "
2589 "template of union type %s\");\n"
2590 "}\n"
2591 "return FALSE;\n"
2592 "}\n\n", name, selection_type, unbound_value, dispname, unbound_value,
2593 dispname, dispname, dispname, dispname);
2594
2595 if (use_runtime_2) {
2596 def = mputstr(def,
2597 "void set_err_descr(Erroneous_descriptor_t* p_err_descr) { err_descr=p_err_descr; }\n");
2598 /** virtual stuff */
2599 def = mputstr(def,
2600 "void valueofv(Base_Type* value) const;\n"
2601 "void set_value(template_sel other_value);\n"
2602 "void copy_value(const Base_Type* other_value);\n"
2603 "Base_Template* clone() const;\n"
2604 "const TTCN_Typedescriptor_t* get_descriptor() const;\n"
2605 "boolean matchv(const Base_Type* other_value, boolean legacy) const;\n"
2606 "void log_matchv(const Base_Type* match_value, boolean legacy) const;\n");
2607 src = mputprintf(src,
2608 "void %s_template::valueofv(Base_Type* value) const "
2609 "{ *(static_cast<%s*>(value)) = valueof(); }\n"
2610 "void %s_template::set_value(template_sel other_value) "
2611 "{ *this = other_value; }\n"
2612 "void %s_template::copy_value(const Base_Type* other_value) "
2613 "{ *this = *(static_cast<const %s*>(other_value)); }\n"
2614 "Base_Template* %s_template::clone() const "
2615 "{ return new %s_template(*this); }\n"
2616 "const TTCN_Typedescriptor_t* %s_template::get_descriptor() const "
2617 "{ return &%s_descr_; }\n"
2618 "boolean %s_template::matchv(const Base_Type* other_value, "
2619 "boolean legacy) const "
2620 "{ return match(*(static_cast<const %s*>(other_value)), legacy); }\n"
2621 "void %s_template::log_matchv(const Base_Type* match_value, "
2622 "boolean legacy) const "
2623 " { log_match(*(static_cast<const %s*>(match_value)), legacy); }\n",
2624 name, name,
2625 name,
2626 name, name,
2627 name, name,
2628 name, name,
2629 name, name,
2630 name, name);
2631 }
2632
2633 /* log function */
2634 def = mputstr(def, "void log() const;\n");
2635 src = mputprintf(src,"void %s_template::log() const\n"
2636 "{\n"
2637 "switch (template_selection) {\n"
2638 "case SPECIFIC_VALUE:\n"
2639 "switch (single_value.union_selection) {\n", name);
2640 for (i = 0; i < sdef->nElements; i++) {
2641 src = mputprintf(src, "case %s_%s:\n"
2642 "TTCN_Logger::log_event_str(\"{ %s := \");\n"
2643 "single_value.field_%s->log();\n"
2644 "TTCN_Logger::log_event_str(\" }\");\n"
2645 "break;\n", selection_prefix, sdef->elements[i].name,
2646 sdef->elements[i].dispname, sdef->elements[i].name);
2647 }
2648 src = mputstr(src, "default:\n"
2649 "TTCN_Logger::log_event_str(\"<invalid selector>\");\n"
2650 "}\n"
2651 "break;\n"
2652 "case COMPLEMENTED_LIST:\n"
2653 "TTCN_Logger::log_event_str(\"complement \");\n"
2654 "case VALUE_LIST:\n"
2655 "TTCN_Logger::log_char('(');\n"
2656 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
2657 "list_count++) {\n"
2658 "if (list_count > 0) TTCN_Logger::log_event_str(\", \");\n"
2659 "value_list.list_value[list_count].log();\n"
2660 "}\n"
2661 "TTCN_Logger::log_char(')');\n"
2662 "break;\n"
2663 "default:\n"
2664 "log_generic();\n"
2665 "}\n"
2666 "log_ifpresent();\n");
2667 if (use_runtime_2) {
2668 src = mputstr(src, "if (err_descr) err_descr->log();\n");
2669 }
2670 src = mputstr(src, "}\n\n");
2671
2672 /* log_match function */
2673 def = mputprintf(def, "void log_match(const %s& match_value, "
2674 "boolean legacy = FALSE) const;\n", name);
2675 src = mputprintf(src,
2676 "void %s_template::log_match(const %s& match_value, boolean legacy) const\n"
2677 "{\n"
2678 "if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity() "
2679 "&& match(match_value, legacy)){\n"
2680 "TTCN_Logger::print_logmatch_buffer();\n"
2681 "TTCN_Logger::log_event_str(\" matched\");\n"
2682 "return;\n"
2683 "}\n"
2684 "if (template_selection == SPECIFIC_VALUE && "
2685 "single_value.union_selection == match_value.get_selection()) {\n"
2686 "switch (single_value.union_selection) {\n", name, name);
2687 for (i = 0; i < sdef->nElements; i++) {
2688 src = mputprintf(src, "case %s_%s:\n"
2689 "if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){\n"
2690 "TTCN_Logger::log_logmatch_info(\".%s\");\n"
2691 "single_value.field_%s->log_match(match_value.%s%s(), legacy);\n"
2692 "} else {\n"
2693 "TTCN_Logger::log_event_str(\"{ %s := \");\n"
2694 "single_value.field_%s->log_match(match_value.%s%s(), legacy);\n"
2695 "TTCN_Logger::log_event_str(\" }\");\n"
2696 "}\n"
2697 "break;\n", selection_prefix, sdef->elements[i].name,
2698 sdef->elements[i].dispname,
2699 sdef->elements[i].name, at_field, sdef->elements[i].name,
2700 sdef->elements[i].dispname, sdef->elements[i].name,
2701 at_field, sdef->elements[i].name);
2702 }
2703 src = mputstr(src, "default:\n"
2704 "TTCN_Logger::print_logmatch_buffer();\n"
2705 "TTCN_Logger::log_event_str(\"<invalid selector>\");\n"
2706 "}\n"
2707 "} else {\n"
2708 "TTCN_Logger::print_logmatch_buffer();\n"
2709 "match_value.log();\n"
2710 "TTCN_Logger::log_event_str(\" with \");\n"
2711 "log();\n"
2712 "if (match(match_value, legacy)) TTCN_Logger::log_event_str(\" matched\");\n"
2713 "else TTCN_Logger::log_event_str(\" unmatched\");\n"
2714 "}\n"
2715 "}\n\n");
2716
2717 /* encode_text function */
2718 def = mputstr(def, "void encode_text(Text_Buf& text_buf) const;\n");
2719 src = mputprintf(src,
2720 "void %s_template::encode_text(Text_Buf& text_buf) const\n"
2721 "{\n"
2722 "encode_text_base(text_buf);\n"
2723 "switch (template_selection) {\n"
2724 "case SPECIFIC_VALUE:\n"
2725 "text_buf.push_int(single_value.union_selection);\n"
2726 "switch (single_value.union_selection) {\n", name);
2727 for (i = 0; i < sdef->nElements; i++) {
2728 src = mputprintf(src, "case %s_%s:\n"
2729 "single_value.field_%s->encode_text(text_buf);\n"
2730 "break;\n", selection_prefix, sdef->elements[i].name,
2731 sdef->elements[i].name);
2732 }
2733 src = mputprintf(src, "default:\n"
2734 "TTCN_error(\"Internal error: Invalid selector in a specific value when "
2735 "encoding a template of union type %s.\");\n"
2736 "}\n"
2737 "case OMIT_VALUE:\n"
2738 "case ANY_VALUE:\n"
2739 "case ANY_OR_OMIT:\n"
2740 "break;\n"
2741 "case VALUE_LIST:\n"
2742 "case COMPLEMENTED_LIST:\n"
2743 "text_buf.push_int(value_list.n_values);\n"
2744 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
2745 "list_count++)\n"
2746 "value_list.list_value[list_count].encode_text(text_buf);\n"
2747 "break;\n"
2748 "default:\n"
2749 "TTCN_error(\"Text encoder: Encoding an uninitialized template of type "
2750 "%s.\");\n"
2751 "}\n"
2752 "}\n\n", dispname, dispname);
2753
2754 /* decode_text function */
2755 def = mputstr(def, "void decode_text(Text_Buf& text_buf);\n");
2756 src = mputprintf(src, "void %s_template::decode_text(Text_Buf& text_buf)\n"
2757 "{\n"
2758 "clean_up();\n"
2759 "decode_text_base(text_buf);\n"
2760 "switch (template_selection) {\n"
2761 "case SPECIFIC_VALUE:\n"
2762 "{\n"
2763 "single_value.union_selection = %s;\n"
2764 "%s new_selection = (%s)text_buf.pull_int().get_val();\n"
2765 "switch (new_selection) {\n", name, unbound_value, selection_type,
2766 selection_type);
2767 for (i = 0; i < sdef->nElements; i++) {
2768 src = mputprintf(src, "case %s_%s:\n"
2769 "single_value.field_%s = new %s_template;\n"
2770 "single_value.field_%s->decode_text(text_buf);\n"
2771 "break;\n", selection_prefix, sdef->elements[i].name,
2772 sdef->elements[i].name, sdef->elements[i].type, sdef->elements[i].name);
2773 }
2774 src = mputprintf(src, "default:\n"
2775 "TTCN_error(\"Text decoder: Unrecognized union selector was received for "
2776 "a template of type %s.\");\n"
2777 "}\n"
2778 "single_value.union_selection = new_selection;\n"
2779 "}\n"
2780 "case OMIT_VALUE:\n"
2781 "case ANY_VALUE:\n"
2782 "case ANY_OR_OMIT:\n"
2783 "break;\n"
2784 "case VALUE_LIST:\n"
2785 "case COMPLEMENTED_LIST:\n"
2786 "value_list.n_values = text_buf.pull_int().get_val();\n"
2787 "value_list.list_value = new %s_template[value_list.n_values];\n"
2788 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
2789 "list_count++)\n"
2790 "value_list.list_value[list_count].decode_text(text_buf);\n"
2791 "break;\n"
2792 "default:\n"
2793 "TTCN_error(\"Text decoder: Unrecognized selector was received in a "
2794 "template of type %s.\");\n"
2795 "}\n"
2796 "}\n\n", dispname, name, dispname);
2797
2798 /* TTCN-3 ispresent() function */
2799 def = mputstr(def, "boolean is_present(boolean legacy = FALSE) const;\n");
2800 src = mputprintf(src,
2801 "boolean %s_template::is_present(boolean legacy) const\n"
2802 "{\n"
2803 "if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;\n"
2804 "return !match_omit(legacy);\n"
2805 "}\n\n", name);
2806
2807 /* match_omit() */
2808 def = mputstr(def, "boolean match_omit(boolean legacy = FALSE) const;\n");
2809 src = mputprintf(src,
2810 "boolean %s_template::match_omit(boolean legacy) const\n"
2811 "{\n"
2812 "if (is_ifpresent) return TRUE;\n"
2813 "switch (template_selection) {\n"
2814 "case OMIT_VALUE:\n"
2815 "case ANY_OR_OMIT:\n"
2816 "return TRUE;\n"
2817 "case VALUE_LIST:\n"
2818 "case COMPLEMENTED_LIST:\n"
2819 "if (legacy) {\n"
2820 "for (unsigned int v_idx=0; v_idx<value_list.n_values; v_idx++)\n"
2821 "if (value_list.list_value[v_idx].match_omit())\n"
2822 "return template_selection==VALUE_LIST;\n"
2823 "return template_selection==COMPLEMENTED_LIST;\n"
2824 "} // else fall through\n"
2825 "default:\n"
2826 "return FALSE;\n"
2827 "}\n"
2828 "return FALSE;\n"
2829 "}\n\n", name);
2830
2831 /* set_param() */
2832 def = mputstr(def, "void set_param(Module_Param& param);\n");
2833 src = mputprintf(src,
2834 "void %s_template::set_param(Module_Param& param)\n"
2835 "{\n"
2836 " if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&\n"
2837 " param.get_id()->next_name()) {\n"
2838 // Haven't reached the end of the module parameter name
2839 // => the name refers to one of the fields, not to the whole union
2840 " char* param_field = param.get_id()->get_current_name();\n"
2841 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
2842 " param.error(\"Unexpected array index in module parameter, expected a valid field\"\n"
2843 " \" name for union template type `%s'\");\n"
2844 " }\n"
2845 " ", name, dispname);
2846 for (i = 0; i < sdef->nElements; i++) {
2847 src = mputprintf(src,
2848 "if (strcmp(\"%s\", param_field) == 0) {\n"
2849 " %s%s().set_param(param);\n"
2850 " return;\n"
2851 " } else ",
2852 sdef->elements[i].dispname, at_field, sdef->elements[i].name);
2853 }
2854 src = mputprintf(src,
2855 "param.error(\"Field `%%s' not found in union template type `%s'\", param_field);\n"
2856 " }\n"
2857 " param.basic_check(Module_Param::BC_TEMPLATE, \"union template\");\n"
2858 " Module_Param_Ptr m_p = &param;\n"
2859 " if (param.get_type() == Module_Param::MP_Reference) {\n"
2860 " m_p = param.get_referenced_param();\n"
2861 " }\n"
2862 " switch (m_p->get_type()) {\n"
2863 " case Module_Param::MP_Omit:\n"
2864 " *this = OMIT_VALUE;\n"
2865 " break;\n"
2866 " case Module_Param::MP_Any:\n"
2867 " *this = ANY_VALUE;\n"
2868 " break;\n"
2869 " case Module_Param::MP_AnyOrNone:\n"
2870 " *this = ANY_OR_OMIT;\n"
2871 " break;\n"
2872 " case Module_Param::MP_List_Template:\n"
2873 " case Module_Param::MP_ComplementList_Template: {\n"
2874 " %s_template new_temp;\n"
2875 " new_temp.set_type(m_p->get_type()==Module_Param::MP_List_Template ? "
2876 "VALUE_LIST : COMPLEMENTED_LIST, m_p->get_size());\n"
2877 " for (size_t p_i=0; p_i<m_p->get_size(); p_i++) {\n"
2878 " new_temp.list_item(p_i).set_param(*m_p->get_elem(p_i));\n"
2879 " }\n"
2880 " *this = new_temp;\n"
2881 " break; }\n"
2882 " case Module_Param::MP_Value_List:\n"
2883 " if (m_p->get_size()==0) break;\n" /* for backward compatibility */
2884 " param.type_error(\"union template\", \"%s\");\n"
2885 " break;\n"
2886 " case Module_Param::MP_Assignment_List: {\n"
2887 " Module_Param* mp_last = m_p->get_elem(m_p->get_size()-1);\n",
2888 dispname, name, dispname);
2889 for (i = 0; i < sdef->nElements; i++) {
2890 src = mputprintf(src,
2891 " if (!strcmp(mp_last->get_id()->get_name(), \"%s\")) {\n"
2892 " %s%s().set_param(*mp_last);\n"
2893 " break;\n"
2894 " }\n", sdef->elements[i].dispname, at_field, sdef->elements[i].name);
2895 }
2896 src = mputprintf(src,
2897 " mp_last->error(\"Field %%s does not exist in type %s.\", mp_last->get_id()->get_name());\n"
2898 " } break;\n"
2899 " default:\n"
2900 " param.type_error(\"union template\", \"%s\");\n"
2901 " }\n"
2902 " is_ifpresent = param.get_ifpresent() || m_p->get_ifpresent();\n"
2903 "}\n\n", dispname, dispname);
2904
2905 /* get_param() */
2906 def = mputstr(def, "Module_Param* get_param(Module_Param_Name& param_name) const;\n");
2907 src = mputprintf(src,
2908 "Module_Param* %s_template::get_param(Module_Param_Name& param_name) const\n"
2909 "{\n"
2910 " if (param_name.next_name()) {\n"
2911 // Haven't reached the end of the module parameter name
2912 // => the name refers to one of the fields, not to the whole union
2913 " char* param_field = param_name.get_current_name();\n"
2914 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
2915 " TTCN_error(\"Unexpected array index in module parameter reference, \"\n"
2916 " \"expected a valid field name for union template type `%s'\");\n"
2917 " }\n"
2918 " ", name, dispname);
2919 for (i = 0; i < sdef->nElements; i++) {
2920 src = mputprintf(src,
2921 "if (strcmp(\"%s\", param_field) == 0) {\n"
2922 " return %s%s().get_param(param_name);\n"
2923 " } else ",
2924 sdef->elements[i].dispname, at_field, sdef->elements[i].name);
2925 }
2926 src = mputprintf(src,
2927 "TTCN_error(\"Field `%%s' not found in union type `%s'\", param_field);\n"
2928 " }\n"
2929 " Module_Param* m_p = NULL;\n"
2930 " switch (template_selection) {\n"
2931 " case UNINITIALIZED_TEMPLATE:\n"
2932 " m_p = new Module_Param_Unbound();\n"
2933 " break;\n"
2934 " case OMIT_VALUE:\n"
2935 " m_p = new Module_Param_Omit();\n"
2936 " break;\n"
2937 " case ANY_VALUE:\n"
2938 " m_p = new Module_Param_Any();\n"
2939 " break;\n"
2940 " case ANY_OR_OMIT:\n"
2941 " m_p = new Module_Param_AnyOrNone();\n"
2942 " break;\n"
2943 " case SPECIFIC_VALUE: {\n"
2944 " Module_Param* mp_field = NULL;\n"
2945 " switch(single_value.union_selection) {\n"
2946 , name);
2947 for (i = 0; i < sdef->nElements; ++i) {
2948 src = mputprintf(src,
2949 " case %s_%s:\n"
2950 " mp_field = single_value.field_%s->get_param(param_name);\n"
2951 " mp_field->set_id(new Module_Param_FieldName(mcopystr(\"%s\")));\n"
2952 " break;\n"
2953 , selection_prefix, sdef->elements[i].name
2954 , sdef->elements[i].name, sdef->elements[i].dispname);
2955 }
2956 src = mputstr(src,
2957 " default:\n"
2958 " break;\n"
2959 " }\n"
2960 " m_p = new Module_Param_Assignment_List();\n"
2961 " m_p->add_elem(mp_field);\n"
2962 " break; }\n"
2963 " case VALUE_LIST:\n"
2964 " case COMPLEMENTED_LIST: {\n"
2965 " if (template_selection == VALUE_LIST) {\n"
2966 " m_p = new Module_Param_List_Template();\n"
2967 " }\n"
2968 " else {\n"
2969 " m_p = new Module_Param_ComplementList_Template();\n"
2970 " }\n"
2971 " for (size_t i_i = 0; i_i < value_list.n_values; ++i_i) {\n"
2972 " m_p->add_elem(value_list.list_value[i_i].get_param(param_name));\n"
2973 " }\n"
2974 " break; }\n"
2975 " default:\n"
2976 " break;\n"
2977 " }\n"
2978 " if (is_ifpresent) {\n"
2979 " m_p->set_ifpresent();\n"
2980 " }\n"
2981 " return m_p;\n"
2982 "}\n\n");
2983
2984 /* check template restriction */
2985 def = mputstr(def, "void check_restriction(template_res t_res, "
2986 "const char* t_name=NULL, boolean legacy = FALSE) const;\n");
2987 src = mputprintf(src,
2988 "void %s_template::check_restriction("
2989 "template_res t_res, const char* t_name, boolean legacy) const\n"
2990 "{\n"
2991 "if (template_selection==UNINITIALIZED_TEMPLATE) return;\n"
2992 "switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {\n"
2993 "case TR_OMIT:\n"
2994 "if (template_selection==OMIT_VALUE) return;\n"
2995 "case TR_VALUE:\n"
2996 "if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;\n"
2997 "switch (single_value.union_selection) {\n"
2998 , name);
2999 for (i = 0; i < sdef->nElements; i++) {
3000 src = mputprintf(src, "case %s_%s:\n"
3001 "single_value.field_%s->check_restriction("
3002 "t_res, t_name ? t_name : \"%s\");\n"
3003 "return;\n",
3004 selection_prefix, sdef->elements[i].name,
3005 sdef->elements[i].name, dispname);
3006 }
3007 src = mputprintf(src, "default:\n"
3008 "TTCN_error(\"Internal error: Invalid selector in a specific value when "
3009 "performing check_restriction operation on a template of union type %s.\");\n"
3010 "}\n"
3011 "case TR_PRESENT:\n"
3012 "if (!match_omit(legacy)) return;\n"
3013 "break;\n"
3014 "default:\n"
3015 "return;\n"
3016 "}\n"
3017 "TTCN_error(\"Restriction `%%s' on template of type %%s violated.\", "
3018 "get_res_name(t_res), t_name ? t_name : \"%s\");\n"
3019 "}\n\n", dispname, dispname);
3020
3021 def = mputstr(def, "};\n\n");
3022
3023 output->header.class_defs = mputstr(output->header.class_defs, def);
3024 Free(def);
3025
3026 output->source.methods = mputstr(output->source.methods, src);
3027 Free(src);
3028
3029 Free(selection_type);
3030 Free(unbound_value);
3031 Free(selection_prefix);
3032 }
This page took 0.107399 seconds and 5 git commands to generate.