1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #include "../common/memory.h"
16 #include "ttcn3/compiler.h"
18 void defEnumClass(const enum_def
*edef
, output_struct
*output
)
21 char *def
= NULL
, *src
= NULL
;
22 const char *name
= edef
->name
, *dispname
= edef
->dispname
;
23 boolean ber_needed
= edef
->isASN1
&& enable_ber();
24 boolean raw_needed
= edef
->hasRaw
&& enable_raw();
25 boolean text_needed
= edef
->hasText
&& enable_text();
26 boolean xer_needed
= edef
->hasXer
&& enable_xer();
27 boolean json_needed
= edef
->hasJson
&& enable_json();
29 char *enum_type
, *qualified_enum_type
, *unknown_value
, *unbound_value
;
30 enum_type
= mcopystr("enum_type");
31 qualified_enum_type
= mprintf("%s::enum_type", name
);
32 unknown_value
= mcopystr("UNKNOWN_VALUE");
33 unbound_value
= mcopystr("UNBOUND_VALUE");
35 /* Class declaration */
36 output
->header
.class_decls
= mputprintf(output
->header
.class_decls
,
39 /* Class definition */
42 "// written by %s in " __FILE__
" at %d\n"
44 "class %s : public %s { // enum\n"
45 "friend class %s_template;\n"
47 , __FUNCTION__
, __LINE__
49 , name
, (use_runtime_2
) ? "Enum_Type" : "Base_Type", name
);
50 def
= mputstr(def
, "public:\n"
52 for (i
= 0; i
< edef
->nElements
; i
++) {
53 def
= mputprintf(def
, "%s = %d, ", edef
->elements
[i
].name
,
54 edef
->elements
[i
].value
);
56 def
= mputprintf(def
, "UNKNOWN_VALUE = %d, UNBOUND_VALUE = %d };\n"
57 "private:\n", edef
->firstUnused
, edef
->secondUnused
);
58 def
= mputprintf(def
, "%s enum_value;\n\n"
59 "public:\n", enum_type
);
62 def
= mputprintf(def
, "%s();\n", name
);
63 src
= mputprintf(src
, "%s::%s()\n"
66 "}\n\n", name
, name
, unbound_value
);
68 def
= mputprintf(def
, "%s(int other_value);\n", name
);
70 "%s::%s(int other_value)\n"
72 "if (!is_valid_enum(other_value)) "
73 "TTCN_error(\"Initializing a variable of enumerated type %s with "
74 "invalid numeric value %%d.\", other_value);\n"
75 "enum_value = (%s)other_value;\n"
77 name
, name
, dispname
, enum_type
);
79 def
= mputprintf(def
, "%s(%s other_value);\n", name
, enum_type
);
81 "%s::%s(%s other_value)\n"
83 "enum_value = other_value;\n"
84 "}\n\n", name
, name
, enum_type
);
86 def
= mputprintf(def
, "%s(const %s& other_value);\n\n", name
, name
);
89 "%s::%s(const %s& other_value)\n"
90 ": %s()\n" /* Base class DEFAULT constructor*/
92 "if (other_value.enum_value == %s) "
93 "TTCN_error(\"Copying an unbound value of enumerated type %s.\");\n"
94 "enum_value = other_value.enum_value;\n"
95 "}\n\n", name
, name
, name
, (use_runtime_2
) ? "Enum_Type" : "Base_Type",
96 unbound_value
, dispname
);
98 /* assignment operators */
99 def
= mputprintf(def
, "%s& operator=(int other_value);\n", name
);
100 src
= mputprintf(src
,
101 "%s& %s::operator=(int other_value)\n"
103 "if (!is_valid_enum(other_value)) "
104 "TTCN_error(\"Assigning unknown numeric value %%d to a variable "
105 "of enumerated type %s.\", other_value);\n"
106 "enum_value = (%s)other_value;\n"
108 "}\n\n", name
, name
, dispname
, enum_type
);
110 def
= mputprintf(def
, "%s& operator=(%s other_value);\n", name
, enum_type
);
111 src
= mputprintf(src
,
112 "%s& %s::operator=(%s other_value)\n"
114 "enum_value = other_value;\n"
116 "}\n\n", name
, name
, enum_type
);
118 def
= mputprintf(def
, "%s& operator=(const %s& other_value);\n\n", name
,
120 src
= mputprintf(src
,
121 "%s& %s::operator=(const %s& other_value)\n"
123 "if (other_value.enum_value == %s) "
124 "TTCN_error(\"Assignment of an unbound value of enumerated type %s.\");\n"
125 "enum_value = other_value.enum_value;\n"
127 "}\n\n", name
, name
, name
, unbound_value
, dispname
);
129 /* Comparison operators */
130 def
= mputprintf(def
, "boolean operator==(%s other_value) const;\n",
132 src
= mputprintf(src
,
133 "boolean %s::operator==(%s other_value) const\n"
135 "if (enum_value == %s) "
136 "TTCN_error(\"The left operand of comparison is an unbound value of "
137 "enumerated type %s.\");\n"
138 "return enum_value == other_value;\n"
139 "}\n\n", name
, enum_type
, unbound_value
, dispname
);
141 def
= mputprintf(def
, "boolean operator==(const %s& other_value) const;\n",
143 src
= mputprintf(src
,
144 "boolean %s::operator==(const %s& other_value) const\n"
146 "if (enum_value == %s) "
147 "TTCN_error(\"The left operand of comparison is an unbound value of "
148 "enumerated type %s.\");\n"
149 "if (other_value.enum_value == %s) "
150 "TTCN_error(\"The right operand of comparison is an unbound value of "
151 "enumerated type %s.\");\n"
152 "return enum_value == other_value.enum_value;\n"
153 "}\n\n", name
, name
, unbound_value
, dispname
, unbound_value
, dispname
);
155 def
= mputprintf(def
, "inline boolean operator!=(%s other_value) "
156 "const { return !(*this == other_value); }\n", enum_type
);
158 def
= mputprintf(def
, "inline boolean operator!=(const %s& other_value) "
159 "const { return !(*this == other_value); }\n", name
);
161 def
= mputprintf(def
, "boolean operator<(%s other_value) const;\n",
163 src
= mputprintf(src
,
164 "boolean %s::operator<(%s other_value) const\n"
166 "if (enum_value == %s) "
167 "TTCN_error(\"The left operand of comparison is an unbound value of "
168 "enumerated type %s.\");\n"
169 "return enum_value < other_value;\n"
170 "}\n\n", name
, enum_type
, unbound_value
, dispname
);
172 def
= mputprintf(def
, "boolean operator<(const %s& other_value) const;\n",
174 src
= mputprintf(src
,
175 "boolean %s::operator<(const %s& other_value) const\n"
177 "if (enum_value == %s) "
178 "TTCN_error(\"The left operand of comparison is an unbound value of "
179 "enumerated type %s.\");\n"
180 "if (other_value.enum_value == %s) "
181 "TTCN_error(\"The right operand of comparison is an unbound value of "
182 "enumerated type %s.\");\n"
183 "return enum_value < other_value.enum_value;\n"
184 "}\n\n", name
, name
, unbound_value
, dispname
, unbound_value
, dispname
);
186 def
= mputprintf(def
, "boolean operator>(%s other_value) const;\n",
188 src
= mputprintf(src
,
189 "boolean %s::operator>(%s other_value) const\n"
191 "if (enum_value == %s) "
192 "TTCN_error(\"The left operand of comparison is an unbound value of "
193 "enumerated type %s.\");\n"
194 "return enum_value > other_value;\n"
195 "}\n\n", name
, enum_type
, unbound_value
, dispname
);
197 def
= mputprintf(def
, "boolean operator>(const %s& other_value) const;\n",
199 src
= mputprintf(src
,
200 "boolean %s::operator>(const %s& other_value) const\n"
202 "if (enum_value == %s) "
203 "TTCN_error(\"The left operand of comparison is an unbound value of "
204 "enumerated type %s.\");\n"
205 "if (other_value.enum_value == %s) "
206 "TTCN_error(\"The right operand of comparison is an unbound value of "
207 "enumerated type %s.\");\n"
208 "return enum_value > other_value.enum_value;\n"
209 "}\n\n", name
, name
, unbound_value
, dispname
, unbound_value
, dispname
);
211 def
= mputprintf(def
, "inline boolean operator<=(%s other_value) "
212 "const { return !(*this > other_value); }\n", enum_type
);
214 def
= mputprintf(def
, "inline boolean operator<=(const %s& other_value) "
215 "const { return !(*this > other_value); }\n", name
);
217 def
= mputprintf(def
, "inline boolean operator>=(%s other_value) "
218 "const { return !(*this < other_value); }\n", enum_type
);
220 def
= mputprintf(def
, "inline boolean operator>=(const %s& other_value) "
221 "const { return !(*this < other_value); }\n\n", name
);
223 /* Conversion function: enum_to_str */
224 def
= mputprintf(def
, "static const char *enum_to_str(%s enum_par%s);\n",
226 edef
->xerText
? ", boolean txt = false" : "");
227 src
= mputprintf(src
, "const char *%s::enum_to_str(%s enum_par%s)\n"
229 "switch (enum_par) {\n", name
, enum_type
,
230 edef
->xerText
? ", boolean txt" : "");
231 for (i
= 0; i
< edef
->nElements
; i
++) {
232 if (edef
->elements
[i
].text
) {
233 src
= mputprintf(src
,
234 "case %s: if (txt) return \"%s\"; else return \"%s\";\n",
235 edef
->elements
[i
].name
, edef
->elements
[i
].text
, edef
->elements
[i
].dispname
);
238 src
= mputprintf(src
, "case %s: return \"%s\";\n",
239 edef
->elements
[i
].name
, edef
->elements
[i
].dispname
);
242 src
= mputstr(src
, "default: return \"<unknown>\";\n"
246 /* Conversion function: str_to_enum */
247 def
= mputprintf(def
, "static %s str_to_enum(const char *str_par);\n",
249 src
= mputprintf(src
, "%s %s::str_to_enum(const char *str_par)\n"
250 "{\n", qualified_enum_type
, name
);
251 for (i
= 0; i
< edef
->nElements
; i
++) {
252 if (edef
->elements
[i
].text
) {
253 src
= mputprintf(src
, "if (!strcmp(str_par, \"%s\") || !strcmp(str_par, \"%s\")) return %s;\n"
254 "else ", edef
->elements
[i
].text
, edef
->elements
[i
].dispname
, edef
->elements
[i
].name
);
257 src
= mputprintf(src
, "if (!strcmp(str_par, \"%s\")) return %s;\n"
258 "else ", edef
->elements
[i
].dispname
, edef
->elements
[i
].name
);
261 src
= mputprintf(src
, "return %s;\n"
262 "}\n\n", unknown_value
);
264 /* Checking function: is_valid_enum */
265 def
= mputstr(def
, "static boolean is_valid_enum(int int_par);\n\n");
266 src
= mputprintf(src
, "boolean %s::is_valid_enum(int int_par)\n"
268 "switch (int_par) {\n", name
);
269 for (i
= 0; i
< edef
->nElements
; i
++) {
270 src
= mputprintf(src
, "case %d:\n", edef
->elements
[i
].value
);
272 src
= mputstr(src
, "return TRUE;\n"
278 /* TTCN-3 predefined function enum2int() */
279 def
= mputprintf(def
, "static int enum2int(%s enum_par);\n", enum_type
);
280 src
= mputprintf(src
, "int %s::enum2int(%s enum_par)\n"
282 "if (enum_par==%s || enum_par==%s) TTCN_error(\"The argument of function "
283 "enum2int() is an %%s value of enumerated type %s.\", "
284 "enum_par==%s?\"unbound\":\"invalid\");\n"
287 name
, enum_type
, unbound_value
, unknown_value
, dispname
, unbound_value
);
288 def
= mputprintf(def
, "static int enum2int(const %s& enum_par);\n", name
);
289 src
= mputprintf(src
, "int %s::enum2int(const %s& enum_par)\n"
291 "if (enum_par.enum_value==%s || enum_par.enum_value==%s) "
292 "TTCN_error(\"The argument of function "
293 "enum2int() is an %%s value of enumerated type %s.\", "
294 "enum_par==%s?\"unbound\":\"invalid\");\n"
295 "return enum_par.enum_value;\n"
297 name
, name
, unbound_value
, unknown_value
, dispname
, unbound_value
);
299 "int as_int() const { return enum2int(enum_value); }\n"
300 "void from_int(int p_val) { *this = p_val; }\n");
302 /* miscellaneous members */
303 def
= mputprintf(def
, "operator %s() const;\n", enum_type
);
304 src
= mputprintf(src
,
305 "%s::operator %s() const\n"
307 "if (enum_value == %s) "
308 "TTCN_error(\"Using the value of an unbound variable of enumerated "
310 "return enum_value;\n"
311 "}\n\n", name
, qualified_enum_type
, unbound_value
, dispname
);
313 def
= mputprintf(def
, "inline boolean is_bound() const "
314 "{ return enum_value != %s; }\n", unbound_value
);
315 def
= mputprintf(def
, "inline boolean is_value() const "
316 "{ return enum_value != %s; }\n", unbound_value
);
317 def
= mputprintf(def
, "inline void clean_up()"
318 "{ enum_value = %s; }\n", unbound_value
);
322 "boolean is_equal(const Base_Type* other_value) const;\n"
323 "void set_value(const Base_Type* other_value);\n"
324 "Base_Type* clone() const;\n"
325 "const TTCN_Typedescriptor_t* get_descriptor() const;\n");
326 src
= mputprintf(src
,
327 "boolean %s::is_equal(const Base_Type* other_value) const "
328 "{ return *this == *(static_cast<const %s*>(other_value)); }\n"
329 "void %s::set_value(const Base_Type* other_value) "
330 "{ *this = *(static_cast<const %s*>(other_value)); }\n"
331 "Base_Type* %s::clone() const { return new %s(*this); }\n"
332 "const TTCN_Typedescriptor_t* %s::get_descriptor() const "
333 "{ return &%s_descr_; }\n",
340 "inline boolean is_present() const { return is_bound(); }\n");
343 def
= mputstr(def
, "void log() const;\n");
344 src
= mputprintf(src
,
345 "void %s::log() const\n"
347 "if (enum_value != %s) TTCN_Logger::log_event_enum(enum_to_str(enum_value), enum_value);\n"
348 "else TTCN_Logger::log_event_unbound();\n"
349 "}\n\n", name
, unbound_value
);
351 def
= mputstr(def
, "void set_param(Module_Param& param);\n");
354 "void %s::set_param(Module_Param& param)\n"
356 " param.basic_check(Module_Param::BC_VALUE, \"enumerated value\");\n"
357 " if (param.get_type()!=Module_Param::MP_Enumerated) param.type_error(\"enumerated value\", \"%s\");\n"
358 " enum_value = str_to_enum(param.get_enumerated());\n"
359 " if (!is_valid_enum(enum_value)) {\n "
360 " param.error(\"Invalid enumerated value for type %s.\");\n"
362 "}\n\n", name
, dispname
, dispname
);
364 /* encoders/decoders */
365 def
= mputstr(def
, "void encode_text(Text_Buf& text_buf) const;\n");
366 src
= mputprintf(src
,
367 "void %s::encode_text(Text_Buf& text_buf) const\n"
369 "if (enum_value == %s) "
370 "TTCN_error(\"Text encoder: Encoding an unbound value of enumerated "
372 "text_buf.push_int(enum_value);\n"
373 "}\n\n", name
, unbound_value
, dispname
);
375 def
= mputstr(def
, "void decode_text(Text_Buf& text_buf);\n");
376 src
= mputprintf(src
,
377 "void %s::decode_text(Text_Buf& text_buf)\n"
379 "enum_value = (%s)text_buf.pull_int().get_val();\n"
380 "if (!is_valid_enum(enum_value)) "
381 "TTCN_error(\"Text decoder: Unknown numeric value %%d was "
382 "received for enumerated type %s.\", enum_value);\n"
383 "}\n\n", name
, enum_type
, dispname
);
386 if(ber_needed
|| raw_needed
|| text_needed
|| xer_needed
|| json_needed
)
387 def_encdec(name
, &def
, &src
, ber_needed
,
388 raw_needed
,text_needed
, xer_needed
, json_needed
, TRUE
);
391 "ASN_BER_TLV_t* %s::BER_encode_TLV(const TTCN_Typedescriptor_t&"
392 " p_td, unsigned p_coding) const\n"
394 " BER_chk_descr(p_td);\n"
395 " ASN_BER_TLV_t *new_tlv=BER_encode_chk_bound(is_bound());\n"
397 " BER_encode_chk_enum_valid(p_td, is_valid_enum(enum_value),"
399 " new_tlv=BER_encode_TLV_INTEGER(p_coding, enum_value);\n"
401 " new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);\n"
405 "boolean %s::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,"
406 " const ASN_BER_TLV_t& p_tlv, unsigned L_form)\n"
408 " enum_value = %s;\n"
409 " BER_chk_descr(p_td);\n"
410 " ASN_BER_TLV_t stripped_tlv;\n"
411 " BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);\n"
412 " TTCN_EncDec_ErrorContext ec(\"While decoding ENUMERATED type %s: "
415 " if (BER_decode_TLV_INTEGER(stripped_tlv, L_form, tmp_mfr)) {\n"
416 " BER_decode_chk_enum_valid(p_td, is_valid_enum(tmp_mfr), tmp_mfr);\n"
417 " enum_value = (%s)tmp_mfr;\n"
419 " } else return FALSE;\n"
421 , name
, name
, unbound_value
, dispname
, enum_type
);
422 } /* if ber_needed */
423 /* new TEXT functions */
425 src
= mputprintf(src
,
426 "int %s::TEXT_encode(const TTCN_Typedescriptor_t& p_td,"
427 "TTCN_Buffer& p_buf) const{\n"
428 "int encoded_length=0;\n"
429 "if(p_td.text->begin_encode){\n"
430 " p_buf.put_cs(*p_td.text->begin_encode);\n"
431 " encoded_length+=p_td.text->begin_encode->lengthof();\n"
433 " if (enum_value == %s) {\n"
434 " TTCN_EncDec_ErrorContext::error\n"
435 " (TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value of "
436 "enumerated type %s.\");\n"
437 " if(p_td.text->end_encode){\n"
438 " p_buf.put_cs(*p_td.text->end_encode);\n"
439 " encoded_length+=p_td.text->end_encode->lengthof();\n"
441 " return encoded_length;\n"
443 "if(p_td.text->val.enum_values==NULL){\n"
444 " int len=strlen(enum_to_str(enum_value));\n"
445 " p_buf.put_s(len,(const unsigned char*)enum_to_str(enum_value));\n"
446 " encoded_length+=len;\n"
448 "switch(enum_value){\n"
449 , name
, unbound_value
, dispname
451 for(i
=0;i
<edef
->nElements
;i
++){
452 src
= mputprintf(src
,
454 "if(p_td.text->val.enum_values[%lu].encode_token){\n"
455 " p_buf.put_cs(*p_td.text->val.enum_values[%lu].encode_token);\n"
456 " encoded_length+=p_td.text->val.enum_values[%lu]"
457 ".encode_token->lengthof();\n"
459 " int len=strlen(enum_to_str(enum_value));\n"
460 " p_buf.put_s(len,(const unsigned char*)enum_to_str(enum_value));\n"
461 " encoded_length+=len;\n"
464 ,edef
->elements
[i
].name
,
465 (unsigned long) i
,(unsigned long) i
,(unsigned long) i
474 " if(p_td.text->end_encode){\n"
475 " p_buf.put_cs(*p_td.text->end_encode);\n"
476 " encoded_length+=p_td.text->end_encode->lengthof();\n"
478 " return encoded_length;\n"
481 src
= mputprintf(src
,
482 "int %s::TEXT_decode(const TTCN_Typedescriptor_t& p_td,"
483 " TTCN_Buffer& p_buf, Limit_Token_List& limit, boolean no_err, boolean){\n"
484 " int decoded_length=0;\n"
486 " if(p_td.text->begin_decode){\n"
488 " if((tl=p_td.text->begin_decode->match_begin(p_buf))<0){\n"
489 " if(no_err)return -1;\n"
490 " TTCN_EncDec_ErrorContext::error\n"
491 " (TTCN_EncDec::ET_TOKEN_ERR, \"The specified token '%%s'"
492 " not found for '%%s': \",(const char*)*(p_td.text->begin_decode)"
496 " decoded_length+=tl;\n"
497 " p_buf.increase_pos(tl);\n"
499 " if(p_buf.get_read_len()<1 && no_err) return -1;\n"
504 for(i
=0;i
<edef
->nElements
;i
++){
505 src
= mputprintf(src
,
506 "if((str_len=p_td.text->val.enum_values[%lu].decode_token->"
507 "match_begin(p_buf))!=-1){\n"
510 ,(unsigned long) i
,edef
->elements
[i
].name
516 " if(no_err)return -1;\n"
517 " TTCN_EncDec_ErrorContext::error"
518 "(TTCN_EncDec::ET_TOKEN_ERR, \"No enum token found for '%s': \""
520 " return decoded_length;\n"
522 " decoded_length+=str_len;\n"
523 " p_buf.increase_pos(str_len);\n"
524 " if(p_td.text->end_decode){\n"
526 " if((tl=p_td.text->end_decode->match_begin(p_buf))<0){\n"
527 " if(no_err)return -1;\n"
528 " TTCN_EncDec_ErrorContext::error"
529 "(TTCN_EncDec::ET_TOKEN_ERR, \"The specified token '%s'"
530 " not found for '%s': \",(const char*)*(p_td.text->end_decode)"
532 " return decoded_length;\n"
534 " decoded_length+=tl;\n"
535 " p_buf.increase_pos(tl);\n"
537 " return decoded_length;\n"
541 /* new RAW functions */
544 int max_val
= edef
->firstUnused
;
546 for (a
= 0; a
< edef
->nElements
; a
++) {
547 int val
= edef
->elements
[a
].value
;
548 if (abs(max_val
) < abs(val
)) max_val
= val
;
558 src
= mputprintf(src
,
559 "int %s::RAW_decode(const TTCN_Typedescriptor_t& p_td,TTCN_Buffer& p_buf,"
560 "int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean)\n"
562 " int decoded_value = 0;\n"
563 " int decoded_length = RAW_decode_enum_type(p_td, p_buf, limit, "
564 "top_bit_ord, decoded_value, %d, no_err);\n"
565 " if (decoded_length < 0) return decoded_length;\n"
566 " if (is_valid_enum(decoded_value)) "
567 "enum_value = (%s)decoded_value;\n"
572 " TTCN_EncDec_ErrorContext::error\n"
573 " (TTCN_EncDec::ET_ENC_ENUM, \"Invalid enum value '%%d'"
574 " for '%%s': \",decoded_value, p_td.name);\n"
575 " enum_value = %s;\n"
578 " return decoded_length;\n"
579 "}\n\n", name
, min_bits
, enum_type
, unknown_value
);
580 src
= mputprintf(src
,
581 "int %s::RAW_encode(const TTCN_Typedescriptor_t& p_td, "
582 "RAW_enc_tree& myleaf) const\n"
584 " return RAW_encode_enum_type(p_td, myleaf, (int)enum_value, %d);\n"
585 "}\n\n", name
, min_bits
);
586 } /* if raw_needed */
588 if (xer_needed
) { /* XERSTUFF encoder codegen for enum */
589 /* FIXME This is redundant,
590 * because the code is identical to BaseType::can_start()
591 * and enum types are derived from BaseType or EnumType (which, in turn,
592 * is derived from BaseType). However, the declaration of can_start()
593 * is written by def_encdec() in encdec.c, which doesn't know
594 * that this is an enum type. Maybe we need to pass an is_enum to
595 * def_encdec, and then we can omit generating can_start() for enums.
597 src
= mputprintf(src
,
598 "boolean %s::can_start(const char *name, const char *uri, "
599 "const XERdescriptor_t& xd, unsigned int flavor) {\n"
600 " boolean exer = is_exer(flavor);\n"
601 " return check_name(name, xd, exer) && (!exer || check_namespace(uri, xd));\n"
606 src
= mputprintf(src
,
607 "int %s::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,"
608 " unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const\n"
610 " int encoded_length=(int)p_buf.get_len();\n"
611 " const boolean e_xer = is_exer(p_flavor);\n"
612 " p_flavor |= (SIMPLE_TYPE | BXER_EMPTY_ELEM);\n"
613 " if (begin_xml(p_td, p_buf, p_flavor, p_indent, false) == -1) "
614 "--encoded_length;\n"
615 " if (!e_xer) p_buf.put_c('<');\n"
618 if (edef
->xerUseNumber
) {
620 " if (e_xer) {\n" /* compile-time instead of p_td.useNumber */
621 " char sval[24];\n" /* unsigned 64 bits fit in 20 characters */
622 " int slen = snprintf(sval, 24, \"%d\", enum_value);\n"
623 " if (slen > 0) p_buf.put_s((size_t)slen, (const unsigned char*)sval);\n"
625 " else" /* no newline, will take over following curly */
628 src
= mputprintf(src
,
630 " const char * enumval = enum_to_str(enum_value%s);\n"
631 " p_buf.put_s(strlen(enumval), (const unsigned char*)enumval);\n"
633 " if (!e_xer) p_buf.put_s(2, (const unsigned char*)\"/>\");\n"
634 " end_xml(p_td, p_buf, p_flavor, p_indent, false);\n"
635 , edef
->xerText
? ", e_xer" : ""
638 " return (int)p_buf.get_len() - encoded_length;\n"
641 src
= mputprintf(src
, /* XERSTUFF decoder codegen for enum */
643 "// written by %s in " __FILE__
" at %d\n"
645 "int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader,"
646 " unsigned int p_flavor, embed_values_dec_struct_t*)\n"
648 " int rd_ok = 1, type;\n"
650 " const int e_xer = is_exer(p_flavor);\n"
651 " const boolean name_tag = !((!e_xer && is_record_of(p_flavor)) || (e_xer && ((p_td.xer_bits & UNTAGGED) ||(is_record_of(p_flavor) && is_exerlist(p_flavor)))));\n"
652 " if (e_xer && ((p_td.xer_bits & XER_ATTRIBUTE) || is_exerlist(p_flavor))) {\n"
653 " if ((p_td.xer_bits & XER_ATTRIBUTE)) verify_name(p_reader, p_td, e_xer);\n"
654 " const char * value = (const char *)p_reader.Value();\n"
657 , __FUNCTION__
, __LINE__
660 if (edef
->xerUseNumber
) {
661 src
= mputprintf(src
,
663 " sscanf(value, \"%%d\", &tempvalue);\n"
664 " if (is_valid_enum(tempvalue)) enum_value = (%s)tempvalue;\n" /* static_cast would be nice */
665 " else enum_value = %s;\n", enum_type
, unknown_value
669 src
= mputstr(src
, " enum_value = str_to_enum(value);\n");
673 /* The caller should do AdvanceAttribute() */
677 /* Go past the opening tag with the type name */
678 " for (; rd_ok == 1; rd_ok = p_reader.Read()) {\n"
679 " type = p_reader.NodeType();\n"
680 " if (XML_READER_TYPE_ELEMENT == type) {\n"
681 " rd_ok = p_reader.Read();\n"
685 /* Go to the element with the actual data (EmptyElementEnumerated) */
686 " for (; rd_ok == 1; rd_ok = p_reader.Read()) {\n"
687 " type = p_reader.NodeType();\n"
688 " if (!e_xer && XML_READER_TYPE_ELEMENT == type) break;\n"
689 " if (XML_READER_TYPE_TEXT == type) break;\n"
691 " const char *local_name = e_xer ? (const char *)p_reader.Value() : (const char *)p_reader.Name();\n"
692 /* TextEnumerated EmptyElementEnumerated */
693 " if (!local_name) ; else");
694 if (edef
->xerUseNumber
) {
695 src
= mputprintf(src
,
698 " sscanf(local_name, \"%%d\", &tempvalue);\n"
699 " if (is_valid_enum(tempvalue)) enum_value = (%s)tempvalue;\n" /* static_cast would be nice */
700 " else enum_value = %s;\n"
702 " else" /* no newline */ , enum_type
, unknown_value
708 " for (; '\\t'==*local_name || '\\n'==*local_name; ++local_name) ;\n" /* crutch while default-for-empty always puts in a newline */
709 " enum_value = str_to_enum(local_name);\n"
712 src
= mputprintf(src
,
714 " for (rd_ok = p_reader.Read(); rd_ok == 1; rd_ok = p_reader.Read()) {\n"
715 " type = p_reader.NodeType();\n"
716 " if (XML_READER_TYPE_END_ELEMENT == type) {\n"
717 " rd_ok = p_reader.Read();\n"
721 " else rd_ok = p_reader.Read();\n"
723 " if (e_xer && (p_flavor & EXIT_ON_ERROR) && %s == enum_value) clean_up();\n" // set to unbound if decoding failed
724 " int decoded_length = 0;\n"
725 " return decoded_length;\n"
731 src
= mputprintf(src
,
732 "int %s::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const\n"
734 " if (enum_value == %s) {\n"
735 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,\n"
736 " \"Encoding an unbound value of enumerated type %s.\");\n"
739 " char* tmp_str = mprintf(\"\\\"%%s\\\"\", enum_to_str(enum_value));\n"
740 " int enc_len = p_tok.put_next_token(JSON_TOKEN_STRING, tmp_str);\n"
744 , name
, unbound_value
, dispname
);
747 src
= mputprintf(src
,
748 "int %s::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent)\n"
750 " json_token_t token = JSON_TOKEN_NONE;\n"
751 " char* value = 0;\n"
752 " size_t value_len = 0;\n"
753 " boolean error = false;\n"
754 " int dec_len = 0;\n"
755 " boolean use_default = p_td.json->default_value && 0 == p_tok.get_buffer_length();\n"
756 " if (use_default) {\n"
757 // No JSON data in the buffer -> use default value
758 " value = (char*)p_td.json->default_value;\n"
759 " value_len = strlen(value);\n"
761 " dec_len = p_tok.get_next_token(&token, &value, &value_len);\n"
763 " if (JSON_TOKEN_ERROR == token) {\n"
764 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, \"\");\n"
765 " return JSON_ERROR_FATAL;\n"
767 " else if (JSON_TOKEN_STRING == token || use_default) {\n"
768 " if (use_default || (value_len > 2 && value[0] == '\\\"' && value[value_len - 1] == '\\\"')) {\n"
769 " if (!use_default) value[value_len - 1] = 0;\n"
770 " enum_value = str_to_enum(value + (use_default ? 0 : 1));\n"
771 " if (!use_default) value[value_len - 1] = '\\\"';\n"
772 " if (%s == enum_value) {\n"
779 " enum_value = %s;\n"
780 " return JSON_ERROR_INVALID_TOKEN;\n"
783 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FORMAT_ERROR, \"string\", \"enumerated\");\n"
784 " enum_value = %s;\n"
785 " return JSON_ERROR_FATAL;\n"
789 , name
, unknown_value
, unbound_value
, unbound_value
);
792 def
= mputstr(def
, "};\n\n");
794 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
796 output
->source
.methods
= mputstr(output
->source
.methods
, src
);
801 Free(qualified_enum_type
);
806 void defEnumTemplate(const enum_def
*edef
, output_struct
*output
)
808 char *def
= NULL
, *src
= NULL
;
809 const char *name
= edef
->name
, *dispname
= edef
->dispname
;
811 char *enum_type
, *unbound_value
;
812 enum_type
= mprintf("%s::enum_type", name
);
813 unbound_value
= mprintf("%s::UNBOUND_VALUE", name
);
815 /* Class declaration */
816 output
->header
.class_decls
= mputprintf(output
->header
.class_decls
,
817 "class %s_template;\n", name
);
819 /* Class definition */
820 def
= mputprintf(def
, "class %s_template : public Base_Template {\n"
824 "unsigned int n_values;\n"
825 "%s_template *list_value;\n"
827 "};\n\n", name
, enum_type
, name
);
829 /* private members */
830 def
= mputprintf(def
, "void copy_template(const %s_template& "
831 "other_value);\n", name
);
832 src
= mputprintf(src
,
833 "void %s_template::copy_template(const %s_template& "
836 "set_selection(other_value);\n"
837 "switch (template_selection) {\n"
838 "case SPECIFIC_VALUE:\n"
839 "single_value = other_value.single_value;\n"
843 "case ANY_OR_OMIT:\n"
846 "case COMPLEMENTED_LIST:\n"
847 "value_list.n_values = other_value.value_list.n_values;\n"
848 "value_list.list_value = new %s_template[value_list.n_values];\n"
849 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
851 "value_list.list_value[list_count].copy_template("
852 "other_value.value_list.list_value[list_count]);\n"
855 "TTCN_error(\"Copying an uninitialized/unsupported template of "
856 "enumerated type %s.\");\n"
858 "}\n\n", name
, name
, name
, dispname
);
860 def
= mputstr(def
, "\npublic:\n");
863 def
= mputprintf(def
, "%s_template();\n", name
);
864 src
= mputprintf(src
,
865 "%s_template::%s_template()\n"
867 "}\n\n", name
, name
);
869 def
= mputprintf(def
, "%s_template(template_sel other_value);\n", name
);
870 src
= mputprintf(src
,
871 "%s_template::%s_template(template_sel other_value)\n"
872 " : Base_Template(other_value)\n"
874 "check_single_selection(other_value);\n"
875 "}\n\n", name
, name
);
877 def
= mputprintf(def
, "%s_template(int other_value);\n", name
);
878 src
= mputprintf(src
,
879 "%s_template::%s_template(int other_value)\n"
880 " : Base_Template(SPECIFIC_VALUE)\n"
882 "if (!%s::is_valid_enum(other_value)) "
883 "TTCN_error(\"Initializing a template of enumerated type %s with "
884 "unknown numeric value %%d.\", other_value);\n"
885 "single_value = (%s)other_value;\n"
886 "}\n\n", name
, name
, name
, dispname
, enum_type
);
888 def
= mputprintf(def
, "%s_template(%s other_value);\n", name
, enum_type
);
889 src
= mputprintf(src
,
890 "%s_template::%s_template(%s other_value)\n"
891 " : Base_Template(SPECIFIC_VALUE)\n"
893 "single_value = other_value;\n"
894 "}\n\n", name
, name
, enum_type
);
896 def
= mputprintf(def
, "%s_template(const %s& other_value);\n", name
, name
);
897 src
= mputprintf(src
,
898 "%s_template::%s_template(const %s& other_value)\n"
899 " : Base_Template(SPECIFIC_VALUE)\n"
901 "if (other_value.enum_value == %s) "
902 "TTCN_error(\"Creating a template from an unbound value of enumerated "
904 "single_value = other_value.enum_value;\n"
905 "}\n\n", name
, name
, name
, unbound_value
, dispname
);
907 def
= mputprintf(def
, "%s_template(const OPTIONAL<%s>& other_value);\n",
909 src
= mputprintf(src
,
910 "%s_template::%s_template(const OPTIONAL<%s>& other_value)\n"
912 "switch (other_value.get_selection()) {\n"
913 "case OPTIONAL_PRESENT:\n"
914 "set_selection(SPECIFIC_VALUE);\n"
915 "single_value = (%s)(const %s&)other_value;\n"
917 "case OPTIONAL_OMIT:\n"
918 "set_selection(OMIT_VALUE);\n"
921 "TTCN_error(\"Creating a template of enumerated type %s from an unbound "
922 "optional field.\");\n"
924 "}\n\n", name
, name
, name
, enum_type
, name
, dispname
);
926 def
= mputprintf(def
, "%s_template(const %s_template& other_value);\n",
928 src
= mputprintf(src
,
929 "%s_template::%s_template(const %s_template& other_value)\n"
930 " : Base_Template()\n"
932 "copy_template(other_value);\n"
933 "}\n\n", name
, name
, name
);
936 def
= mputprintf(def
, "~%s_template();\n\n", name
);
937 src
= mputprintf(src
,
938 "%s_template::~%s_template()\n"
941 "}\n\n", name
, name
);
944 def
= mputstr(def
, "boolean is_bound() const;\n");
945 src
= mputprintf(src
, "boolean %s_template::is_bound() const\n"
947 "if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) "
948 "return FALSE;\n", name
);
949 src
= mputstr(src
, "return TRUE;\n"
953 def
= mputstr(def
, "boolean is_value() const;\n");
954 src
= mputprintf(src
, "boolean %s_template::is_value() const\n"
956 "if (template_selection != SPECIFIC_VALUE || is_ifpresent) "
958 "return single_value != %s;\n"
959 "}\n\n", name
, unbound_value
);
962 def
= mputstr(def
, "void clean_up();\n");
963 src
= mputprintf(src
,
964 "void %s_template::clean_up()\n"
966 "if (template_selection == VALUE_LIST || "
967 "template_selection == COMPLEMENTED_LIST) "
968 "delete [] value_list.list_value;\n"
969 "template_selection = UNINITIALIZED_TEMPLATE;\n"
972 /* assignment operators */
973 def
= mputprintf(def
, "%s_template& operator=(template_sel other_value);\n",
975 src
= mputprintf(src
,
976 "%s_template& %s_template::operator=(template_sel other_value)\n"
978 "check_single_selection(other_value);\n"
980 "set_selection(other_value);\n"
982 "}\n\n", name
, name
);
984 def
= mputprintf(def
, "%s_template& operator=(int other_value);\n",
986 src
= mputprintf(src
,
987 "%s_template& %s_template::operator=(int other_value)\n"
989 "if (!%s::is_valid_enum(other_value)) "
990 "TTCN_warning(\"Assigning unknown numeric value %%d to a template "
991 "of enumerated type %s.\", other_value);\n"
993 "set_selection(SPECIFIC_VALUE);\n"
994 "single_value = (%s)other_value;\n"
996 "}\n\n", name
, name
, name
, dispname
, enum_type
);
998 def
= mputprintf(def
, "%s_template& operator=(%s other_value);\n",
1000 src
= mputprintf(src
,
1001 "%s_template& %s_template::operator=(%s other_value)\n"
1004 "set_selection(SPECIFIC_VALUE);\n"
1005 "single_value = other_value;\n"
1007 "}\n\n", name
, name
, enum_type
);
1009 def
= mputprintf(def
, "%s_template& operator=(const %s& other_value);\n",
1011 src
= mputprintf(src
,
1012 "%s_template& %s_template::operator=(const %s& other_value)\n"
1014 "if (other_value.enum_value == %s) "
1015 "TTCN_error(\"Assignment of an unbound value of enumerated type %s to a "
1018 "set_selection(SPECIFIC_VALUE);\n"
1019 "single_value = other_value.enum_value;\n"
1021 "}\n\n", name
, name
, name
, unbound_value
, dispname
);
1023 def
= mputprintf(def
, "%s_template& operator=(const OPTIONAL<%s>& "
1024 "other_value);\n", name
, name
);
1025 src
= mputprintf(src
,
1026 "%s_template& %s_template::operator=(const OPTIONAL<%s>& other_value)\n"
1029 "switch (other_value.get_selection()) {\n"
1030 "case OPTIONAL_PRESENT:\n"
1031 "set_selection(SPECIFIC_VALUE);\n"
1032 "single_value = (%s)(const %s&)other_value;\n"
1034 "case OPTIONAL_OMIT:\n"
1035 "set_selection(OMIT_VALUE);\n"
1038 "TTCN_error(\"Assignment of an unbound optional field to a template of "
1039 "enumerated type %s.\");\n"
1042 "}\n\n", name
, name
, name
, enum_type
, name
, dispname
);
1044 def
= mputprintf(def
, "%s_template& operator=(const %s_template& "
1045 "other_value);\n\n", name
, name
);
1046 src
= mputprintf(src
,
1047 "%s_template& %s_template::operator=(const %s_template& other_value)\n"
1049 "if (&other_value != this) {\n"
1051 "copy_template(other_value);\n"
1054 "}\n\n", name
, name
, name
);
1056 /* match operators */
1057 def
= mputprintf(def
, "boolean match(%s other_value) const;\n", enum_type
);
1058 src
= mputprintf(src
,
1059 "boolean %s_template::match(%s other_value) "
1062 "switch (template_selection) {\n"
1063 "case SPECIFIC_VALUE:\n"
1064 "return single_value == other_value;\n"
1065 "case OMIT_VALUE:\n"
1068 "case ANY_OR_OMIT:\n"
1070 "case VALUE_LIST:\n"
1071 "case COMPLEMENTED_LIST:\n"
1072 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
1074 "if (value_list.list_value[list_count].match(other_value)) "
1075 "return template_selection == VALUE_LIST;\n"
1076 "return template_selection == COMPLEMENTED_LIST;\n"
1078 "TTCN_error(\"Matching an uninitialized/unsupported template of "
1079 "enumerated type %s.\");\n"
1082 "}\n\n", name
, enum_type
, dispname
);
1084 def
= mputprintf(def
, "boolean match(const %s& other_value) const;\n",
1086 src
= mputprintf(src
,
1087 "boolean %s_template::match(const %s& other_value) const\n"
1089 "if (other_value.enum_value == %s) "
1090 "TTCN_error(\"Matching a template of enumerated type %s with an unbound "
1092 "return match(other_value.enum_value);\n"
1093 "}\n\n", name
, name
, unbound_value
, dispname
);
1095 /* valueof operator */
1096 def
= mputprintf(def
, "%s valueof() const;\n", enum_type
);
1097 src
= mputprintf(src
,
1098 "%s %s_template::valueof() const\n"
1100 "if (template_selection != SPECIFIC_VALUE || is_ifpresent) "
1101 "TTCN_error(\"Performing a valueof or send operation on a "
1102 "non-specific template of enumerated type %s.\");\n"
1103 "return single_value;\n"
1104 "}\n\n", enum_type
, name
, dispname
);
1106 /* value list handling operators */
1109 "void set_type(template_sel template_type, unsigned int list_length);\n");
1110 src
= mputprintf(src
,
1111 "void %s_template::set_type(template_sel template_type, "
1112 "unsigned int list_length)\n"
1114 "if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST) "
1115 "TTCN_error(\"Setting an invalid list type for a template of enumerated "
1118 "set_selection(template_type);\n"
1119 "value_list.n_values = list_length;\n"
1120 "value_list.list_value = new %s_template[list_length];\n"
1121 "}\n\n", name
, dispname
, name
);
1123 def
= mputprintf(def
, "%s_template& list_item(unsigned int list_index);\n",
1125 src
= mputprintf(src
,
1126 "%s_template& %s_template::list_item(unsigned int list_index)\n"
1128 "if (template_selection != VALUE_LIST && "
1129 "template_selection != COMPLEMENTED_LIST) "
1130 "TTCN_error(\"Accessing a list element in a non-list template of "
1131 "enumerated type %s.\");\n"
1132 "if (list_index >= value_list.n_values) "
1133 "TTCN_error(\"Index overflow in a value list template of enumerated type "
1135 "return value_list.list_value[list_index];\n"
1136 "}\n\n", name
, name
, dispname
, dispname
);
1138 if (use_runtime_2
) {
1139 /** virtual stuff */
1141 "void valueofv(Base_Type* value) const;\n"
1142 "void set_value(template_sel other_value);\n"
1143 "void copy_value(const Base_Type* other_value);\n"
1144 "Base_Template* clone() const;\n"
1145 "const TTCN_Typedescriptor_t* get_descriptor() const;\n"
1146 "boolean matchv(const Base_Type* other_value) const;\n"
1147 "void log_matchv(const Base_Type* match_value) const;\n");
1148 src
= mputprintf(src
,
1149 "void %s_template::valueofv(Base_Type* value) const "
1150 "{ *(static_cast<%s*>(value)) = valueof(); }\n"
1151 "void %s_template::set_value(template_sel other_value) "
1152 "{ *this = other_value; }\n"
1153 "void %s_template::copy_value(const Base_Type* other_value) "
1154 "{ *this = *(static_cast<const %s*>(other_value)); }\n"
1155 "Base_Template* %s_template::clone() const "
1156 "{ return new %s_template(*this); }\n"
1157 "const TTCN_Typedescriptor_t* %s_template::get_descriptor() const "
1158 "{ return &%s_descr_; }\n"
1159 "boolean %s_template::matchv(const Base_Type* other_value) const "
1160 "{ return match(*(static_cast<const %s*>(other_value))); }\n"
1161 "void %s_template::log_matchv(const Base_Type* match_value) const "
1162 " { log_match(*(static_cast<const %s*>(match_value))); }\n",
1172 /* logging functions */
1173 def
= mputstr(def
, "void log() const;\n");
1176 "void %s_template::log() const\n"
1178 "switch (template_selection) {\n"
1179 "case SPECIFIC_VALUE:\n"
1180 "TTCN_Logger::log_event_enum(%s::enum_to_str(single_value), single_value);\n"
1182 "case COMPLEMENTED_LIST:\n"
1183 "TTCN_Logger::log_event_str(\"complement \");\n"
1184 "case VALUE_LIST:\n"
1185 "TTCN_Logger::log_char('(');\n"
1186 "for (unsigned int elem_count = 0; elem_count < value_list.n_values; "
1188 "if (elem_count > 0) TTCN_Logger::log_event_str(\", \");\n"
1189 "value_list.list_value[elem_count].log();\n"
1191 "TTCN_Logger::log_char(')');\n"
1196 "log_ifpresent();\n"
1197 "}\n\n", name
, name
);
1199 def
= mputprintf(def
, "void log_match(const %s& match_value) const;\n",
1201 src
= mputprintf(src
,
1202 "void %s_template::log_match(const %s& match_value) "
1205 "match_value.log();\n"
1206 "TTCN_Logger::log_event_str(\" with \");\n"
1208 "if (match(match_value)) TTCN_Logger::log_event_str(\" matched\");\n"
1209 "else TTCN_Logger::log_event_str(\" unmatched\");\n"
1210 "}\n\n", name
, name
);
1212 /* encoding/decoding functions */
1213 def
= mputstr(def
, "void encode_text(Text_Buf& text_buf) const;\n");
1214 src
= mputprintf(src
,
1215 "void %s_template::encode_text(Text_Buf& text_buf) "
1218 "encode_text_base(text_buf);\n"
1219 "switch (template_selection) {\n"
1220 "case SPECIFIC_VALUE:\n"
1221 "text_buf.push_int(single_value);\n"
1222 "case OMIT_VALUE:\n"
1224 "case ANY_OR_OMIT:\n"
1226 "case VALUE_LIST:\n"
1227 "case COMPLEMENTED_LIST:\n"
1228 "text_buf.push_int(value_list.n_values);\n"
1229 "for (unsigned int elem_count = 0; elem_count < value_list.n_values; "
1231 "value_list.list_value[elem_count].encode_text(text_buf);\n"
1234 "TTCN_error(\"Text encoder: Encoding an uninitialized/unsupported "
1235 "template of enumerated type %s.\");\n"
1237 "}\n\n", name
, dispname
);
1239 def
= mputstr(def
, "void decode_text(Text_Buf& text_buf);\n");
1240 src
= mputprintf(src
,
1241 "void %s_template::decode_text(Text_Buf& text_buf)\n"
1244 "decode_text_base(text_buf);\n"
1245 "switch (template_selection) {\n"
1246 "case SPECIFIC_VALUE:\n"
1247 "single_value = (%s)text_buf.pull_int().get_val();\n"
1248 "if (!%s::is_valid_enum(single_value)) "
1249 "TTCN_error(\"Text decoder: Unknown numeric value %%d was "
1250 "received for a template of enumerated type %s.\", single_value);\n"
1251 "case OMIT_VALUE:\n"
1253 "case ANY_OR_OMIT:\n"
1255 "case VALUE_LIST:\n"
1256 "case COMPLEMENTED_LIST:\n"
1257 "value_list.n_values = text_buf.pull_int().get_val();\n"
1258 "value_list.list_value = new %s_template[value_list.n_values];\n"
1259 "for (unsigned int elem_count = 0; elem_count < value_list.n_values; "
1261 "value_list.list_value[elem_count].decode_text(text_buf);\n"
1264 "TTCN_error(\"Text decoder: An unknown/unsupported selection was "
1265 "received for a template of enumerated type %s.\");\n"
1267 "}\n\n", name
, enum_type
, name
, dispname
, name
, dispname
);
1269 /* TTCN-3 ispresent() function */
1270 def
= mputstr(def
, "boolean is_present() const;\n");
1271 src
= mputprintf(src
,
1272 "boolean %s_template::is_present() const\n"
1274 "if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;\n"
1275 "return !match_omit();\n"
1279 def
= mputstr(def
, "boolean match_omit() const;\n");
1280 src
= mputprintf(src
,
1281 "boolean %s_template::match_omit() const\n"
1283 "if (is_ifpresent) return TRUE;\n"
1284 "switch (template_selection) {\n"
1285 "case OMIT_VALUE:\n"
1286 "case ANY_OR_OMIT:\n"
1288 "case VALUE_LIST:\n"
1289 "case COMPLEMENTED_LIST:\n"
1290 "for (unsigned int i=0; i<value_list.n_values; i++)\n"
1291 "if (value_list.list_value[i].match_omit())\n"
1292 "return template_selection==VALUE_LIST;\n"
1293 "return template_selection==COMPLEMENTED_LIST;\n"
1301 def
= mputstr(def
, "void set_param(Module_Param& param);\n");
1302 src
= mputprintf(src
,
1303 "void %s_template::set_param(Module_Param& param)\n"
1305 " param.basic_check(Module_Param::BC_TEMPLATE, \"enumerated template\");\n"
1306 " switch (param.get_type()) {\n"
1307 " case Module_Param::MP_Omit:\n"
1308 " *this = OMIT_VALUE;\n"
1310 " case Module_Param::MP_Any:\n"
1311 " *this = ANY_VALUE;\n"
1313 " case Module_Param::MP_AnyOrNone:\n"
1314 " *this = ANY_OR_OMIT;\n"
1316 " case Module_Param::MP_List_Template:\n"
1317 " case Module_Param::MP_ComplementList_Template:\n"
1318 " set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());\n"
1319 " for (size_t p_i=0; p_i<param.get_size(); p_i++) {\n"
1320 " list_item(p_i).set_param(*param.get_elem(p_i));\n"
1323 " case Module_Param::MP_Enumerated: {\n"
1324 " %s enum_val = %s::str_to_enum(param.get_enumerated());\n"
1325 " if (!%s::is_valid_enum(enum_val)) {\n"
1326 " param.error(\"Invalid enumerated value for type %s.\");\n"
1328 " *this = enum_val;\n"
1331 " param.type_error(\"enumerated template\", \"%s\");\n"
1333 " is_ifpresent = param.get_ifpresent();\n"
1334 "}\n\n", name
, enum_type
, name
, name
, dispname
, dispname
);
1336 if (!use_runtime_2
) {
1337 /* check template restriction */
1338 def
= mputstr(def
, "void check_restriction(template_res t_res, "
1339 "const char* t_name=NULL) const;\n");
1340 src
= mputprintf(src
,
1341 "void %s_template::check_restriction(template_res t_res, const char* t_name) const\n"
1343 "if (template_selection==UNINITIALIZED_TEMPLATE) return;\n"
1344 "switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {\n"
1346 "if (!is_ifpresent && template_selection==SPECIFIC_VALUE) return;\n"
1349 "if (!is_ifpresent && (template_selection==OMIT_VALUE || "
1350 "template_selection==SPECIFIC_VALUE)) return;\n"
1352 "case TR_PRESENT:\n"
1353 "if (!match_omit()) return;\n"
1358 "TTCN_error(\"Restriction `%%s' on template of type %%s violated.\", "
1359 "get_res_name(t_res), t_name ? t_name : \"%s\");\n"
1360 "}\n\n", name
, dispname
);
1364 def
= mputstr(def
, "};\n\n");
1366 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
1368 output
->source
.methods
= mputstr(output
->source
.methods
, src
);
1372 Free(unbound_value
);
This page took 0.133605 seconds and 5 git commands to generate.