Sync with 5.4.2
[deliverable/titan.core.git] / compiler2 / Type.cc
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 "../common/dbgnew.hh"
9 #include "Type.hh"
10 #include <ctype.h>
11 #include "Typestuff.hh" // FIXME CTs
12 #include "CompType.hh"
13 #include "TypeCompat.hh"
14 #include "CompField.hh"
15 #include "SigParam.hh"
16 #include "EnumItem.hh"
17
18 #include "Valuestuff.hh"
19 #include "ttcn3/ArrayDimensions.hh"
20 #include "asn1/Tag.hh"
21 #include "asn1/Block.hh"
22 #include "asn1/Ref.hh"
23 #include "Constraint.hh"
24 #include "main.hh"
25 #include "../common/pattern.hh"
26 #include "ttcn3/Attributes.hh"
27 #include "XerAttributes.hh"
28 #include "ttcn3/Ttcnstuff.hh"
29 #include "ttcn3/TtcnTemplate.hh"
30 #include "ttcn3/Templatestuff.hh"
31
32 #include "../common/static_check.h"
33 #include "PredefFunc.hh"
34
35 // implemented in coding_attrib_p.y
36 extern Ttcn::ExtensionAttributes * parse_extattributes(
37 Ttcn::WithAttribPath *w_attrib_path);
38
39 namespace Common {
40
41 using Ttcn::MultiWithAttrib;
42 using Ttcn::SingleWithAttrib;
43 using Ttcn::WithAttribPath;
44
45 const char* Type::type_as_string[] = {
46 "undefined", // T_UNDEF
47 "erroneous", // T_ERROR
48 "null(ASN)", // T_NULL
49 "boolean", // T_BOOL
50 "integer", // T_INT
51 "integer(ASN.1)", // T_INT_A
52 "real/float", // T_REAL
53 "enumerated(ASN.1)", // T_ENUM_A
54 "enumerated(TTCN-3)", // T_ENUM_T
55 "bitstring", // T_BSTR
56 "bitstring(ASN)", // T_BSTR_A
57 "hexstring(TTCN-3)", // T_HSTR
58 "octetstring", // T_OSTR
59 "charstring (TTCN-3)", // T_CSTR
60 "universal charstring(TTCN-3)", // T_USTR
61 "UTF8String(ASN.1)", // T_UTF8STRING
62 "NumericString(ASN.1)", // T_NUMERICSTRING
63 "PrintableString(ASN.1)", // T_PRINTABLESTRING
64 "TeletexString(ASN.1)", //T_TELETEXSTRING
65 "VideotexString(ASN.1)", // T_VIDEOTEXSTRING
66 "IA5String(ASN.1)", // T_IA5STRING
67 "GraphicString(ASN.1)", // T_GRAPHICSTRING,
68 "VisibleString(ASN.1)", // T_VISIBLESTRING
69 "GeneralString (ASN.1)", // T_GENERALSTRING
70 "UniversalString (ASN.1)", // T_UNIVERSALSTRING
71 "BMPString (ASN.1)", // T_BMPSTRING
72 "UnrestrictedCharacterString(ASN.1)", // T_UNRESTRICTEDSTRING
73 "UTCTime(ASN.1)", // T_UTCTIME
74 "GeneralizedTime(ASN.1)", // T_GENERALIZEDTIME
75 "Object descriptor, a kind of string (ASN.1)", // T_OBJECTDESCRIPTOR
76 "object identifier", // T_OID
77 "relative OID(ASN.1)", // T_ROID
78 "choice(ASN-1)", // T_CHOICE_A
79 "union(TTCN-3)", // T_CHOICE_T
80 "sequence (record) of", // T_SEQOF
81 "set of", // T_SETOF
82 "sequence(ASN-1)", // T_SEQ_A
83 "record(TTCN-3)", // T_SEQ_T
84 "set(ASN.1)", // T_SET_A
85 "set(TTCN-3)", // T_SET_T
86 "ObjectClassFieldType(ASN.1)", // T_OCFT
87 "open type(ASN.1)", // T_OPENTYPE
88 "ANY(deprecated ASN.1)", // T_ANY
89 "external(ASN.1)", // T_EXTERNAL
90 "embedded PDV(ASN.1)", // T_EMBEDDED_PDV
91 "referenced", // T_REFD
92 "special referenced(by pointer, not by name)", // T_REFDSPEC
93 "selection type(ASN.1)", // T_SELTYPE
94 "verdict type(TTCN-3)", // T_VERDICT
95 "port type(TTCN-3)", // T_PORT
96 "component type(TTCN-3)", // T_COMPONENT
97 "address type(TTCN-3)", // T_ADDRESS
98 "default type (TTCN-3)", // T_DEFAULT
99 "array(TTCN-3)", // T_ARRAY
100 "signature(TTCN-3)", // T_SIGNATURE
101 "function reference(TTCN-3)", // T_FUNCTION
102 "altstep reference(TTCN-3)", // T_ALTSTEP
103 "testcase reference(TTCN-3)", // T_TESTCASE
104 "anytype(TTCN-3)", // T_ANYTYPE
105 };
106
107 // =================================
108 // ===== Type
109 // =================================
110 const char* Type::asString() const {
111 if (this->get_typetype() < Type::T_LAST && Type::T_UNDEF < this->get_typetype()) {
112 return type_as_string[this->get_typetype()];
113 }
114 else {
115 return type_as_string[Type::T_UNDEF];
116 }
117 }
118
119 const char* Type::asString(Type::typetype_t type) {
120 if (type < Type::T_LAST && Type::T_UNDEF < type) {
121 return type_as_string[type];
122 }
123 else {
124 return type_as_string[Type::T_UNDEF];
125 }
126 }
127
128 // Used by dump() for user-readable messages, by Def_ExtFunction::generate_*
129 // The text returned must match the case label without the "CT_" !
130 const char *Type::get_encoding_name(MessageEncodingType_t encoding_type)
131 {
132 ENSURE_EQUAL(Type::T_UNDEF, 0);
133 ENSURE_EQUAL(Type::OT_UNKNOWN, 0);
134 switch (encoding_type) {
135 case CT_BER:
136 return "BER";
137 case CT_PER:
138 return "PER";
139 case CT_XER:
140 return "XER";
141 case CT_RAW:
142 return "RAW";
143 case CT_TEXT:
144 return "TEXT";
145 case CT_JSON:
146 return "JSON";
147 case CT_CUSTOM:
148 return "custom";
149 default:
150 return "<unknown encoding>";
151 }
152 }
153
154 Type *Type::get_stream_type(MessageEncodingType_t encoding_type, int stream_variant)
155 {
156 switch (encoding_type) {
157 case CT_BER:
158 case CT_PER:
159 case CT_RAW:
160 case CT_XER: // UTF-8 doesn't fit into charstring and universal is wasteful
161 case CT_JSON:
162 return get_pooltype(T_OSTR);
163 case CT_TEXT:
164 if(stream_variant==0){
165 return get_pooltype(T_CSTR);
166 } else {
167 return get_pooltype(T_OSTR);
168 }
169 case CT_CUSTOM:
170 return get_pooltype(T_BSTR);
171 default:
172 FATAL_ERROR("Type::get_stream_type()");
173 return 0;
174 }
175 }
176
177 map<Type::typetype_t, Type> *Type::pooltypes = 0;
178
179 Type* Type::get_pooltype(typetype_t p_typetype)
180 {
181 p_typetype=get_typetype_ttcn3(p_typetype);
182 switch(p_typetype) {
183 case T_NULL:
184 case T_BOOL:
185 case T_INT:
186 case T_REAL:
187 case T_BSTR:
188 case T_HSTR:
189 case T_OSTR:
190 case T_CSTR:
191 case T_USTR:
192 case T_OID:
193 case T_ERROR:
194 case T_VERDICT:
195 case T_COMPONENT:
196 case T_DEFAULT:
197 break; // we have a pool type
198 default:
199 return 0; // no pool type for you!
200 } // switch
201 if (!pooltypes) pooltypes = new map<typetype_t, Type>; // lazy init
202 else if (pooltypes->has_key(p_typetype)) return (*pooltypes)[p_typetype];
203 Type *t;
204 if (p_typetype == T_COMPONENT)
205 t = new Type(T_COMPONENT, new ComponentTypeBody());
206 else t = new Type(p_typetype);
207 t->ownertype = OT_POOL;
208 pooltypes->add(p_typetype, t);
209 return t;
210 }
211
212 void Type::destroy_pooltypes()
213 {
214 if(pooltypes) {
215 for(size_t i=0; i<pooltypes->size(); i++)
216 delete pooltypes->get_nth_elem(i);
217 pooltypes->clear();
218 delete pooltypes;
219 pooltypes=0;
220 }
221 }
222
223 Tag *Type::get_default_tag()
224 {
225 typetype_t t_typetype;
226 switch (typetype) {
227 case T_INT:
228 t_typetype = T_INT_A;
229 break;
230 case T_BSTR:
231 t_typetype = T_BSTR_A;
232 break;
233 case T_ENUM_T:
234 t_typetype = T_ENUM_A;
235 break;
236 case T_SEQ_T:
237 case T_SEQOF:
238 t_typetype = T_SEQ_A;
239 break;
240 case T_SET_T:
241 case T_SETOF:
242 t_typetype = T_SET_A;
243 break;
244 case T_OPENTYPE:
245 t_typetype = T_ANY;
246 break;
247 case T_REFD:
248 case T_REFDSPEC:
249 case T_SELTYPE:
250 case T_OCFT:
251 return get_type_refd()->get_tag();
252 default:
253 t_typetype = typetype;
254 break;
255 }
256 if (!default_tags) default_tags = new map<typetype_t, Tag>;
257 else if (default_tags->has_key(t_typetype))
258 return (*default_tags)[t_typetype];
259 Tag *tag;
260 switch (t_typetype) {
261 case T_ANY:
262 tag = new Tag(Tag::TAG_EXPLICIT, Tag::TAG_ALL, (Int)0);
263 break;
264 case T_ERROR:
265 tag = new Tag(Tag::TAG_EXPLICIT, Tag::TAG_ERROR, (Int)0);
266 break;
267 default: {
268 int tagnumber = get_default_tagnumber(t_typetype);
269 if (tagnumber < 0) FATAL_ERROR ("Type::get_default_tag():type `%s' "
270 "does not have default tag", get_typename().c_str());
271 tag = new Tag(Tag::TAG_EXPLICIT, Tag::TAG_UNIVERSAL, Int(tagnumber));
272 break; }
273 }
274 default_tags->add(t_typetype, tag);
275 return tag;
276 }
277
278 int Type::get_default_tagnumber(typetype_t p_tt)
279 {
280 switch (p_tt) {
281 // note: tag number 0 is reserved for internal use
282 case T_BOOL:
283 return 1;
284 case T_INT_A:
285 return 2;
286 case T_BSTR_A:
287 return 3;
288 case T_OSTR:
289 return 4;
290 case T_NULL:
291 return 5;
292 case T_OID:
293 return 6;
294 case T_OBJECTDESCRIPTOR:
295 return 7;
296 case T_EXTERNAL:
297 return 8;
298 case T_REAL:
299 return 9;
300 case T_ENUM_A:
301 return 10;
302 case T_EMBEDDED_PDV:
303 return 11;
304 case T_UTF8STRING:
305 return 12;
306 case T_ROID:
307 return 13;
308 // note: tag numbers 14 and 15 are reserved for future use
309 case T_SEQ_A:
310 return 16;
311 case T_SET_A:
312 return 17;
313 case T_NUMERICSTRING:
314 return 18;
315 case T_PRINTABLESTRING:
316 return 19;
317 case T_TELETEXSTRING:
318 return 20;
319 case T_VIDEOTEXSTRING:
320 return 21;
321 case T_IA5STRING:
322 return 22;
323 case T_UTCTIME:
324 return 23;
325 case T_GENERALIZEDTIME:
326 return 24;
327 case T_GRAPHICSTRING:
328 return 25;
329 case T_VISIBLESTRING:
330 return 26;
331 case T_GENERALSTRING:
332 return 27;
333 case T_UNIVERSALSTRING:
334 return 28;
335 case T_UNRESTRICTEDSTRING:
336 return 29;
337 case T_BMPSTRING:
338 return 30;
339 default:
340 return -1;
341 }
342 }
343
344 map<Type::typetype_t, Tag> *Type::default_tags = 0;
345
346 void Type::destroy_default_tags()
347 {
348 if (default_tags) {
349 size_t nof_tags = default_tags->size();
350 for (size_t i = 0; i < nof_tags; i++)
351 delete default_tags->get_nth_elem(i);
352 default_tags->clear();
353 delete default_tags;
354 default_tags = 0;
355 }
356 }
357
358 Type::Type(const Type& p)
359 : Governor(p), typetype(p.typetype)
360 {
361 init();
362 if (p.w_attrib_path != NULL) FATAL_ERROR("Type::Type()");
363 tags=p.tags?p.tags->clone():0;
364 if(p.constraints) {
365 constraints=p.constraints->clone();
366 constraints->set_my_type(this);
367 }
368 else constraints=0;
369 if(p.parsed_restr!=NULL) {
370 parsed_restr=new vector<SubTypeParse>;
371 for(size_t i=0;i<p.parsed_restr->size();i++) {
372 SubTypeParse *stp = 0;
373 switch((*p.parsed_restr)[i]->get_selection()) {
374 case SubTypeParse::STP_SINGLE:
375 stp=new SubTypeParse((*p.parsed_restr)[i]->Single());
376 break;
377 case SubTypeParse::STP_RANGE:
378 stp=new SubTypeParse((*p.parsed_restr)[i]->Min(),
379 (*p.parsed_restr)[i]->MinExclusive(),
380 (*p.parsed_restr)[i]->Max(),
381 (*p.parsed_restr)[i]->MaxExclusive());
382 break;
383 case SubTypeParse::STP_LENGTH:
384 FATAL_ERROR("Type::Type(Type&): STP_LENGTH");
385 break;
386 default: FATAL_ERROR("Type::Type()");
387 }
388 parsed_restr->add(stp);
389 }
390 }
391 else parsed_restr=0;
392 switch(typetype) {
393 case T_ERROR:
394 case T_NULL:
395 case T_BOOL:
396 case T_INT:
397 case T_REAL:
398 case T_BSTR:
399 case T_HSTR:
400 case T_OSTR:
401 case T_CSTR:
402 case T_USTR:
403 case T_UTF8STRING:
404 case T_NUMERICSTRING:
405 case T_PRINTABLESTRING:
406 case T_TELETEXSTRING:
407 case T_VIDEOTEXSTRING:
408 case T_IA5STRING:
409 case T_GRAPHICSTRING:
410 case T_VISIBLESTRING:
411 case T_GENERALSTRING:
412 case T_UNIVERSALSTRING:
413 case T_BMPSTRING:
414 case T_UTCTIME:
415 case T_GENERALIZEDTIME:
416 case T_OBJECTDESCRIPTOR:
417 case T_OID:
418 case T_ROID:
419 case T_ANY:
420 case T_EXTERNAL:
421 case T_EMBEDDED_PDV:
422 case T_UNRESTRICTEDSTRING:
423 case T_VERDICT:
424 case T_DEFAULT:
425 break;
426 case T_INT_A:
427 case T_BSTR_A:
428 u.namednums.block=p.u.namednums.block?p.u.namednums.block->clone():0;
429 u.namednums.nvs=p.u.namednums.nvs?p.u.namednums.nvs->clone():0;
430 break;
431 case T_ENUM_A:
432 u.enums.block=p.u.enums.block?p.u.enums.block->clone():0;
433 u.enums.eis1=p.u.enums.eis1?p.u.enums.eis1->clone():0;
434 u.enums.ellipsis=p.u.enums.ellipsis;
435 u.enums.excSpec=p.u.enums.excSpec?p.u.enums.excSpec->clone():0;
436 u.enums.eis2=p.u.enums.eis2?p.u.enums.eis2->clone():0;
437 // no break
438 case T_ENUM_T:
439 u.enums.eis=p.u.enums.eis->clone();
440 u.enums.eis_by_name=0;
441 break;
442 case T_CHOICE_T:
443 case T_SEQ_T:
444 case T_SET_T:
445 case T_ANYTYPE:
446 u.secho.cfm=p.u.secho.cfm->clone();
447 u.secho.field_by_name = 0;
448 u.secho.component_internal = false;
449 u.secho.has_single_charenc = false;
450 break;
451 case T_SEQ_A:
452 case T_SET_A:
453 u.secho.tr_compsof_ready=p.u.secho.tr_compsof_ready;
454 // no break
455 case T_CHOICE_A:
456 u.secho.cfm = 0;
457 u.secho.block=p.u.secho.block?p.u.secho.block->clone():0;
458 u.secho.ctss=p.u.secho.ctss?p.u.secho.ctss->clone():0;
459 u.secho.field_by_name = 0;
460 u.secho.component_internal = false;
461 u.secho.has_single_charenc = false;
462 break;
463 case T_SEQOF:
464 case T_SETOF:
465 u.seof.ofType=p.u.seof.ofType->clone();
466 u.seof.component_internal = false;
467 break;
468 case T_REFD:
469 u.ref.ref=p.u.ref.ref->clone();
470 u.ref.type_refd=0;
471 u.ref.component_internal = false;
472 break;
473 case T_OCFT:
474 u.ref.oc_defn=p.u.ref.oc_defn;
475 u.ref.oc_fieldname=p.u.ref.oc_fieldname;
476 // no break
477 case T_REFDSPEC:
478 u.ref.type_refd=p.u.ref.type_refd;
479 u.ref.component_internal = false;
480 break;
481 case T_SELTYPE:
482 u.seltype.id=p.u.seltype.id->clone();
483 u.seltype.type=p.u.seltype.type->clone();
484 u.seltype.type_refd=0;
485 break;
486 case T_OPENTYPE:
487 u.secho.cfm=new CompFieldMap();
488 u.secho.cfm->set_my_type(this);
489 u.secho.oc_defn=p.u.secho.oc_defn;
490 u.secho.oc_fieldname=p.u.secho.oc_fieldname;
491 u.secho.my_tableconstraint=0;
492 u.secho.field_by_name = 0;
493 u.secho.component_internal = false;
494 u.secho.has_single_charenc = false;
495 break;
496 case T_ARRAY:
497 u.array.element_type=p.u.array.element_type->clone();
498 u.array.dimension = p.u.array.dimension->clone();
499 u.array.in_typedef = p.u.array.in_typedef;
500 u.array.component_internal = false;
501 break;
502 case T_PORT:
503 u.port = p.u.port->clone();
504 break;
505 case T_COMPONENT:
506 u.component = p.u.component->clone();
507 break;
508 case T_ADDRESS:
509 u.address = 0;
510 break;
511 case T_SIGNATURE:
512 u.signature.parameters = p.u.signature.parameters ?
513 p.u.signature.parameters->clone() : 0;
514 u.signature.return_type = p.u.signature.return_type ?
515 p.u.signature.return_type->clone() : 0;
516 u.signature.no_block = p.u.signature.no_block;
517 u.signature.exceptions = p.u.signature.exceptions ?
518 p.u.signature.exceptions->clone() : 0;
519 u.signature.component_internal = false;
520 break;
521 case T_FUNCTION:
522 case T_ALTSTEP:
523 u.fatref.fp_list = p.u.fatref.fp_list->clone();
524 u.fatref.runs_on.ref = p.u.fatref.runs_on.ref ?
525 p.u.fatref.runs_on.ref->clone() : 0;
526 u.fatref.runs_on.self = p.u.fatref.runs_on.self;
527 u.fatref.runs_on.type = 0;
528 u.fatref.return_type = p.u.fatref.return_type ?
529 p.u.fatref.return_type->clone() : 0;
530 u.fatref.is_startable = false;
531 u.fatref.returns_template = p.u.fatref.returns_template;
532 u.fatref.template_restriction = p.u.fatref.template_restriction;
533 break;
534 case T_TESTCASE:
535 u.fatref.fp_list = p.u.fatref.fp_list->clone();
536 u.fatref.runs_on.ref = p.u.fatref.runs_on.ref ?
537 p.u.fatref.runs_on.ref->clone() : 0;
538 u.fatref.runs_on.self = false;
539 u.fatref.runs_on.type = 0;
540 u.fatref.system.ref = p.u.fatref.system.ref ?
541 p.u.fatref.system.ref->clone() : 0;
542 u.fatref.system.type = 0;
543 u.fatref.is_startable = false;
544 u.fatref.returns_template = false;
545 u.fatref.template_restriction = TR_NONE;
546 break;
547 default:
548 FATAL_ERROR("Type::Type()");
549 } // switch
550 }
551
552 void Type::init()
553 {
554 tags_checked = false;
555 tbl_cons_checked = false;
556 text_checked = false;
557 json_checked = false;
558 raw_parsed = false;
559 raw_checked = false;
560 xer_checked = false;
561 raw_length_calculated = false;
562 has_opentypes = false;
563 opentype_outermost = false;
564 code_generated = false;
565 embed_values_possible = false;
566 use_nil_possible = false;
567 use_order_possible = false;
568 raw_length = -1;
569 parent_type = 0;
570 tags = 0;
571 constraints = 0;
572 w_attrib_path = 0;
573 encode_attrib_path = 0;
574 rawattrib = 0;
575 textattrib = 0;
576 xerattrib = 0;
577 berattrib = 0;
578 jsonattrib = 0;
579 sub_type = 0;
580 parsed_restr = 0;
581 ownertype = OT_UNKNOWN;
582 owner = 0;
583 chk_finished = false;
584 pard_type_instance = false;
585 }
586
587 void Type::clean_up()
588 {
589 switch (typetype) {
590 case T_ERROR:
591 case T_NULL:
592 case T_BOOL:
593 case T_INT:
594 case T_REAL:
595 case T_BSTR:
596 case T_HSTR:
597 case T_OSTR:
598 case T_CSTR:
599 case T_USTR:
600 case T_UTF8STRING:
601 case T_NUMERICSTRING:
602 case T_PRINTABLESTRING:
603 case T_TELETEXSTRING:
604 case T_VIDEOTEXSTRING:
605 case T_IA5STRING:
606 case T_GRAPHICSTRING:
607 case T_VISIBLESTRING:
608 case T_GENERALSTRING:
609 case T_UNIVERSALSTRING:
610 case T_BMPSTRING:
611 case T_UTCTIME:
612 case T_GENERALIZEDTIME:
613 case T_OBJECTDESCRIPTOR:
614 case T_OID:
615 case T_ROID:
616 case T_ANY:
617 case T_EXTERNAL:
618 case T_EMBEDDED_PDV:
619 case T_UNRESTRICTEDSTRING:
620 case T_REFDSPEC:
621 case T_OCFT:
622 case T_VERDICT:
623 case T_ADDRESS:
624 case T_DEFAULT:
625 break;
626 case T_INT_A:
627 case T_BSTR_A:
628 delete u.namednums.block;
629 delete u.namednums.nvs;
630 break;
631 case T_ENUM_A:
632 delete u.enums.block;
633 if(u.enums.eis1) {
634 u.enums.eis1->release_eis();
635 delete u.enums.eis1;
636 }
637 if(u.enums.eis2) {
638 u.enums.eis2->release_eis();
639 delete u.enums.eis2;
640 }
641 /* no break */
642 case T_ENUM_T:
643 delete u.enums.eis;
644 if (u.enums.eis_by_name) {
645 for (size_t a = 0; a < u.enums.eis_by_name->size(); a++) {
646 delete u.enums.eis_by_name->get_nth_elem(a);
647 }
648 u.enums.eis_by_name->clear();
649 delete u.enums.eis_by_name;
650 }
651 break;
652 case T_CHOICE_A:
653 case T_SEQ_A:
654 case T_SET_A:
655 delete u.secho.block;
656 delete u.secho.ctss;
657 /* no break */
658 case T_ANYTYPE:
659 case T_CHOICE_T:
660 case T_SEQ_T:
661 case T_SET_T:
662 case T_OPENTYPE:
663 delete u.secho.cfm;
664 if (u.secho.field_by_name) {
665 for(size_t a = 0; a < u.secho.field_by_name->size(); a++) {
666 delete u.secho.field_by_name->get_nth_elem(a);
667 }
668 u.secho.field_by_name->clear();
669 delete u.secho.field_by_name;
670 }
671 break;
672 case T_SEQOF:
673 case T_SETOF:
674 delete u.seof.ofType;
675 break;
676 case T_REFD:
677 delete u.ref.ref;
678 break;
679 case T_SELTYPE:
680 delete u.seltype.id;
681 delete u.seltype.type;
682 break;
683 case T_ARRAY:
684 delete u.array.element_type;
685 delete u.array.dimension;
686 break;
687 case T_PORT:
688 delete u.port;
689 break;
690 case T_COMPONENT:
691 delete u.component;
692 break;
693 case T_SIGNATURE:
694 delete u.signature.parameters;
695 delete u.signature.return_type;
696 delete u.signature.exceptions;
697 break;
698 case T_FUNCTION:
699 case T_ALTSTEP:
700 delete u.fatref.fp_list;
701 delete u.fatref.runs_on.ref;
702 delete u.fatref.return_type;
703 break;
704 case T_TESTCASE:
705 delete u.fatref.fp_list;
706 delete u.fatref.runs_on.ref;
707 delete u.fatref.system.ref;
708 break;
709 default:
710 FATAL_ERROR("Type::clean_up()");
711 } // switch
712 typetype = T_ERROR;
713 delete tags;
714 tags = 0;
715 delete constraints;
716 constraints = 0;
717 delete rawattrib;
718 rawattrib = 0;
719 delete textattrib;
720 textattrib = 0;
721 delete xerattrib;
722 xerattrib = 0;
723 delete sub_type;
724 sub_type = 0;
725 delete berattrib;
726 berattrib = 0;
727 delete jsonattrib;
728 jsonattrib = 0;
729 if (parsed_restr) {
730 for (size_t i = 0; i < parsed_restr->size(); i++)
731 delete (*parsed_restr)[i];
732 parsed_restr->clear();
733 delete parsed_restr;
734 parsed_restr = 0;
735 }
736 delete w_attrib_path;
737 w_attrib_path = 0;
738 delete encode_attrib_path;
739 encode_attrib_path = 0;
740 }
741
742 Type::Type(typetype_t p_tt)
743 : Governor(S_T), typetype(p_tt)
744 {
745 init();
746 switch(p_tt) {
747 case T_ERROR:
748 case T_NULL:
749 case T_BOOL:
750 case T_INT:
751 case T_REAL:
752 case T_BSTR:
753 case T_HSTR:
754 case T_OSTR:
755 case T_CSTR:
756 case T_USTR:
757 case T_UTF8STRING:
758 case T_NUMERICSTRING:
759 case T_PRINTABLESTRING:
760 case T_TELETEXSTRING:
761 case T_VIDEOTEXSTRING:
762 case T_IA5STRING:
763 case T_GRAPHICSTRING:
764 case T_VISIBLESTRING:
765 case T_GENERALSTRING:
766 case T_UNIVERSALSTRING:
767 case T_BMPSTRING:
768 case T_UTCTIME:
769 case T_GENERALIZEDTIME:
770 case T_OBJECTDESCRIPTOR:
771 case T_OID:
772 case T_ROID:
773 case T_ANY:
774 case T_EXTERNAL:
775 case T_EMBEDDED_PDV:
776 case T_UNRESTRICTEDSTRING:
777 case T_VERDICT:
778 case T_DEFAULT:
779 break;
780 case T_ANYTYPE: {
781 u.secho.cfm = new CompFieldMap;
782 u.secho.cfm->set_my_type(this);
783 u.secho.block=0;
784 u.secho.ctss=0;
785 u.secho.field_by_name = 0;
786 u.secho.component_internal = false;
787 u.secho.has_single_charenc = false;
788 break; }
789 case T_INT_A:
790 case T_BSTR_A:
791 u.namednums.block=0;
792 u.namednums.nvs=0;
793 break;
794 case T_ADDRESS:
795 u.address = 0;
796 break;
797 default:
798 FATAL_ERROR("Type::Type()");
799 } // switch
800 }
801
802 Type::Type(typetype_t p_tt, EnumItems *p_eis)
803 : Governor(S_T), typetype(p_tt)
804 {
805 if (p_tt != T_ENUM_T || !p_eis) FATAL_ERROR("Type::Type()");
806 init();
807 u.enums.eis=p_eis;
808 u.enums.eis_by_name=0;
809 }
810
811 Type::Type(typetype_t p_tt, Block *p_block)
812 : Governor(S_T), typetype(p_tt)
813 {
814 if (!p_block) FATAL_ERROR("NULL parameter");
815 init();
816 switch(p_tt) {
817 case T_INT_A:
818 case T_BSTR_A:
819 u.namednums.block=p_block;
820 u.namednums.nvs=0;
821 break;
822 case T_ENUM_A:
823 u.enums.eis=new EnumItems();
824 u.enums.block=p_block;
825 u.enums.eis1=0;
826 u.enums.ellipsis=false;
827 u.enums.excSpec=0;
828 u.enums.eis2=0;
829 u.enums.eis_by_name=0;
830 break;
831 case T_SEQ_A:
832 case T_SET_A:
833 u.secho.tr_compsof_ready=false;
834 // no break
835 case T_CHOICE_A:
836 u.secho.cfm = 0;
837 u.secho.block=p_block;
838 u.secho.ctss=0;
839 u.secho.field_by_name = 0;
840 u.secho.component_internal = false;
841 u.secho.has_single_charenc = false;
842 break;
843 default:
844 FATAL_ERROR("Type::Type()");
845 } // switch
846 }
847
848 Type::Type(typetype_t p_tt,
849 EnumItems *p_eis1, bool p_ellipsis, EnumItems *p_eis2)
850 : Governor(S_T), typetype(p_tt)
851 {
852 if (p_tt != T_ENUM_A || !p_eis1) FATAL_ERROR("Type::Type()");
853 init();
854 u.enums.eis=new EnumItems();
855 u.enums.block=0;
856 u.enums.eis1=p_eis1;
857 u.enums.ellipsis=p_ellipsis;
858 u.enums.eis2=p_eis2;
859 u.enums.eis_by_name=0;
860 }
861
862 Type::Type(typetype_t p_tt, CompFieldMap *p_cfm)
863 : Governor(S_T), typetype(p_tt)
864 {
865 if (!p_cfm) FATAL_ERROR("NULL parameter");
866 init();
867 switch (p_tt) {
868 case T_CHOICE_T:
869 case T_SEQ_T:
870 case T_SET_T:
871 u.secho.cfm=p_cfm;
872 u.secho.field_by_name = 0;
873 u.secho.component_internal = false;
874 u.secho.has_single_charenc = false;
875 break;
876 default:
877 FATAL_ERROR("Type::Type()");
878 } // switch
879 }
880
881 Type::Type(typetype_t p_tt, Type *p_type)
882 : Governor(S_T), typetype(p_tt)
883 {
884 if (!p_type) FATAL_ERROR("NULL parameter");
885 init();
886 switch (p_tt) {
887 case T_SEQOF:
888 case T_SETOF:
889 u.seof.ofType=p_type;
890 u.seof.ofType->set_ownertype(OT_RECORD_OF, this);
891 u.seof.component_internal = false;
892 break;
893 case T_REFDSPEC:
894 u.ref.type_refd=p_type;
895 u.ref.type_refd->set_ownertype(OT_REF_SPEC, this);
896 u.ref.component_internal = false;
897 break;
898 default:
899 FATAL_ERROR("Type::Type()");
900 } // switch
901 }
902
903 Type::Type(typetype_t p_tt, Identifier *p_id, Type *p_type)
904 : Governor(S_T), typetype(p_tt)
905 {
906 if (p_tt != T_SELTYPE || !p_id || !p_type) FATAL_ERROR("Type::Type()");
907 init();
908 u.seltype.id=p_id;
909 u.seltype.type=p_type;
910 u.seltype.type->set_ownertype(OT_SELTYPE, this);
911 u.seltype.type_refd=0;
912 }
913
914 Type::Type(typetype_t p_tt, Type *p_type, Ttcn::ArrayDimension *p_dim,
915 bool p_in_typedef)
916 : Governor(S_T), typetype(p_tt)
917 {
918 if (p_tt != T_ARRAY || !p_type || !p_dim) FATAL_ERROR("Type::Type()");
919 init();
920 u.array.element_type = p_type;
921 u.array.element_type->set_ownertype(OT_ARRAY, this);
922 u.array.dimension = p_dim;
923 u.array.in_typedef = p_in_typedef;
924 u.array.component_internal = false;
925 }
926
927 Type::Type(typetype_t p_tt, Type *p_type, OC_defn *p_oc_defn,
928 const Identifier *p_id)
929 : Governor(S_T), typetype(p_tt)
930 {
931 if (p_tt != T_OCFT || !p_type ||!p_oc_defn || !p_id)
932 FATAL_ERROR("Type::Type()");
933 init();
934 u.ref.type_refd=p_type;
935 u.ref.type_refd->set_ownertype(OT_OCFT, this);
936 u.ref.oc_defn=p_oc_defn;
937 u.ref.oc_fieldname=p_id;
938 u.ref.component_internal = false;
939 }
940
941 Type::Type(typetype_t p_tt, OC_defn *p_oc_defn,
942 const Identifier *p_id)
943 : Governor(S_T), typetype(p_tt)
944 {
945 if (p_tt != T_OPENTYPE || !p_oc_defn || !p_id) FATAL_ERROR("Type::Type()");
946 init();
947 has_opentypes=true;
948 u.secho.cfm=new CompFieldMap();
949 u.secho.cfm->set_my_type(this);
950 u.secho.oc_defn=p_oc_defn;
951 u.secho.oc_fieldname=p_id;
952 u.secho.my_tableconstraint=0;
953 u.secho.field_by_name = 0;
954 u.secho.component_internal = false;
955 u.secho.has_single_charenc = false;
956 }
957
958 Type::Type(typetype_t p_tt, Reference *p_ref)
959 : Governor(S_T), typetype(p_tt)
960 {
961 if (p_tt != T_REFD || !p_ref) FATAL_ERROR("Type::Type()");
962 init();
963 u.ref.ref=p_ref;
964 u.ref.type_refd=0;
965 u.ref.component_internal = false;
966 }
967
968 Type::Type(typetype_t p_tt, Ttcn::PortTypeBody *p_pb)
969 : Governor(S_T), typetype(p_tt)
970 {
971 if (p_tt != T_PORT || !p_pb) FATAL_ERROR("Type::Type()");
972 init();
973 u.port = p_pb;
974 p_pb->set_my_type(this);
975 }
976
977 Type::Type(typetype_t p_tt, ComponentTypeBody *p_cb)
978 : Governor(S_T), typetype(p_tt)
979 {
980 if (p_tt != T_COMPONENT || !p_cb) FATAL_ERROR("Type::Type()");
981 init();
982 u.component = p_cb;
983 p_cb->set_my_type(this);
984 }
985
986 Type::Type(typetype_t p_tt, SignatureParamList *p_params, Type *p_returntype,
987 bool p_noblock, SignatureExceptions *p_exceptions)
988 : Governor(S_T), typetype(p_tt)
989 {
990 if (p_tt != T_SIGNATURE || (p_returntype && p_noblock))
991 FATAL_ERROR("Type::Type()");
992 init();
993 u.signature.parameters = p_params;
994 if ((u.signature.return_type = p_returntype)) { // check assignment for 0
995 u.signature.return_type->set_ownertype(OT_SIGNATURE, this);
996 }
997 u.signature.no_block = p_noblock;
998 u.signature.exceptions = p_exceptions;
999 u.signature.component_internal = false;
1000 }
1001
1002 Type::Type(typetype_t p_tt,Ttcn::FormalParList *p_params,
1003 Ttcn::Reference* p_runs_on_ref, bool p_runs_on_self,
1004 Type *p_returntype, bool p_returns_template,
1005 template_restriction_t p_template_restriction)
1006 : Governor(S_T), typetype(p_tt)
1007 {
1008 if (p_tt != T_FUNCTION || !p_params || (!p_returntype && p_returns_template)
1009 || (p_runs_on_ref && p_runs_on_self)) FATAL_ERROR("Type::Type()");
1010 init();
1011 u.fatref.fp_list = p_params;
1012 u.fatref.runs_on.ref = p_runs_on_ref;
1013 u.fatref.runs_on.self = p_runs_on_self;
1014 u.fatref.runs_on.type = 0;
1015 if ((u.fatref.return_type = p_returntype)) { // check assignment for 0
1016 u.fatref.return_type->set_ownertype(OT_FUNCTION, this);
1017 }
1018 u.fatref.is_startable = false;
1019 u.fatref.returns_template = p_returns_template;
1020 u.fatref.template_restriction = p_template_restriction;
1021 }
1022
1023 Type::Type(typetype_t p_tt,Ttcn::FormalParList *p_params,
1024 Ttcn::Reference* p_runs_on_ref, bool p_runs_on_self)
1025 : Governor(S_T), typetype(p_tt)
1026 {
1027 if(p_tt != T_ALTSTEP || !p_params || (p_runs_on_ref && p_runs_on_self))
1028 FATAL_ERROR("Type::Type()");
1029 init();
1030 u.fatref.fp_list = p_params;
1031 u.fatref.runs_on.ref = p_runs_on_ref;
1032 u.fatref.runs_on.self = p_runs_on_self;
1033 u.fatref.runs_on.type = 0;
1034 u.fatref.return_type = 0;
1035 u.fatref.is_startable = false;
1036 u.fatref.returns_template = false;
1037 u.fatref.template_restriction = TR_NONE;
1038 }
1039
1040 Type::Type(typetype_t p_tt,Ttcn::FormalParList *p_params,
1041 Ttcn::Reference* p_runs_on_ref, Ttcn::Reference *p_system_ref)
1042 : Governor(S_T), typetype(p_tt)
1043 {
1044 if(p_tt != T_TESTCASE || !p_params || !p_runs_on_ref)
1045 FATAL_ERROR("Type::Type()");
1046 init();
1047 u.fatref.fp_list = p_params;
1048 u.fatref.runs_on.ref = p_runs_on_ref;
1049 u.fatref.runs_on.self = false;
1050 u.fatref.runs_on.type = 0;
1051 u.fatref.system.ref = p_system_ref;
1052 u.fatref.system.type = 0;
1053 u.fatref.is_startable = false;
1054 u.fatref.returns_template = false;
1055 u.fatref.template_restriction = TR_NONE;
1056 }
1057
1058 Type::~Type()
1059 {
1060 clean_up();
1061 }
1062
1063 void Type::free_pools()
1064 {
1065 destroy_default_tags();// Additionally: R&S license warning
1066 destroy_pooltypes();// Additionally: R&S license checkin/disconnect/shutdown
1067 }
1068
1069 Type *Type::clone() const
1070 {
1071 return new Type(*this);
1072 }
1073
1074 Type::typetype_t Type::get_typetype_ttcn3(typetype_t p_tt)
1075 {
1076 switch (p_tt) {
1077 case T_INT_A:
1078 return T_INT;
1079 case T_ENUM_A:
1080 return T_ENUM_T;
1081 case T_BSTR_A:
1082 return T_BSTR;
1083 case T_UTF8STRING:
1084 case T_BMPSTRING:
1085 case T_UNIVERSALSTRING:
1086 return T_USTR;
1087 case T_TELETEXSTRING:
1088 case T_VIDEOTEXSTRING:
1089 case T_GRAPHICSTRING:
1090 case T_OBJECTDESCRIPTOR:
1091 case T_GENERALSTRING:
1092 // iso2022str
1093 case T_NUMERICSTRING:
1094 case T_PRINTABLESTRING:
1095 case T_IA5STRING:
1096 case T_VISIBLESTRING:
1097 case T_UTCTIME:
1098 case T_GENERALIZEDTIME:
1099 return T_CSTR;
1100 case T_ROID:
1101 return T_OID;
1102 case T_ANY:
1103 return T_OSTR;
1104 case T_CHOICE_A:
1105 case T_OPENTYPE:
1106 return T_CHOICE_T;
1107 case T_SEQ_A:
1108 case T_EXTERNAL:
1109 case T_EMBEDDED_PDV:
1110 case T_UNRESTRICTEDSTRING:
1111 return T_SEQ_T;
1112 case T_SET_A:
1113 return T_SET_T;
1114 default:
1115 return p_tt;
1116 } // switch typetype
1117 }
1118
1119 bool Type::is_asn1() const
1120 {
1121 if (my_scope) return Setting::is_asn1();
1122 // the type might be a pool type, which is considered to be a TTCN-3 type
1123 typetype_t t_typetype = get_typetype_ttcn3(typetype);
1124 if (pooltypes && pooltypes->has_key(t_typetype) &&
1125 (*pooltypes)[t_typetype] == this) return false;
1126 else FATAL_ERROR("Type::is_asn1()");
1127 }
1128
1129 bool Type::is_ref() const
1130 {
1131 switch(typetype) {
1132 case T_UNRESTRICTEDSTRING:
1133 case T_OCFT:
1134 case T_EXTERNAL:
1135 case T_EMBEDDED_PDV:
1136 case T_REFD:
1137 case T_REFDSPEC:
1138 case T_SELTYPE:
1139 case T_ADDRESS:
1140 return true;
1141 default:
1142 return false;
1143 } // switch
1144 }
1145
1146 bool Type::is_secho() const
1147 {
1148 switch(typetype) {
1149 case T_ANYTYPE:
1150 case T_CHOICE_A:
1151 case T_CHOICE_T:
1152 case T_OPENTYPE:
1153 case T_SEQ_A:
1154 case T_SEQ_T:
1155 case T_SET_A:
1156 case T_SET_T:
1157 return true;
1158 default:
1159 return false;
1160 } // switch
1161 }
1162
1163 Type::truth Type::is_charenc()
1164 {
1165 switch(typetype) {
1166 case T_CHOICE_A:
1167 case T_CHOICE_T:
1168 {
1169 bool possible = true;
1170 size_t ncomp = u.secho.cfm->get_nof_comps();
1171 for (size_t i=0; i<ncomp; ++i) {
1172 CompField * cf = u.secho.cfm->get_comp_byIndex(i);
1173 if (cf->get_type()->is_charenc() == No) {
1174 possible = false; break;
1175 }
1176 } // next i
1177 if (possible) {
1178 return (xerattrib && (xerattrib->useUnion_ || xerattrib->useType_)) ? Yes : No;
1179 }
1180 }
1181 // no break
1182 case T_SEQ_A:
1183 case T_SEQ_T:
1184 case T_SET_A:
1185 case T_SET_T:
1186 case T_OPENTYPE:
1187 // UNTAGGED cannot be used to make a type character-encodable!
1188 // But USE-QNAME can!
1189 return (xerattrib && xerattrib->useQName_) ? Yes : No;
1190
1191 case T_SEQOF: // A record-of is character-encodable if it has the "list"
1192 case T_SETOF: // attribute and its element is character-encodable.
1193 return (xerattrib && xerattrib->list_ && (u.seof.ofType->is_charenc()==Yes))
1194 ? Yes : No;
1195
1196 case T_ENUM_A:
1197 case T_ENUM_T:
1198 case T_VERDICT:
1199 return Yes;
1200
1201 default:
1202 if (is_ref()) {
1203 truth retval = get_type_refd_last()->is_charenc();
1204 if (retval == Yes) return Yes;
1205 else if (retval == Maybe) {
1206 if (xerattrib && xerattrib->useUnion_) return Yes;
1207 }
1208 // else fall through to No
1209 }
1210 return No;
1211
1212 case T_BSTR:
1213 case T_OSTR:
1214 case T_HSTR:
1215 case T_CSTR:
1216 case T_USTR:
1217 case T_UTF8STRING:
1218 // TODO ASN.1 restricted character string types when (if) ASN.1 gets XER
1219 // TODO check subtype; strings must be restricted to not contain
1220 // control characters (0..0x1F except 9,0x0A,0x0D)
1221 case T_INT_A:
1222 case T_INT:
1223 case T_BOOL:
1224 case T_REAL:
1225 // TODO more types
1226 /* FIXME : this kind of check should be applied to elements of secho,
1227 * not to the type of the element ! */
1228 return Yes;
1229 }
1230 }
1231
1232 bool Type::has_empty_xml() {
1233 bool answer = false;
1234 switch (typetype) {
1235 case T_SEQ_A: case T_SEQ_T:
1236 case T_SET_A: case T_SET_T: {
1237 answer = true; // If all components are optional.
1238 size_t n_comps = get_nof_comps();
1239 for (size_t i = 0; i < n_comps; ++i) {
1240 CompField* cf = get_comp_byIndex(i);
1241 if (!cf->get_is_optional()) {
1242 answer = false;
1243 break; // the loop
1244 }
1245 }
1246 break; }
1247 case T_SEQOF: case T_SETOF:
1248 // _If_ there is a length restriction, 0 length must be allowed.
1249 // By this time parsed_restr has been absorbed into sub_type.
1250 answer = (sub_type==0) || sub_type->zero_length_allowed();
1251 break;
1252 default:
1253 break;
1254 } // switch
1255 return answer;
1256 }
1257
1258 void Type::set_fullname(const string& p_fullname)
1259 {
1260 Governor::set_fullname(p_fullname);
1261 switch(typetype) {
1262 case T_INT_A:
1263 case T_BSTR_A:
1264 if(u.namednums.block) u.namednums.block->set_fullname(p_fullname);
1265 if(u.namednums.nvs)
1266 u.namednums.nvs->set_fullname(p_fullname+".<namedvalues>");
1267 break;
1268 case T_ENUM_A:
1269 if(u.enums.eis1) u.enums.eis1->set_fullname(p_fullname);
1270 if(u.enums.eis2) u.enums.eis2->set_fullname(p_fullname);
1271 // no break
1272 case T_ENUM_T:
1273 u.enums.eis->set_fullname(p_fullname);
1274 break;
1275 case T_ANYTYPE:
1276 case T_CHOICE_T:
1277 case T_SEQ_T:
1278 case T_SET_T:
1279 case T_OPENTYPE:
1280 u.secho.cfm->set_fullname(p_fullname);
1281 break;
1282 case T_SEQ_A:
1283 case T_SET_A:
1284 case T_CHOICE_A:
1285 if (u.secho.ctss) u.secho.ctss->set_fullname(p_fullname);
1286 break;
1287 case T_SEQOF:
1288 case T_SETOF: {
1289 string subtypename(".<oftype>");
1290 Type * t = u.seof.ofType;
1291 /* Do NOT call get_type_refd_last() or else fatal_error !
1292 * The AST is not fully set up. */
1293
1294 /* XER will use these strings */
1295 switch (t->typetype)
1296 {
1297 case T_EMBEDDED_PDV: case T_EXTERNAL:
1298 case T_SEQ_A: case T_SEQ_T:
1299 subtypename = ".SEQUENCE";
1300 break;
1301
1302 case T_SET_A: case T_SET_T:
1303 subtypename = ".SET";
1304 break;
1305
1306 case T_SEQOF:
1307 subtypename = ".SEQUENCE_OF";
1308 break;
1309
1310 case T_SETOF:
1311 subtypename = ".SET_OF";
1312 break;
1313
1314 case T_BSTR_A:
1315 subtypename = ".BITSTRING";
1316 break;
1317
1318 case T_BOOL:
1319 subtypename = ".BOOLEAN";
1320 break;
1321
1322 case T_CHOICE_A: case T_CHOICE_T:
1323 subtypename = ".CHOICE";
1324 break;
1325
1326 case T_ENUM_A: case T_ENUM_T:
1327 subtypename = ".ENUMERATED";
1328 break;
1329
1330 case T_INT_A: case T_INT:
1331 subtypename = ".INTEGER";
1332 break;
1333
1334 default:
1335 break;
1336 }
1337 u.seof.ofType->set_fullname(p_fullname+subtypename);
1338 break; }
1339 case T_REFD:
1340 u.ref.ref->set_fullname(p_fullname);
1341 break;
1342 case T_SELTYPE:
1343 u.seltype.type->set_fullname(p_fullname+".<selection>");
1344 break;
1345 case T_PORT:
1346 u.port->set_fullname(p_fullname);
1347 break;
1348 case T_COMPONENT:
1349 u.component->set_fullname(p_fullname);
1350 break;
1351 case T_ARRAY:
1352 u.array.element_type->set_fullname(p_fullname + ".<element_type>");
1353 u.array.dimension->set_fullname(p_fullname + ".<dimension>");
1354 break;
1355 case T_SIGNATURE:
1356 if (u.signature.parameters)
1357 u.signature.parameters->set_fullname(p_fullname);
1358 if (u.signature.return_type)
1359 u.signature.return_type->set_fullname(p_fullname + ".<return_type>");
1360 if (u.signature.exceptions)
1361 u.signature.exceptions->set_fullname(p_fullname + ".<exception_list>");
1362 break;
1363 case T_FUNCTION:
1364 case T_ALTSTEP:
1365 u.fatref.fp_list->set_fullname(p_fullname + "<formal_par_list>");
1366 if (u.fatref.runs_on.ref)
1367 u.fatref.runs_on.ref->set_fullname(p_fullname + "<runs_on_type>");
1368 if (u.fatref.return_type)
1369 u.fatref.return_type->set_fullname(p_fullname + "<return type>");
1370 break;
1371 case T_TESTCASE:
1372 u.fatref.fp_list->set_fullname(p_fullname + ".<formal_par_list>");
1373 if (u.fatref.runs_on.ref)
1374 u.fatref.runs_on.ref->set_fullname(p_fullname+".<runs_on_type>");
1375 if (u.fatref.system.ref)
1376 u.fatref.system.ref->set_fullname(p_fullname + ".<system_type>");
1377 break;
1378 default:
1379 break;
1380 } // switch
1381 }
1382
1383 void Type::set_my_scope(Scope *p_scope)
1384 {
1385 Governor::set_my_scope(p_scope);
1386 if(tags) tags->set_my_scope(p_scope);
1387 switch(typetype) {
1388 case T_INT_A:
1389 case T_BSTR_A:
1390 if(u.namednums.nvs) u.namednums.nvs->set_my_scope(p_scope);
1391 break;
1392 case T_ENUM_A:
1393 if(u.enums.eis1) u.enums.eis1->set_my_scope(p_scope);
1394 if(u.enums.eis2) u.enums.eis2->set_my_scope(p_scope);
1395 // no break
1396 case T_ENUM_T:
1397 u.enums.eis->set_my_scope(p_scope);
1398 break;
1399 case T_CHOICE_T:
1400 case T_SEQ_T:
1401 case T_SET_T:
1402 case T_OPENTYPE:
1403 case T_ANYTYPE:
1404 u.secho.cfm->set_my_scope(p_scope);
1405 break;
1406 case T_SEQ_A:
1407 case T_SET_A:
1408 case T_CHOICE_A:
1409 if(u.secho.ctss) u.secho.ctss->set_my_scope(p_scope);
1410 break;
1411 case T_SEQOF:
1412 case T_SETOF:
1413 u.seof.ofType->set_my_scope(p_scope);
1414 break;
1415 case T_REFD:
1416 u.ref.ref->set_my_scope(p_scope);
1417 break;
1418 case T_SELTYPE:
1419 u.seltype.type->set_my_scope(p_scope);
1420 break;
1421 case T_ARRAY:
1422 u.array.element_type->set_my_scope(p_scope);
1423 u.array.dimension->set_my_scope(p_scope);
1424 break;
1425 case T_PORT:
1426 u.port->set_my_scope(p_scope);
1427 break;
1428 case T_SIGNATURE:
1429 if (u.signature.parameters)
1430 u.signature.parameters->set_my_scope(p_scope);
1431 if (u.signature.return_type)
1432 u.signature.return_type->set_my_scope(p_scope);
1433 if (u.signature.exceptions)
1434 u.signature.exceptions->set_my_scope(p_scope);
1435 break;
1436 case T_COMPONENT:
1437 u.component->set_my_scope(p_scope);
1438 break;
1439 case T_FUNCTION:
1440 case T_ALTSTEP:
1441 // the scope of parameter list is set later in chk_Fat()
1442 if (u.fatref.runs_on.ref)
1443 u.fatref.runs_on.ref->set_my_scope(p_scope);
1444 if (u.fatref.return_type)
1445 u.fatref.return_type->set_my_scope(p_scope);
1446 break;
1447 case T_TESTCASE:
1448 // the scope of parameter list is set later in chk_Fat()
1449 if (u.fatref.runs_on.ref)
1450 u.fatref.runs_on.ref->set_my_scope(p_scope);
1451 if (u.fatref.system.ref)
1452 u.fatref.system.ref->set_my_scope(p_scope);
1453 break;
1454 default:
1455 break;
1456 } // switch
1457 }
1458
1459 Type* Type::get_type_refd(ReferenceChain *refch)
1460 {
1461 switch(typetype) {
1462 case T_REFD: {
1463 if(refch && !refch->add(get_fullname())) goto error;
1464 if(!u.ref.type_refd) {
1465 Assignment *ass = u.ref.ref->get_refd_assignment();
1466 if (!ass) goto error; // The referenced assignment is not found
1467 switch (ass->get_asstype()) {
1468 case Assignment::A_ERROR:
1469 goto error;
1470 case Assignment::A_TYPE:
1471 case Assignment::A_VS:
1472 u.ref.type_refd = ass->get_Type()->get_field_type(
1473 u.ref.ref->get_subrefs(), EXPECTED_DYNAMIC_VALUE, refch);
1474 if (!u.ref.type_refd) goto error;
1475 break;
1476 //case Assignment::A_VS:
1477 //u.ref.type_refd = ass->get_Type();
1478 // if(!u.ref.type_refd) goto error;
1479 //break;
1480 case Assignment::A_OC:
1481 case Assignment::A_OBJECT:
1482 case Assignment::A_OS: {
1483 Setting *setting = u.ref.ref->get_refd_setting();
1484 if (!setting || setting->get_st() == Setting::S_ERROR) goto error;
1485 /* valueset? */
1486 u.ref.type_refd = dynamic_cast<Type*>(setting);
1487 if(!u.ref.type_refd) {
1488 error("`%s' is not a reference to a type",
1489 u.ref.ref->get_dispname().c_str());
1490 goto error;
1491 }
1492
1493 if (u.ref.type_refd->ownertype == OT_UNKNOWN) {
1494 u.ref.type_refd->set_ownertype(OT_REF, this);
1495 }
1496
1497 break;}
1498 default:
1499 error("`%s' is not a reference to a type",
1500 u.ref.ref->get_dispname().c_str());
1501 goto error;
1502 } // switch
1503 if(!u.ref.type_refd->get_my_scope()) {
1504 // opentype or OCFT
1505 u.ref.type_refd->set_my_scope(get_my_scope());
1506 u.ref.type_refd->set_parent_type(get_parent_type());
1507 u.ref.type_refd->set_genname(get_genname_own(), string("type"));
1508 u.ref.type_refd->set_fullname(get_fullname()+".type");
1509 }
1510 if (u.ref.type_refd->typetype == T_OPENTYPE && !constraints)
1511 warning("An open type without table constraint is useless in TTCN-3");
1512 }
1513 return u.ref.type_refd;
1514 break;}
1515 case T_SELTYPE: {
1516 if(refch && !refch->add(get_fullname())) goto error;
1517 if(!u.seltype.type_refd) {
1518 Type *t=u.seltype.type->get_type_refd_last(refch);
1519 if(t->typetype==T_ERROR) goto error;
1520 if(t->typetype!=T_CHOICE_A) {
1521 error("(Reference to) a CHOICE type was expected"
1522 " in selection type.");
1523 goto error;
1524 }
1525 if(!t->has_comp_withName(*u.seltype.id)) {
1526 error("No alternative with name `%s' in the given type `%s'.",
1527 u.seltype.id->get_dispname().c_str(),
1528 t->get_fullname().c_str());
1529 goto error;
1530 }
1531 u.seltype.type_refd=t->get_comp_byName(*u.seltype.id)->get_type();
1532 }
1533 return u.seltype.type_refd;
1534 break;}
1535 case T_REFDSPEC:
1536 case T_OCFT:
1537 if(refch && !refch->add(get_fullname())) goto error;
1538 return u.ref.type_refd;
1539 break;
1540 case T_EXTERNAL: {
1541 if (!my_scope) FATAL_ERROR("Type::get_type_refd()");
1542 Identifier t_id(Identifier::ID_ASN, string("EXTERNAL"));
1543 return my_scope->get_scope_asss()->get_local_ass_byId(t_id)->get_Type(); }
1544 case T_EMBEDDED_PDV: {
1545 if (!my_scope) FATAL_ERROR("Type::get_type_refd()");
1546 Identifier t_id(Identifier::ID_ASN, string("EMBEDDED PDV"));
1547 return my_scope->get_scope_asss()->get_local_ass_byId(t_id)->get_Type(); }
1548 case T_UNRESTRICTEDSTRING: {
1549 if (!my_scope) FATAL_ERROR("Type::get_type_refd()");
1550 Identifier t_id(Identifier::ID_ASN, string("CHARACTER STRING"));
1551 return my_scope->get_scope_asss()->get_local_ass_byId(t_id)->get_Type(); }
1552 case T_ADDRESS:
1553 if (refch && !refch->add(get_fullname())) goto error;
1554 if (u.address) return u.address;
1555 if (!my_scope) FATAL_ERROR("Type::get_type_refd()");
1556 u.address = my_scope->get_scope_mod()->get_address_type();
1557 if (!u.address) {
1558 error("Type `address' is not defined in this module");
1559 goto error;
1560 }
1561 return u.address;
1562 default:
1563 FATAL_ERROR("Type::get_type_refd()");
1564 return 0;
1565 } // switch
1566 error:
1567 clean_up();
1568 return this;
1569 }
1570
1571 Type* Type::get_type_refd_last(ReferenceChain *refch)
1572 {
1573 Type *t=this;
1574 while(t->is_ref()) t=t->get_type_refd(refch);
1575 return t;
1576 }
1577
1578 Type *Type::get_field_type(Ttcn::FieldOrArrayRefs *subrefs,
1579 expected_value_t expected_index, ReferenceChain *refch,
1580 bool interrupt_if_optional)
1581 {
1582 if (!subrefs) return this;
1583 Type *t = this;
1584 if (expected_index == EXPECTED_TEMPLATE)
1585 expected_index = EXPECTED_DYNAMIC_VALUE;
1586 size_t nof_refs = subrefs->get_nof_refs();
1587 subrefs->clear_string_element_ref();
1588 for (size_t i = 0; i < nof_refs; i++) {
1589 if (refch) refch->mark_state();
1590 t = t->get_type_refd_last(refch);
1591 if (refch) refch->prev_state();
1592 // stop immediately if current type t is erroneous
1593 // (e.g. because of circular reference)
1594 if (t->typetype == T_ERROR) return 0;
1595 Ttcn::FieldOrArrayRef *ref = subrefs->get_ref(i);
1596 switch (ref->get_type()) {
1597 case Ttcn::FieldOrArrayRef::FIELD_REF: {
1598 if (t->typetype == T_OPENTYPE) {
1599 // allow the alternatives of open types as both lower and upper identifiers
1600 ref->set_field_name_to_lowercase();
1601 }
1602 const Identifier& id = *ref->get_id();
1603 switch (t->typetype) {
1604 case T_CHOICE_A:
1605 case T_CHOICE_T:
1606 case T_OPENTYPE:
1607 case T_SEQ_A:
1608 case T_SEQ_T:
1609 case T_SET_A:
1610 case T_SET_T:
1611 case T_ANYTYPE:
1612 break;
1613 default:
1614 ref->error("Invalid field reference `%s': type `%s' "
1615 "does not have fields", id.get_dispname().c_str(),
1616 t->get_typename().c_str());
1617 return 0;
1618 }
1619 if (!t->has_comp_withName(id)) {
1620 ref->error("Reference to non-existent field `%s' in type `%s'",
1621 id.get_dispname().c_str(),
1622 t->get_typename().c_str());
1623 return 0;
1624 }
1625 CompField* cf = t->get_comp_byName(id);
1626 if (interrupt_if_optional && cf->get_is_optional()) return 0;
1627 t = cf->get_type();
1628 break; }
1629 case Ttcn::FieldOrArrayRef::ARRAY_REF: {
1630 Type *embedded_type = 0;
1631 switch (t->typetype) {
1632 case T_SEQOF:
1633 case T_SETOF:
1634 embedded_type = t->u.seof.ofType;
1635 break;
1636 case T_ARRAY:
1637 embedded_type = t->u.array.element_type;
1638 break;
1639 case T_BSTR:
1640 case T_BSTR_A:
1641 case T_HSTR:
1642 case T_OSTR:
1643 case T_CSTR:
1644 case T_USTR:
1645 case T_UTF8STRING:
1646 case T_NUMERICSTRING:
1647 case T_PRINTABLESTRING:
1648 case T_TELETEXSTRING:
1649 case T_VIDEOTEXSTRING:
1650 case T_IA5STRING:
1651 case T_GRAPHICSTRING:
1652 case T_VISIBLESTRING:
1653 case T_GENERALSTRING:
1654 case T_UNIVERSALSTRING:
1655 case T_BMPSTRING:
1656 case T_UTCTIME:
1657 case T_GENERALIZEDTIME:
1658 case T_OBJECTDESCRIPTOR:
1659 if (subrefs->refers_to_string_element()) {
1660 ref->error("A string element of type `%s' cannot be indexed",
1661 t->get_typename().c_str());
1662 return 0;
1663 } else {
1664 subrefs->set_string_element_ref();
1665 // string elements have the same type as the string itself
1666 embedded_type = t;
1667 break;
1668 }
1669 default:
1670 ref->error("Type `%s' cannot be indexed",
1671 t->get_typename().c_str());
1672 return 0;
1673 }
1674 // check the index value
1675 Value *index_value = ref->get_val();
1676 if (t->typetype == T_ARRAY) {
1677 // checking of array index is performed by the array dimension
1678 t->u.array.dimension->chk_index(index_value, expected_index);
1679 } else {
1680 // perform a generic index check for other types
1681 if (refch == 0 // variable assignment
1682 || index_value->get_valuetype() != Value::V_NOTUSED) {
1683 Error_Context cntxt(index_value, "In index value");
1684 index_value->chk_expr_int(expected_index);
1685 }
1686 Value *v_last = index_value->get_value_refd_last();
1687 if (v_last->get_valuetype() == Value::V_INT) {
1688 const int_val_t *index_int = v_last->get_val_Int();
1689 if (*index_int > INT_MAX) {
1690 index_value->error("Integer value `%s' is too big for indexing "
1691 "type `%s'", (index_int->t_str()).c_str(),
1692 (t->get_typename()).c_str());
1693 index_value->set_valuetype(Value::V_ERROR);
1694 } else {
1695 if (*index_int < 0) {
1696 index_value->error("A non-negative integer value was "
1697 "expected for indexing type `%s' instead of `%s'",
1698 t->get_typename().c_str(), (index_int->t_str()).c_str());
1699 index_value->set_valuetype(Value::V_ERROR);
1700 }
1701 }
1702 }
1703 }
1704 // change t to the embedded type
1705 t = embedded_type;
1706 break; }
1707 default:
1708 FATAL_ERROR("Type::get_field_type(): invalid reference type");
1709 }
1710 }
1711 return t;
1712 }
1713
1714 bool Type::get_subrefs_as_array(const Ttcn::FieldOrArrayRefs *subrefs, dynamic_array<size_t>& subrefs_array, dynamic_array<Type*>& type_array)
1715 {
1716 if (!subrefs) FATAL_ERROR("Type::get_subrefs_as_array()");
1717 Type *t = this;
1718 size_t nof_refs = subrefs->get_nof_refs();
1719 for (size_t i = 0; i < nof_refs; i++) {
1720 t = t->get_type_refd_last();
1721 type_array.add(t);
1722 if (t->typetype == T_ERROR) FATAL_ERROR("Type::get_subrefs_as_array()");
1723 Ttcn::FieldOrArrayRef *ref = subrefs->get_ref(i);
1724 size_t field_index=0;
1725 switch (ref->get_type()) {
1726 case Ttcn::FieldOrArrayRef::FIELD_REF: {
1727 const Identifier& id = *ref->get_id();
1728 if (!t->has_comp_withName(id)) FATAL_ERROR("Type::get_subrefs_as_array()");
1729 CompField* cf = t->get_comp_byName(id);
1730 field_index = t->get_comp_index_byName(id);
1731 field_index = t->get_codegen_index(field_index);
1732 t = cf->get_type();
1733 break; }
1734 case Ttcn::FieldOrArrayRef::ARRAY_REF: {
1735 Value *index_value = ref->get_val();
1736 Value *v_last = index_value->get_value_refd_last();
1737 if (v_last->get_valuetype()!=Value::V_INT) {
1738 // workaround: get_field_type() does not return NULL if the index
1739 // value is invalid, this function returns false in this case
1740 return false;
1741 }
1742 const int_val_t *index_int = v_last->get_val_Int();
1743 if (!index_int->is_native() || index_int->is_negative()) {
1744 return false;
1745 }
1746 field_index = (size_t)index_int->get_val();
1747 Type *embedded_type = 0;
1748 switch (t->typetype) {
1749 case T_SEQOF:
1750 case T_SETOF:
1751 embedded_type = t->u.seof.ofType;
1752 break;
1753 case T_ARRAY:
1754 embedded_type = t->u.array.element_type;
1755 break;
1756 default:
1757 embedded_type = t;
1758 break;
1759 }
1760 // change t to the embedded type
1761 t = embedded_type;
1762 break; }
1763 default:
1764 FATAL_ERROR("Type::get_subrefs_as_array()");
1765 }
1766 subrefs_array.add(field_index);
1767 }
1768 return true;
1769 }
1770
1771 bool Type::is_optional_field() const {
1772 if (ownertype == OT_COMP_FIELD) {
1773 const CompField* const myOwner = (CompField*) owner;
1774 return myOwner && myOwner->get_is_optional();
1775 }
1776 return false;
1777 }
1778
1779 bool Type::field_is_optional(Ttcn::FieldOrArrayRefs *subrefs)
1780 {
1781 // handling trivial cases
1782 if (!subrefs) return false;
1783 size_t nof_subrefs = subrefs->get_nof_refs();
1784 if (nof_subrefs < 1) return false;
1785 Ttcn::FieldOrArrayRef *last_ref = subrefs->get_ref(nof_subrefs - 1);
1786 if (last_ref->get_type() == Ttcn::FieldOrArrayRef::ARRAY_REF) return false;
1787 // following the embedded types
1788 Type *t=get_type_refd_last();
1789 for (size_t i = 0; i < nof_subrefs - 1; i++) {
1790 Ttcn::FieldOrArrayRef *ref = subrefs->get_ref(i);
1791 if (ref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF)
1792 t = t->get_comp_byName(*ref->get_id())->get_type();
1793 else t = t->get_ofType();
1794 t=t->get_type_refd_last();
1795 }
1796 // now last_ref refers to a field of t
1797 return t->get_comp_byName(*last_ref->get_id())->get_is_optional();
1798 }
1799
1800 bool Type::is_root_basic(){
1801 Type *t=get_type_refd_last();
1802 switch(t->typetype){
1803 case T_INT:
1804 case T_BOOL:
1805 case T_BSTR:
1806 case T_HSTR:
1807 case T_OSTR:
1808 case T_CSTR:
1809 return true;
1810 break;
1811 default:
1812 break;
1813 }
1814 return false;
1815 }
1816
1817 int Type::get_raw_length(){
1818 if(!raw_checked) FATAL_ERROR("Type::get_raw_length()");
1819 if(raw_length_calculated) return raw_length;
1820 raw_length_calculated=true;
1821 switch(typetype) {
1822 case T_REFD:
1823 raw_length=get_type_refd()->get_raw_length();
1824 break;
1825 case T_INT:
1826 if(rawattrib) raw_length=rawattrib->fieldlength;
1827 else raw_length=8;
1828 break;
1829 case T_BOOL:
1830 if(rawattrib) raw_length=rawattrib->fieldlength;
1831 else raw_length=1;
1832 break;
1833 case T_BSTR:
1834 case T_HSTR:
1835 case T_OSTR:
1836 case T_CSTR:
1837 if(rawattrib && rawattrib->fieldlength) raw_length=rawattrib->fieldlength;
1838 else raw_length=-1;
1839 break;
1840 case T_ENUM_T:
1841 if(rawattrib && rawattrib->fieldlength) raw_length=rawattrib->fieldlength;
1842 else{
1843 int min_bits=0;
1844 int max_val=u.enums.first_unused;
1845 for(size_t a=0;a<u.enums.eis->get_nof_eis();a++){
1846 int val=u.enums.eis->get_ei_byIndex(a)->get_value()->get_val_Int()
1847 ->get_val();
1848 if((max_val<0?-max_val:max_val)<(val<0?-val:val)) max_val=val;
1849 }
1850 if(max_val<0){ min_bits=1;max_val=-max_val;}
1851 while(max_val){ min_bits++; max_val/=2;}
1852 raw_length=min_bits;
1853 }
1854 break;
1855 case T_SEQ_T:
1856 case T_SET_T:
1857 raw_length=0;
1858 for(size_t i = 0; i < get_nof_comps(); i++){
1859 int l=0;
1860 CompField* cf=get_comp_byIndex(i);
1861 if(cf->get_is_optional()){
1862 raw_length=-1;
1863 return raw_length;
1864 }
1865 l=cf->get_type()->get_raw_length();
1866 if(l==-1){
1867 raw_length=-1;
1868 return raw_length;
1869 }
1870 if(cf->get_type()->rawattrib
1871 && (cf->get_type()->rawattrib->pointerto
1872 || cf->get_type()->rawattrib->lengthto_num)){
1873 raw_length=-1;
1874 return raw_length;
1875 }
1876 raw_length+=l;
1877 }
1878 break;
1879 // TODO: case T_ANYTYPE: for get_raw_length needed ?
1880 case T_CHOICE_T:
1881 for(size_t i = 0; i < get_nof_comps(); i++){
1882 CompField *cf=get_comp_byIndex(i);
1883 int l=0;
1884 l=cf->get_type()->get_raw_length();
1885 if(l==-1){
1886 raw_length=-1;
1887 return raw_length;
1888 }
1889 if(i){
1890 if(raw_length!=l){
1891 raw_length=-1;
1892 return raw_length;
1893 }
1894 }
1895 else raw_length=l;
1896 }
1897 break;
1898 default:
1899 raw_length=-1;
1900 break;
1901 }
1902 return raw_length;
1903 }
1904
1905 /** \todo: add extra checks and warnings for unsupported attributes
1906 * e.g. when TAG refers to a record/set field which has union type */
1907 void Type::chk_raw()
1908 {
1909 bool self_ref = false;
1910 if (raw_checked) return;
1911 raw_checked = true;
1912 if (!enable_raw()) return;
1913 int restrlength=-1;
1914 if(sub_type)
1915 restrlength=(int)sub_type->get_length_restriction();
1916 if(restrlength!=-1){
1917 if(!rawattrib){
1918 Type *t=get_type_refd_last();
1919 typetype_t basic_type=t->typetype;
1920 rawattrib=new RawAST(basic_type==T_INT);
1921 if(basic_type==T_REAL) rawattrib->fieldlength=64;
1922 }
1923 rawattrib->length_restrition=restrlength;
1924 }
1925 if(!rawattrib) return;
1926 switch(typetype) {
1927 case T_REFD:
1928 get_type_refd()->force_raw();
1929 if(rawattrib->fieldlength==0 && rawattrib->length_restrition!=-1){
1930 typetype_t basic_type=get_type_refd_last()->typetype;
1931 switch(basic_type){
1932 case T_BSTR:
1933 rawattrib->fieldlength=rawattrib->length_restrition;
1934 rawattrib->length_restrition=-1;
1935 break;
1936 case T_HSTR:
1937 rawattrib->fieldlength=rawattrib->length_restrition*4;
1938 rawattrib->length_restrition=-1;
1939 break;
1940 case T_OSTR:
1941 rawattrib->fieldlength=rawattrib->length_restrition*8;
1942 rawattrib->length_restrition=-1;
1943 break;
1944 case T_CSTR:
1945 rawattrib->fieldlength=rawattrib->length_restrition*8;
1946 rawattrib->length_restrition=-1;
1947 break;
1948 case T_SEQOF:
1949 case T_SETOF:
1950 rawattrib->fieldlength=rawattrib->length_restrition;
1951 rawattrib->length_restrition=-1;
1952 break;
1953 default:
1954 break;
1955 }
1956 }
1957 break;
1958 case T_CHOICE_T:
1959 if(rawattrib){
1960 size_t nof_comps = get_nof_comps();
1961 for (size_t i = 0; i < nof_comps; i++)
1962 get_comp_byIndex(i)->get_type()->force_raw();
1963 for(int c=0;c<rawattrib->taglist.nElements;c++){
1964 Identifier *idf=rawattrib->taglist.tag[c].fieldName;
1965 if(!has_comp_withName(*idf)){
1966 error("Invalid field name `%s' in RAW parameter TAG for type `%s'",
1967 idf->get_dispname().c_str(), get_typename().c_str());
1968 continue;
1969 }
1970 size_t fieldnum = get_comp_index_byName(*idf);
1971 for(int a=0;a<rawattrib->taglist.tag[c].nElements;a++){
1972 bool hiba=false;
1973 CompField *cf=get_comp_byIndex(fieldnum);
1974 Type *t=cf->get_type()->get_type_refd_last();
1975 for(int b=0;b<rawattrib->taglist.tag[c].keyList[a].
1976 keyField->nElements;b++){
1977 Identifier *idf2=
1978 rawattrib->taglist.tag[c].keyList[a].keyField->names[b];
1979 if(!t->is_secho()){
1980 error("Invalid fieldmember type in RAW parameter TAG"
1981 " for field %s."
1982 ,cf->get_name().get_dispname().c_str());
1983 hiba=true;
1984 break;
1985 }
1986 if(!t->has_comp_withName(*idf2)){
1987 error("Invalid field member name `%s' in RAW parameter TAG "
1988 "for field `%s'", idf2->get_dispname().c_str(),
1989 cf->get_name().get_dispname().c_str());
1990 hiba=true;
1991 break;
1992 }
1993 size_t comp_index=t->get_comp_index_byName(*idf2);
1994 CompField *cf2=t->get_comp_byIndex(comp_index);
1995 t=cf2->get_type()->get_type_refd_last();
1996 }
1997 if(!hiba){
1998 Error_Context cntx(this, "In Raw parmeter TAG");
1999 Value *v = rawattrib->taglist.tag[c].keyList[a].v_value;
2000 v->set_my_scope(get_my_scope());
2001 v->set_my_governor(t);
2002 t->chk_this_value_ref(v);
2003 self_ref = t->chk_this_value(v, 0, EXPECTED_CONSTANT,
2004 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
2005 Value::valuetype_t vt = v->get_valuetype();
2006 if (vt == Value::V_ENUM || vt == Value::V_REFD) {
2007 Free(rawattrib->taglist.tag[c].keyList[a].value);
2008 rawattrib->taglist.tag[c].keyList[a].value =
2009 mcopystr(v->get_single_expr().c_str());
2010 }
2011 }
2012 }
2013 }
2014 }
2015 break;
2016 case T_SEQ_T:
2017 case T_SET_T: {
2018 if(rawattrib){
2019 size_t fieldnum;
2020 for(int c=0;c<rawattrib->taglist.nElements;c++) { // check TAG
2021 Identifier *idf=rawattrib->taglist.tag[c].fieldName;
2022 if(!has_comp_withName(*idf)){
2023 error("Invalid field name `%s' in RAW parameter TAG "
2024 "for type `%s'", idf->get_dispname().c_str(),
2025 get_typename().c_str());
2026 continue;
2027 }
2028 fieldnum=get_comp_index_byName(*idf);
2029 for(int a=0;a<rawattrib->taglist.tag[c].nElements;a++){
2030 bool hiba=false;
2031 CompField *cf=get_comp_byIndex(fieldnum);
2032 Type *t=cf->get_type()->get_type_refd_last();
2033 for(int b=0;b<rawattrib->taglist.tag[c].keyList[a].
2034 keyField->nElements;b++){
2035 Identifier *idf2=
2036 rawattrib->taglist.tag[c].keyList[a].keyField->names[b];
2037 if(!t->is_secho()){
2038 error("Invalid fieldmember type in RAW parameter TAG"
2039 " for field %s."
2040 ,cf->get_name().get_dispname().c_str());
2041 hiba=true;
2042 break;
2043 }
2044 if(!t->has_comp_withName(*idf2)){
2045 error("Invalid field member name `%s' in RAW parameter TAG "
2046 "for field `%s'", idf2->get_dispname().c_str(),
2047 cf->get_name().get_dispname().c_str());
2048 hiba=true;
2049 break;
2050 }
2051 size_t comp_index=t->get_comp_index_byName(*idf2);
2052 CompField *cf2=t->get_comp_byIndex(comp_index);
2053 t=cf2->get_type()->get_type_refd_last();
2054 }
2055 if(!hiba){
2056 Error_Context cntx(this, "In Raw parmeter TAG");
2057 Value *v = rawattrib->taglist.tag[c].keyList[a].v_value;
2058 v->set_my_scope(get_my_scope());
2059 v->set_my_governor(t);
2060 t->chk_this_value_ref(v);
2061 self_ref = t->chk_this_value(v, 0, EXPECTED_CONSTANT,
2062 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
2063 Value::valuetype_t vt = v->get_valuetype();
2064 if (vt == Value::V_ENUM || vt == Value::V_REFD) {
2065 Free(rawattrib->taglist.tag[c].keyList[a].value);
2066 rawattrib->taglist.tag[c].keyList[a].value =
2067 mcopystr(v->get_single_expr().c_str());
2068 }
2069 }
2070 }
2071 }
2072 for(int a=0; a<rawattrib->ext_bit_goup_num;a++){ // EXTENSION_BIT_GROUP
2073 Identifier *idf=rawattrib->ext_bit_groups[a].from;
2074 Identifier *idf2=rawattrib->ext_bit_groups[a].to;
2075 bool hiba=false;
2076 if(!has_comp_withName(*idf)){
2077 error("Invalid field name `%s' in RAW parameter "
2078 "EXTENSION_BIT_GROUP for type `%s'",
2079 idf->get_dispname().c_str(), get_typename().c_str());
2080 hiba=true;
2081 }
2082 if(!has_comp_withName(*idf2)){
2083 error("Invalid field name `%s' in RAW parameter "
2084 "EXTENSION_BIT_GROUP for type `%s'",
2085 idf2->get_dispname().c_str(), get_typename().c_str());
2086 hiba=true;
2087 }
2088 if(!hiba){
2089 size_t kezd=get_comp_index_byName(*idf);
2090 size_t veg=get_comp_index_byName(*idf2);
2091 if(kezd>veg){
2092 error("Invalid field order in RAW parameter "
2093 "EXTENSION_BIT_GROUP for type `%s': `%s', `%s'",
2094 get_typename().c_str(), idf->get_dispname().c_str(),
2095 idf2->get_dispname().c_str());
2096 hiba=true;
2097 }
2098 }
2099 }
2100 if(rawattrib->paddall!=XDEFDEFAULT){ // PADDALL
2101 for(size_t i = 0; i < get_nof_comps(); i++) {
2102 CompField *cfield=get_comp_byIndex(i);
2103 RawAST *field_rawattr=cfield->get_type()->rawattrib;
2104 if(field_rawattr==NULL){
2105 Type *t=cfield->get_type()->get_type_refd_last();
2106 typetype_t basic_type=t->typetype;
2107 t=cfield->get_type();
2108 if(t->is_ref()) t=t->get_type_refd();
2109 while(!t->rawattrib && t->is_ref()) t=t->get_type_refd();
2110 field_rawattr= new RawAST(t->rawattrib,basic_type==T_INT);
2111 if(!t->rawattrib && basic_type==T_REAL) field_rawattr->fieldlength=64;
2112 cfield->get_type()->rawattrib=field_rawattr;
2113 }
2114 if(field_rawattr->padding==0)
2115 field_rawattr->padding=rawattrib->padding;
2116 if(field_rawattr->prepadding==0)
2117 field_rawattr->prepadding=rawattrib->prepadding;
2118 if (field_rawattr->padding_pattern_length == 0 &&
2119 rawattrib->padding_pattern_length > 0) {
2120 Free(field_rawattr->padding_pattern);
2121 field_rawattr->padding_pattern =
2122 mcopystr(rawattrib->padding_pattern);
2123 field_rawattr->padding_pattern_length =
2124 rawattrib->padding_pattern_length;
2125 }
2126 }
2127 }
2128 if(rawattrib->fieldorder!=XDEFDEFAULT){ // FIELDORDER
2129 for(size_t i = 0; i < get_nof_comps(); i++) {
2130 CompField *cfield=get_comp_byIndex(i);
2131 RawAST *field_rawattr=cfield->get_type()->rawattrib;
2132 if(field_rawattr==NULL){
2133 Type *t=cfield->get_type()->get_type_refd_last();
2134 typetype_t basic_type=t->typetype;
2135 t=cfield->get_type();
2136 if(t->is_ref()) t=t->get_type_refd();
2137 while(!t->rawattrib && t->is_ref()) t=t->get_type_refd();
2138 field_rawattr= new RawAST(t->rawattrib,basic_type==T_INT);
2139 if(!t->rawattrib && basic_type==T_REAL) field_rawattr->fieldlength=64;
2140 cfield->get_type()->rawattrib=field_rawattr;
2141 }
2142 if(field_rawattr->fieldorder==XDEFDEFAULT)
2143 field_rawattr->fieldorder=rawattrib->fieldorder;
2144 }
2145 }
2146 }
2147 for(int a=0;a<rawattrib->presence.nElements;a++){ //PRESENCE
2148 Type *t=this;
2149 bool hiba=false;
2150 for(int b=0;b<rawattrib->presence.keyList[a].keyField->nElements;b++){
2151 Identifier *idf=rawattrib->presence.keyList[a].keyField->names[b];
2152 if(!t->is_secho()){
2153 error("Invalid fieldmember type in RAW parameter PRESENCE"
2154 " for the record %s."
2155 ,get_typename().c_str());
2156 hiba=true;
2157 break;
2158 }
2159 if(!t->has_comp_withName(*idf)){
2160 error("Invalid fieldname in RAW parameter"
2161 " PRESENCE for the record %s: %s"
2162 ,get_typename().c_str()
2163 ,rawattrib->presence.keyList[a].keyField->names[b]
2164 ->get_dispname().c_str());
2165 hiba=true;
2166 break;
2167 }
2168 t=t->get_comp_byName(*idf)->get_type()->get_type_refd_last();
2169 }
2170 if(!hiba){
2171 Error_Context cntx(this, "In Raw parameter PRESENCE");
2172 Value *v = rawattrib->presence.keyList[a].v_value;
2173 v->set_my_scope(get_my_scope());
2174 v->set_my_governor(t);
2175 t->chk_this_value_ref(v);
2176 self_ref = t->chk_this_value(v, 0, EXPECTED_CONSTANT,
2177 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
2178 Value::valuetype_t vt = v->get_valuetype();
2179 if (vt == Value::V_ENUM || vt == Value::V_REFD) {
2180 Free(rawattrib->presence.keyList[a].value);
2181 rawattrib->presence.keyList[a].value =
2182 mcopystr(v->get_single_expr().c_str());
2183 }
2184 }
2185 }
2186 int used_bits = 0; // number of bits used to store all previous fields
2187 for(size_t i = 0; i < get_nof_comps(); i++) { // field attributes
2188 CompField *cf = get_comp_byIndex(i);
2189 const Identifier& field_id = cf->get_name();
2190 Type *field_type = cf->get_type();
2191 Type *field_type_last = field_type->get_type_refd_last();
2192 field_type->force_raw();
2193 RawAST *rawpar = field_type->rawattrib;
2194 if (rawpar) {
2195 if (rawpar->prepadding != 0) {
2196 used_bits = (used_bits + rawpar->prepadding - 1) / rawpar->prepadding *
2197 rawpar->prepadding;
2198 }
2199 if (rawpar->intx && field_type_last->get_typetype() == T_INT) { // IntX
2200 if (used_bits % 8 != 0 &&
2201 (!rawattrib || rawattrib->fieldorder != XDEFMSB)) {
2202 error("Using RAW parameter IntX in a record/set with FIELDORDER "
2203 "set to 'lsb' is only supported if the IntX field starts at "
2204 "the beginning of a new octet. There are %d unused bits in the "
2205 "last octet before field %s.", 8 - (used_bits % 8),
2206 field_id.get_dispname().c_str());
2207 }
2208 }
2209 else {
2210 used_bits += rawpar->fieldlength;
2211 }
2212 if (rawpar->padding != 0) {
2213 used_bits = (used_bits + rawpar->padding - 1) / rawpar->padding *
2214 rawpar->padding;
2215 }
2216 for (int j = 0; j < rawpar->lengthto_num; j++) { // LENGTHTO
2217 Identifier *idf = rawpar->lengthto[j];
2218 if (!has_comp_withName(*idf)) {
2219 error("Invalid fieldname in RAW parameter "
2220 "LENGTHTO for field %s: %s",
2221 field_id.get_dispname().c_str(),
2222 rawpar->lengthto[j]->get_dispname().c_str());
2223 }
2224 }
2225 if (rawpar->lengthto_num) {
2226 Type *ft = field_type;
2227 if (ft->get_typetype() == T_REFD) ft = ft->get_type_refd_last();
2228 typetype_t ftt = ft->get_typetype();
2229 switch (ftt) {
2230 case T_INT:
2231 case T_INT_A:
2232 break;
2233 case T_CHOICE_T:
2234 case T_CHOICE_A:
2235 for (size_t fi = 0; fi < ft->get_nof_comps(); fi++) {
2236 typetype_t uftt = ft->get_comp_byIndex(fi)->get_type()
2237 ->get_typetype();
2238 if (uftt != T_INT && uftt != T_INT_A)
2239 error("The union type LENGTHTO field must contain only "
2240 "integer fields");
2241 }
2242 break;
2243 case T_ANYTYPE:
2244 case T_OPENTYPE:
2245 case T_SEQ_A:
2246 case T_SEQ_T:
2247 case T_SET_A:
2248 case T_SET_T:
2249 if (rawpar->lengthindex) break; // Will be checked in the next step.
2250 // Else continue with default.
2251 default:
2252 error("The LENGTHTO field must be an integer or union type "
2253 "instead of `%s'", ft->get_typename().c_str());
2254 break;
2255 }
2256 }
2257 if(rawpar->lengthto_num && rawpar->lengthindex){ // LENGTHINDEX
2258 Identifier *idf=rawpar->lengthindex->names[0];
2259 if(!field_type_last->is_secho()){
2260 error("Invalid fieldmember type in RAW parameter LENGTHINDEX"
2261 " for field %s."
2262 ,field_id.get_dispname().c_str());
2263 break;
2264 }
2265 if(!field_type_last->has_comp_withName(*idf))
2266 error("Invalid fieldname in RAW parameter"
2267 " LENGTHINDEX for field %s: %s"
2268 ,field_id.get_dispname().c_str()
2269 ,rawpar->lengthindex->names[0]->get_dispname().c_str());
2270 }
2271 if(rawpar->pointerto){ // POINTERTO
2272 Identifier *idf=rawpar->pointerto;
2273 bool hiba=false;
2274 size_t pointed=0;
2275 if(!has_comp_withName(*idf)){
2276 error("Invalid fieldname in RAW"
2277 " parameter POINTERTO for field %s: %s"
2278 ,field_id.get_dispname().c_str()
2279 ,rawpar->pointerto->get_dispname().c_str());
2280 hiba=true;
2281 }
2282 if(!hiba && (pointed=get_comp_index_byName(*idf))<=i){
2283 error("Pointer must precede the pointed field. Incorrect field "
2284 "name `%s' in RAW parameter POINTERTO for field `%s'",
2285 rawpar->pointerto->get_dispname().c_str(),
2286 field_id.get_dispname().c_str());
2287 hiba=true;
2288 }
2289 if(!hiba && rawpar->ptrbase){ // POINTERTO
2290 Identifier *idf2=rawpar->ptrbase;
2291 if(!has_comp_withName(*idf2)){
2292 error("Invalid field name `%s' in RAW parameter PTROFFSET for "
2293 "field `%s'", rawpar->ptrbase->get_dispname().c_str(),
2294 field_id.get_dispname().c_str());
2295 hiba=true;
2296 }
2297 if(!hiba && get_comp_index_byName(*idf2)>pointed){
2298 error("Pointer base must precede the pointed field. Incorrect "
2299 "field name `%s' in RAW parameter PTROFFSET for field "
2300 "`%s'", rawpar->ptrbase->get_dispname().c_str(),
2301 field_id.get_dispname().c_str());
2302 }
2303 }
2304 }
2305 for(int a=0;a<rawpar->presence.nElements;a++){ //PRESENCE
2306 Type *t=this;
2307 bool hiba=false;
2308 for(int b=0;b<rawpar->presence.keyList[a].keyField->nElements;b++){
2309 Identifier *idf=rawpar->presence.keyList[a].keyField->names[b];
2310 if(!t->is_secho()){
2311 error("Invalid fieldmember type in RAW parameter PRESENCE"
2312 " for field %s."
2313 ,field_id.get_dispname().c_str());
2314 hiba=true;
2315 break;
2316 }
2317 if(!t->has_comp_withName(*idf)){
2318 error("Invalid fieldname `%s' in RAW parameter PRESENCE for "
2319 "field `%s'", rawpar->presence.keyList[a].keyField
2320 ->names[b]->get_dispname().c_str(),
2321 field_id.get_dispname().c_str());
2322 hiba=true;
2323 break;
2324 }
2325 if(b==0 && !(get_comp_index_byName(*rawpar->presence.keyList[a]
2326 .keyField->names[0])<i)){
2327 error("The PRESENCE field `%s' must precede the optional field "
2328 "in RAW parameter PRESENCE for field `%s'"
2329 ,rawpar->presence.keyList[a].keyField->names[0]
2330 ->get_dispname().c_str()
2331 ,field_id.get_dispname().c_str());
2332 hiba=true;
2333 break;
2334 }
2335 t=t->get_comp_byName(*idf)->get_type()->get_type_refd_last();
2336 }
2337 if(!hiba){
2338 Error_Context cntx(this, "In Raw parmeter PRESENCE");
2339 Value *v = rawpar->presence.keyList[a].v_value;
2340 v->set_my_scope(get_my_scope());
2341 v->set_my_governor(t);
2342 t->chk_this_value_ref(v);
2343 self_ref = t->chk_this_value(v, 0, EXPECTED_CONSTANT,
2344 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
2345 Value::valuetype_t vt = v->get_valuetype();
2346 if (vt == Value::V_ENUM || vt == Value::V_REFD) {
2347 Free(rawpar->presence.keyList[a].value);
2348 rawpar->presence.keyList[a].value =
2349 mcopystr(v->get_single_expr().c_str());
2350 }
2351 }
2352 }
2353 for(int c=0;c<rawpar->crosstaglist.nElements;c++) { // CROSSTAG
2354 Identifier *idf=rawpar->crosstaglist.tag[c].fieldName;
2355 if(!field_type_last->is_secho()){
2356 error("Invalid fieldmember type in RAW parameter CROSSTAG"
2357 " for field %s."
2358 ,field_id.get_dispname().c_str());
2359 break;
2360 }
2361 if(!field_type_last->has_comp_withName(*idf)){
2362 error("Invalid fieldmember name in RAW parameter CROSSTAG"
2363 " for field %s: %s"
2364 ,field_id.get_dispname().c_str()
2365 ,rawpar->crosstaglist.tag[c].fieldName
2366 ->get_dispname().c_str());
2367 break;
2368 }
2369 for(int a=0;a<rawpar->crosstaglist.tag[c].nElements;a++){
2370 Type *t2=this;
2371 bool hiba=false;
2372 bool allow_omit = false;
2373 for(int b=0;
2374 b<rawpar->crosstaglist.tag[c].keyList[a].keyField->nElements;b++){
2375 Identifier *idf2=
2376 rawpar->crosstaglist.tag[c].keyList[a].keyField->names[b];
2377 if(!t2->is_secho()){
2378 error("Invalid fieldmember type in RAW parameter CROSSTAG"
2379 " for field %s."
2380 ,field_id.get_dispname().c_str());
2381 hiba=true;
2382 break;
2383 }
2384 if(!t2->has_comp_withName(*idf2)){
2385 error("Invalid fieldname in RAW parameter CROSSTAG"
2386 " for field %s: %s"
2387 ,field_id.get_dispname().c_str()
2388 ,idf2->get_dispname().c_str());
2389 hiba=true;
2390 break;
2391 }
2392 if (b == 0) {
2393 size_t field_idx = get_comp_index_byName(*idf2);
2394 if (field_idx == i) {
2395 error("RAW parameter CROSSTAG for field `%s' cannot refer "
2396 "to the field itself", idf2->get_dispname().c_str());
2397 } else if (field_idx > i) {
2398 if (cf->get_is_optional() ||
2399 field_type->get_raw_length() < 0)
2400 error("Field `%s' that CROSSTAG refers to must precede "
2401 "field `%s' or field `%s' must be mandatory with "
2402 "fixed length", idf2->get_dispname().c_str(),
2403 field_id.get_dispname().c_str(),
2404 field_id.get_dispname().c_str());
2405 }
2406 }
2407 CompField *cf2=t2->get_comp_byName(*idf2);
2408 t2=cf2->get_type()->get_type_refd_last();
2409 if (b == rawpar->crosstaglist.tag[c].keyList[a].keyField
2410 ->nElements - 1 && cf2->get_is_optional())
2411 allow_omit = true;
2412 }
2413 if(!hiba){
2414 Error_Context cntx(this, "In Raw parmeter CROSSTAG");
2415 Value *v = rawpar->crosstaglist.tag[c].keyList[a].v_value;
2416 v->set_my_scope(get_my_scope());
2417 v->set_my_governor(t2);
2418 t2->chk_this_value_ref(v);
2419 self_ref = t2->chk_this_value(v, 0, EXPECTED_CONSTANT,
2420 INCOMPLETE_NOT_ALLOWED,
2421 (allow_omit ? OMIT_ALLOWED : OMIT_NOT_ALLOWED), SUB_CHK);
2422 Value::valuetype_t vt = v->get_valuetype();
2423 if (vt == Value::V_ENUM || vt == Value::V_REFD) {
2424 Free(rawpar->crosstaglist.tag[c].keyList[a].value);
2425 rawpar->crosstaglist.tag[c].keyList[a].value =
2426 mcopystr(v->get_single_expr().c_str());
2427 }
2428 }
2429 }
2430 }
2431 }
2432 }
2433 break; }
2434 case T_BSTR:
2435 if(rawattrib->fieldlength==0 && rawattrib->length_restrition!=-1){
2436 rawattrib->fieldlength=rawattrib->length_restrition;
2437 rawattrib->length_restrition=-1;
2438 }
2439 break;
2440 case T_HSTR:
2441 if(rawattrib->fieldlength==0 && rawattrib->length_restrition!=-1){
2442 rawattrib->fieldlength=rawattrib->length_restrition*4;
2443 rawattrib->length_restrition=-1;
2444 }
2445 break;
2446 case T_OSTR:
2447 if(rawattrib->fieldlength==0 && rawattrib->length_restrition!=-1){
2448 rawattrib->fieldlength=rawattrib->length_restrition*8;
2449 rawattrib->length_restrition=-1;
2450 }
2451 break;
2452 case T_CSTR:
2453 if(rawattrib->fieldlength==0 && rawattrib->length_restrition!=-1){
2454 rawattrib->fieldlength=rawattrib->length_restrition*8;
2455 rawattrib->length_restrition=-1;
2456 }
2457 break;
2458 case T_SEQOF:
2459 case T_SETOF:
2460 get_ofType()->force_raw();
2461 if(rawattrib->fieldlength==0 && rawattrib->length_restrition!=-1){
2462 rawattrib->fieldlength=rawattrib->length_restrition;
2463 rawattrib->length_restrition=-1;
2464 }
2465 if(rawattrib->length_restrition!=-1 &&
2466 rawattrib->length_restrition!=rawattrib->fieldlength){
2467 error("Invalid length specified in parameter FIELDLENGTH for %s of "
2468 "type `%s'. The FIELDLENGTH must be equal to specified length "
2469 "restriction", typetype == T_SEQOF ? "record" : "set",
2470 get_fullname().c_str());
2471 }
2472 break;
2473 case T_REAL:
2474 if(rawattrib->fieldlength!=64 && rawattrib->fieldlength!=32){
2475 error("Invalid length (%d) specified in parameter FIELDLENGTH for "
2476 "float type `%s'. The FIELDLENGTH must be single (32) or double "
2477 "(64)", rawattrib->fieldlength, get_fullname().c_str());
2478 }
2479 break;
2480 case T_INT:
2481 if (rawattrib->intx) {
2482 rawattrib->bitorderinfield = XDEFMSB;
2483 rawattrib->bitorderinoctet = XDEFMSB;
2484 rawattrib->byteorder = XDEFMSB;
2485 }
2486 break;
2487 case T_ENUM_T:
2488 case T_BOOL:
2489 default:
2490 // nothing to do, ASN1 types or types without defined raw attribute
2491 break;
2492 } // switch
2493
2494 (void)self_ref;
2495 }
2496
2497 void Type::force_raw()
2498 {
2499 if (!rawattrib)
2500 {
2501 switch (typetype) {
2502 case T_SEQOF:
2503 case T_SETOF:
2504 case T_CHOICE_T:
2505 // TODO case T_ANYTYPE: for force_raw ?
2506 case T_ENUM_T:
2507 case T_SEQ_T:
2508 case T_SET_T:
2509 rawattrib = new RawAST(false);
2510 break;
2511 default:
2512 if (is_ref()) get_type_refd()->force_raw();
2513 break;
2514 }
2515 }
2516
2517 // Don't run chk_raw() on unchecked types
2518 if (chk_finished)
2519 chk_raw();
2520 }
2521
2522 void Type::chk_text()
2523 {
2524 if (text_checked) return;
2525 text_checked = true;
2526 if (!textattrib || !enable_text()) return;
2527 //textattrib->print_TextAST();
2528
2529 chk_text_matching_values(textattrib->begin_val, "BEGIN");
2530 chk_text_matching_values(textattrib->end_val, "END");
2531 chk_text_matching_values(textattrib->separator_val, "SEPARATOR");
2532
2533 switch (typetype) {
2534 case T_ANYTYPE:
2535 case T_CHOICE_T:
2536 case T_SEQ_T:
2537 case T_SET_T: {
2538 size_t nof_comps = get_nof_comps();
2539 for (size_t i = 0; i < nof_comps; i++)
2540 get_comp_byIndex(i)->get_type()->force_text();
2541 break; }
2542 case T_SEQOF:
2543 case T_SETOF:
2544 get_ofType()->force_text();
2545 break;
2546 default:
2547 if (is_ref()) get_type_refd()->force_text();
2548 break;
2549 }
2550
2551 switch (get_type_refd_last()->typetype) {
2552 case T_BOOL:
2553 chk_text_matching_values(textattrib->true_params, "true value");
2554 chk_text_matching_values(textattrib->false_params, "false value");
2555 break;
2556 case T_ENUM_T:
2557 if(textattrib->nof_field_params){
2558 Type *t=get_type_refd_last();
2559 size_t nof_comps = t->u.enums.eis->get_nof_eis();
2560 textAST_enum_def **params=(textAST_enum_def**)
2561 Malloc(nof_comps*sizeof(textAST_enum_def*));
2562 memset(params,0,nof_comps*sizeof(textAST_enum_def*));
2563 for (int a = 0; a < textattrib->nof_field_params; a++) {
2564 const Identifier& id = *textattrib->field_params[a]->name;
2565 if (t->u.enums.eis->has_ei_withName(id)) {
2566 int index = t->get_eis_index_byName(id);
2567 if (params[index]) FATAL_ERROR("Type::chk_text(): duplicate " \
2568 "attribute for enum `%s'", id.get_dispname().c_str());
2569 params[index] = textattrib->field_params[a];
2570 char *attrib_name = mprintf("enumerated value `%s'",
2571 id.get_dispname().c_str());
2572 chk_text_matching_values(&params[index]->value, attrib_name);
2573 Free(attrib_name);
2574 } else {
2575 error("Coding attribute refers to non-existent enumerated value "
2576 "`%s'", id.get_dispname().c_str());
2577 Free(textattrib->field_params[a]->value.encode_token);
2578 Free(textattrib->field_params[a]->value.decode_token);
2579 delete textattrib->field_params[a]->name;
2580 Free(textattrib->field_params[a]);
2581 }
2582 }
2583 Free(textattrib->field_params);
2584 textattrib->field_params=params;
2585 textattrib->nof_field_params=nof_comps;
2586 }
2587 break;
2588 case T_OSTR:
2589 case T_CSTR:
2590 case T_INT:
2591 if (textattrib->decode_token) {
2592 char *tmp = textattrib->decode_token;
2593 textattrib->decode_token = process_decode_token(tmp, *this);
2594 Free(tmp);
2595 tmp = TTCN_pattern_to_regexp(textattrib->decode_token);
2596 if (tmp) Free(tmp);
2597 else {
2598 error("Incorrect select token expression: `%s'",
2599 textattrib->decode_token);
2600 }
2601 }
2602 break;
2603 default:
2604 break;
2605 }
2606 //textattrib->print_TextAST();
2607 }
2608
2609 void Type::chk_text_matching_values(textAST_matching_values *matching_values,
2610 const char *attrib_name)
2611 {
2612 if (!matching_values) return;
2613 if (matching_values->decode_token) {
2614 // check whether decode token is a correct TTCN-3 pattern
2615 char *tmp = matching_values->decode_token;
2616 matching_values->decode_token = process_decode_token(tmp, *this);
2617 Free(tmp);
2618 tmp = TTCN_pattern_to_regexp(matching_values->decode_token);
2619 if (tmp) Free(tmp);
2620 else {
2621 error("Incorrect matching expression for %s: `%s'", attrib_name,
2622 matching_values->decode_token);
2623 }
2624 } else if (matching_values->encode_token) {
2625 // the decode token is not present, but there is an encode token
2626 // derive the decode token from the encode token
2627 matching_values->generated_decode_token = true;
2628 matching_values->decode_token =
2629 convert_charstring_to_pattern(matching_values->encode_token);
2630 }
2631 }
2632
2633 void Type::force_text()
2634 {
2635 if (!textattrib)
2636 {
2637 switch (typetype) {
2638 case T_SEQOF:
2639 case T_SETOF:
2640 case T_CHOICE_T:
2641 // TODO case T_ANYTYPE: for force_text ?
2642 case T_ENUM_T:
2643 case T_SEQ_T:
2644 case T_SET_T:
2645 textattrib = new TextAST;
2646 break;
2647 default:
2648 if (is_ref()) get_type_refd()->force_text();
2649 break;
2650 }
2651 }
2652 if (chk_finished)
2653 chk_text();
2654 }
2655
2656 static const char* JSON_SCHEMA_KEYWORDS[] = {
2657 // built-in JSON schema keywords
2658 "$ref", "type", "properties", "items", "anyOf", "enum", "pattern",
2659 "default", "minItems", "maxItems", "additionalProperties", "fieldOrder",
2660 "required", "$schema", "minLength", "maxLength", "minimum", "maximum",
2661 "excludeMinimum", "excludeMaximum", "allOf"
2662 // TITAN-specific keywords
2663 "originalName", "unusedAlias", "subType", "numericValues", "omitAsNull",
2664 "encoding", "decoding", "valueList"
2665 };
2666
2667 void Type::chk_json()
2668 {
2669 if (json_checked) return;
2670 json_checked = true;
2671 if ((NULL == jsonattrib && !hasEncodeAttr(get_encoding_name(CT_JSON))) || !enable_json()) return;
2672
2673 switch (typetype) {
2674 case T_ANYTYPE:
2675 case T_CHOICE_T:
2676 case T_CHOICE_A:
2677 case T_SEQ_T:
2678 case T_SEQ_A:
2679 case T_SET_T:
2680 case T_SET_A: {
2681 size_t nof_comps = get_nof_comps();
2682 for (size_t i = 0; i < nof_comps; i++)
2683 get_comp_byIndex(i)->get_type()->force_json();
2684 break; }
2685 case T_SEQOF:
2686 case T_SETOF:
2687 case T_ARRAY:
2688 get_ofType()->force_json();
2689 break;
2690 default:
2691 if (is_ref()) get_type_refd()->force_json();
2692 break;
2693 }
2694
2695 if (NULL != jsonattrib) {
2696 if (jsonattrib->omit_as_null && !is_optional_field()) {
2697 error("Invalid attribute, 'omit as null' requires optional "
2698 "field of a record or set.");
2699 }
2700
2701 if (jsonattrib->as_value && T_CHOICE_T != get_type_refd_last()->typetype) {
2702 error("Invalid attribute, 'as value' is only allowed for unions");
2703 }
2704
2705 if (NULL != jsonattrib->alias) {
2706 Type* parent = get_parent_type();
2707 if (NULL == parent || (T_SEQ_T != parent->typetype &&
2708 T_SET_T != parent->typetype && T_CHOICE_T != parent->typetype)) {
2709 error("Invalid attribute, 'name as ...' requires field of a "
2710 "record, set or union.");
2711 }
2712 if (NULL != parent && NULL != parent->jsonattrib &&
2713 T_CHOICE_T == parent->typetype && parent->jsonattrib->as_value) {
2714 warning("Attribute 'name as ...' will be ignored, because parent union "
2715 "is encoded without field names.");
2716 }
2717 }
2718
2719 if (NULL != jsonattrib->default_value) {
2720 chk_json_default();
2721 }
2722
2723 const size_t nof_extensions = jsonattrib->schema_extensions.size();
2724 if (0 != nof_extensions) {
2725 const size_t nof_keywords = sizeof(JSON_SCHEMA_KEYWORDS) / sizeof(char*);
2726
2727 // these keep track of erroneous extensions so each warning is only
2728 // displayed once
2729 char* checked_extensions = new char[nof_extensions];
2730 char* checked_keywords = new char[nof_keywords];
2731 memset(checked_extensions, 0, nof_extensions);
2732 memset(checked_keywords, 0, nof_keywords);
2733
2734 for (size_t i = 0; i < nof_extensions; ++i) {
2735 for (size_t j = 0; j < nof_keywords; ++j) {
2736 if (0 == checked_extensions[i] && 0 == checked_keywords[j] &&
2737 0 == strcmp(jsonattrib->schema_extensions[i]->key,
2738 JSON_SCHEMA_KEYWORDS[j])) {
2739 // only report the warning once for each keyword
2740 warning("JSON schema keyword '%s' should not be used as the key of "
2741 "attribute 'extend'", JSON_SCHEMA_KEYWORDS[j]);
2742 checked_keywords[j] = 1;
2743 checked_extensions[i] = 1;
2744 break;
2745 }
2746 }
2747 if (0 == checked_extensions[i]) {
2748 for (size_t k = i + 1; k < nof_extensions; ++k) {
2749 if (0 == strcmp(jsonattrib->schema_extensions[i]->key,
2750 jsonattrib->schema_extensions[k]->key)) {
2751 if (0 == checked_extensions[i]) {
2752 // only report the warning once for each unique key
2753 warning("Key '%s' is used multiple times in 'extend' attributes "
2754 "of type '%s'", jsonattrib->schema_extensions[i]->key,
2755 get_typename().c_str());
2756 checked_extensions[i] = 1;
2757 }
2758 checked_extensions[k] = 1;
2759 }
2760 }
2761 }
2762 }
2763 delete[] checked_extensions;
2764 delete[] checked_keywords;
2765 }
2766 if (jsonattrib->metainfo_unbound) {
2767 Type* parent = get_parent_type();
2768 if (T_SEQ_T == get_type_refd_last()->typetype ||
2769 T_SET_T == get_type_refd_last()->typetype) {
2770 // if it's set for the record/set, pass it onto its fields
2771 size_t nof_comps = get_nof_comps();
2772 for (size_t i = 0; i < nof_comps; i++) {
2773 Type* comp_type = get_comp_byIndex(i)->get_type();
2774 if (NULL == comp_type->jsonattrib) {
2775 comp_type->jsonattrib = new JsonAST;
2776 }
2777 comp_type->jsonattrib->metainfo_unbound = true;
2778 }
2779 }
2780 else if (NULL == parent || (T_SEQ_T != parent->typetype &&
2781 T_SET_T != parent->typetype)) {
2782 // only allowed if it's a field of a record/set
2783 error("Invalid attribute 'metainfo for unbound', requires record, set, "
2784 "or field of a record or set");
2785 }
2786 }
2787 }
2788 }
2789
2790 void Type::chk_json_default()
2791 {
2792 const char* dval = jsonattrib->default_value;
2793 const size_t dval_len = strlen(dval);
2794 Type *last = get_type_refd_last();
2795 bool err = false;
2796 switch (last->typetype) {
2797 case T_BOOL:
2798 if (strcmp(dval, "true") != 0 && strcmp(dval, "false") != 0) {
2799 err = true;
2800 }
2801 break;
2802 case T_INT:
2803 for (size_t i = (dval[0] == '-') ? 1 : 0; i < dval_len; ++i) {
2804 if (dval[i] < '0' || dval[i] > '9') {
2805 err = true;
2806 break; // from the loop
2807 }
2808 }
2809 break;
2810 case T_REAL: {
2811 if (strcmp(dval, "infinity") == 0 || strcmp(dval, "-infinity") == 0 ||
2812 strcmp(dval, "not_a_number") == 0) {
2813 // special float values => skip the rest of the check
2814 break;
2815 }
2816
2817 boolean first_digit = false; // first non-zero digit reached
2818 boolean zero = false; // first zero digit reached
2819 boolean decimal_point = false; // decimal point (.) reached
2820 boolean exponent_mark = false; // exponential mark (e or E) reached
2821 boolean exponent_sign = false; // sign of the exponential (- or +) reached
2822
2823 size_t i = (dval[0] == '-') ? 1 : 0;
2824 while(!err && i < dval_len) {
2825 switch (dval[i]) {
2826 case '.':
2827 if (decimal_point || exponent_mark || (!first_digit && !zero)) {
2828 err = true;
2829 }
2830 decimal_point = true;
2831 first_digit = false;
2832 zero = false;
2833 break;
2834 case 'e':
2835 case 'E':
2836 if (exponent_mark || (!first_digit && !zero)) {
2837 err = true;
2838 }
2839 exponent_mark = true;
2840 first_digit = false;
2841 zero = false;
2842 break;
2843 case '0':
2844 if (!first_digit && (exponent_mark || (!decimal_point && zero))) {
2845 err = true;
2846 }
2847 zero = true;
2848 break;
2849 case '1':
2850 case '2':
2851 case '3':
2852 case '4':
2853 case '5':
2854 case '6':
2855 case '7':
2856 case '8':
2857 case '9':
2858 if (!first_digit && zero && (!decimal_point || exponent_mark)) {
2859 err = true;
2860 }
2861 first_digit = true;
2862 break;
2863 case '-':
2864 case '+':
2865 if (exponent_sign || !exponent_mark || zero || first_digit) {
2866 err = true;
2867 }
2868 exponent_sign = true;
2869 break;
2870 default:
2871 err = true;
2872 }
2873 ++i;
2874 }
2875 err = !first_digit && !zero;
2876 break; }
2877 case T_BSTR:
2878 for (size_t i = 0; i < dval_len; ++i) {
2879 if (dval[i] < '0' || dval[i] > '1') {
2880 err = true;
2881 break; // from the loop
2882 }
2883 }
2884 break;
2885 case T_OSTR:
2886 if (dval_len % 2 != 0) {
2887 err = true;
2888 break;
2889 }
2890 // no break
2891 case T_HSTR:
2892 for (size_t i = 0; i < dval_len; ++i) {
2893 if ((dval[i] < '0' || dval[i] > '9') && (dval[i] < 'a' || dval[i] > 'f') &&
2894 (dval[i] < 'A' || dval[i] > 'F')) {
2895 err = true;
2896 break; // from the loop
2897 }
2898 }
2899 break;
2900 case T_CSTR:
2901 case T_USTR: {
2902 size_t i = 0;
2903 while(!err && i < dval_len) {
2904 if (dval[i] < 0 && last->typetype == T_CSTR) {
2905 err = true;
2906 }
2907 else if (dval[i] == '\\') {
2908 if (i == dval_len - 1) {
2909 err = true;
2910 } else {
2911 ++i;
2912 switch (dval[i]) {
2913 case '\\':
2914 case '\"':
2915 case 'n':
2916 case 't':
2917 case 'r':
2918 case 'f':
2919 case 'b':
2920 case '/':
2921 break; // these are OK
2922 case 'u': {
2923 if (i + 4 >= dval_len) {
2924 err = true;
2925 } else if (last->typetype == T_CSTR &&
2926 (dval[i + 1] != '0' || dval[i + 2] != '0' ||
2927 dval[i + 3] < '0' || dval[i + 3] > '7')) {
2928 err = true;
2929 } else {
2930 for (size_t j = (last->typetype == T_CSTR) ? 4 : 1; j <= 4; ++j) {
2931 if ((dval[i + j] < '0' || dval[i + j] > '9') &&
2932 (dval[i + j] < 'a' || dval[i + j] > 'f') &&
2933 (dval[i + j] < 'A' || dval[i + j] > 'F')) {
2934 err = true;
2935 break; // from the loop
2936 }
2937 }
2938 }
2939 i += 4;
2940 break; }
2941 default:
2942 err = true;
2943 break;
2944 }
2945 }
2946 }
2947 ++i;
2948 }
2949 break; }
2950 case T_ENUM_T: {
2951 Common::Identifier id(Identifier::ID_TTCN, string(dval));
2952 if (!last->has_ei_withName(id)) {
2953 err = true;
2954 }
2955 break; }
2956 case T_VERDICT:
2957 if (strcmp(dval, "none") != 0 && strcmp(dval, "pass") != 0 &&
2958 strcmp(dval, "inconc") != 0 && strcmp(dval, "fail") != 0 &&
2959 strcmp(dval, "error") != 0) {
2960 err = true;
2961 }
2962 break;
2963 default:
2964 error("JSON default values are not available for type `%s'",
2965 last->get_stringRepr().c_str());
2966 return;
2967 }
2968
2969 if (err) {
2970 if (last->typetype == T_ENUM_T) {
2971 error("Invalid JSON default value for enumerated type `%s'",
2972 last->get_stringRepr().c_str());
2973 } else {
2974 error("Invalid %s JSON default value", get_typename_builtin(last->typetype));
2975 }
2976 }
2977 }
2978
2979 void Type::force_json()
2980 {
2981 if (!jsonattrib)
2982 {
2983 switch (typetype) {
2984 case T_SEQOF:
2985 case T_SETOF:
2986 case T_CHOICE_T:
2987 case T_CHOICE_A:
2988 case T_ENUM_T:
2989 case T_ENUM_A:
2990 case T_SEQ_T:
2991 case T_SEQ_A:
2992 case T_SET_T:
2993 case T_SET_A:
2994 jsonattrib = new JsonAST;
2995 break;
2996 default:
2997 if (is_ref()) get_type_refd()->force_json();
2998 break;
2999 }
3000 }
3001 if (chk_finished)
3002 chk_json();
3003 }
3004
3005
3006 int Type::get_length_multiplier()
3007 {
3008 switch(typetype) {
3009 case T_REFD:
3010 return get_type_refd()->get_length_multiplier();
3011 break;
3012 case T_HSTR:
3013 return 4;
3014 break;
3015 case T_OSTR:
3016 case T_CSTR:
3017 return 8;
3018 default:
3019 return 1;
3020 break;
3021 }
3022 return 1;
3023 }
3024
3025 /** \todo review, especially the string types... */
3026 bool Type::is_compatible_tt_tt(typetype_t p_tt1, typetype_t p_tt2,
3027 bool p_is_asn11, bool p_is_asn12)
3028 {
3029 if (p_tt2 == T_ERROR) return true;
3030 switch (p_tt1) {
3031 // error type is compatible with everything
3032 case T_ERROR:
3033 return true;
3034 // unambiguous built-in types
3035 case T_NULL:
3036 case T_BOOL:
3037 case T_REAL:
3038 case T_HSTR:
3039 case T_SEQOF:
3040 case T_SETOF:
3041 case T_VERDICT:
3042 case T_DEFAULT:
3043 case T_COMPONENT:
3044 case T_SIGNATURE:
3045 case T_PORT:
3046 case T_ARRAY:
3047 case T_FUNCTION:
3048 case T_ALTSTEP:
3049 case T_TESTCASE:
3050 return p_tt1 == p_tt2;
3051 case T_OSTR:
3052 return p_tt2==T_OSTR || (!p_is_asn11 && p_tt2==T_ANY);
3053 case T_USTR:
3054 switch (p_tt2) {
3055 case T_USTR:
3056 case T_UTF8STRING:
3057 case T_BMPSTRING:
3058 case T_UNIVERSALSTRING:
3059 case T_TELETEXSTRING:
3060 case T_VIDEOTEXSTRING:
3061 case T_GRAPHICSTRING:
3062 case T_OBJECTDESCRIPTOR:
3063 case T_GENERALSTRING:
3064 case T_CSTR:
3065 case T_NUMERICSTRING:
3066 case T_PRINTABLESTRING:
3067 case T_IA5STRING:
3068 case T_VISIBLESTRING:
3069 case T_UTCTIME:
3070 case T_GENERALIZEDTIME:
3071 return true;
3072 default:
3073 return false;
3074 }
3075 // character string group 1
3076 case T_UTF8STRING:
3077 case T_BMPSTRING:
3078 case T_UNIVERSALSTRING:
3079 switch (p_tt2) {
3080 case T_USTR:
3081 case T_UTF8STRING:
3082 case T_BMPSTRING:
3083 case T_UNIVERSALSTRING:
3084 case T_CSTR:
3085 case T_NUMERICSTRING:
3086 case T_PRINTABLESTRING:
3087 case T_IA5STRING:
3088 case T_VISIBLESTRING:
3089 case T_UTCTIME:
3090 case T_GENERALIZEDTIME:
3091 return true;
3092 default:
3093 return false;
3094 }
3095 // character string group 2
3096 case T_TELETEXSTRING:
3097 case T_VIDEOTEXSTRING:
3098 case T_GRAPHICSTRING:
3099 case T_OBJECTDESCRIPTOR:
3100 case T_GENERALSTRING:
3101 switch (p_tt2) {
3102 case T_TELETEXSTRING:
3103 case T_VIDEOTEXSTRING:
3104 case T_GRAPHICSTRING:
3105 case T_OBJECTDESCRIPTOR:
3106 case T_GENERALSTRING:
3107 case T_CSTR:
3108 case T_NUMERICSTRING:
3109 case T_PRINTABLESTRING:
3110 case T_IA5STRING:
3111 case T_VISIBLESTRING:
3112 case T_UTCTIME:
3113 case T_GENERALIZEDTIME:
3114 return true;
3115 case T_USTR:
3116 // maybe :) is ustr.is_cstr()
3117 return true;
3118 default:
3119 return false;
3120 }
3121 // character string group 3
3122 case T_CSTR:
3123 case T_NUMERICSTRING:
3124 case T_PRINTABLESTRING:
3125 case T_IA5STRING:
3126 case T_VISIBLESTRING:
3127 case T_UTCTIME:
3128 case T_GENERALIZEDTIME:
3129 switch (p_tt2) {
3130 case T_CSTR:
3131 case T_NUMERICSTRING:
3132 case T_PRINTABLESTRING:
3133 case T_IA5STRING:
3134 case T_VISIBLESTRING:
3135 case T_UTCTIME:
3136 case T_GENERALIZEDTIME:
3137 return true;
3138 default:
3139 return false;
3140 }
3141 // polymorphic built-in types
3142 case T_BSTR:
3143 case T_BSTR_A:
3144 return p_tt2 == T_BSTR || p_tt2 == T_BSTR_A;
3145 case T_INT:
3146 case T_INT_A:
3147 return p_tt2 == T_INT || p_tt2 == T_INT_A;
3148 // ROID is visible as OID from TTCN-3
3149 case T_OID:
3150 return p_tt2 == T_OID ||
3151 (!p_is_asn11 && p_tt2 == T_ROID);
3152 case T_ROID:
3153 return p_tt2 == T_ROID ||
3154 (!p_is_asn12 && p_tt2 == T_OID);
3155 case T_ENUM_A:
3156 case T_ENUM_T:
3157 return p_tt2==T_ENUM_A || p_tt2==T_ENUM_T;
3158 case T_CHOICE_T:
3159 case T_CHOICE_A:
3160 case T_OPENTYPE:
3161 return p_tt2==T_CHOICE_T || p_tt2==T_CHOICE_A || p_tt2==T_OPENTYPE;
3162 case T_SEQ_A:
3163 case T_SEQ_T:
3164 return p_tt2==T_SEQ_A || p_tt2==T_SEQ_T;
3165 case T_SET_A:
3166 case T_SET_T:
3167 return p_tt2==T_SET_A || p_tt2==T_SET_T;
3168 case T_ANY:
3169 return p_tt2 == T_ANY || p_tt2 == T_OSTR;
3170 // these should never appear?
3171 case T_REFD:
3172 case T_REFDSPEC:
3173 case T_OCFT:
3174 case T_ADDRESS:
3175 return false;
3176 default:
3177 FATAL_ERROR("Type::is_compatible_tt_tt()");
3178 return false;
3179 }
3180 }
3181
3182 bool Type::is_compatible_tt(typetype_t p_tt, bool p_is_asn1)
3183 {
3184 chk();
3185 Type *t1=get_type_refd_last();
3186 if (p_tt == T_ERROR) return true;
3187 switch (t1->typetype) {
3188 // these should never appear
3189 case T_REFD:
3190 case T_REFDSPEC:
3191 case T_OCFT:
3192 case T_ADDRESS:
3193 FATAL_ERROR("Type::is_compatible_tt()");
3194 return false;
3195 default:
3196 return is_compatible_tt_tt(t1->typetype, p_tt, is_asn1(), p_is_asn1);
3197 }
3198 }
3199
3200 bool Type::is_compatible(Type *p_type, TypeCompatInfo *p_info,
3201 TypeChain *p_left_chain, TypeChain *p_right_chain,
3202 bool p_is_inline_template)
3203 {
3204 chk();
3205 p_type->chk();
3206 Type *t1 = get_type_refd_last();
3207 Type *t2 = p_type->get_type_refd_last();
3208 // Error type is compatible with everything.
3209 if (t1->typetype == T_ERROR || t2->typetype == T_ERROR) return true;
3210 bool is_type_comp;
3211 switch (t1->typetype) {
3212 // Unambiguous built-in types.
3213 case T_NULL:
3214 case T_BOOL:
3215 case T_REAL:
3216 case T_HSTR:
3217 case T_VERDICT:
3218 case T_DEFAULT:
3219 is_type_comp = (t1->typetype == t2->typetype);
3220 break;
3221 case T_OSTR:
3222 is_type_comp = ( t2->typetype==T_OSTR || (!is_asn1() && t2->typetype==T_ANY) );
3223 break;
3224 case T_USTR:
3225 switch (t2->typetype) {
3226 case T_USTR:
3227 case T_UTF8STRING:
3228 case T_BMPSTRING:
3229 case T_UNIVERSALSTRING:
3230 case T_TELETEXSTRING:
3231 case T_VIDEOTEXSTRING:
3232 case T_GRAPHICSTRING:
3233 case T_OBJECTDESCRIPTOR:
3234 case T_GENERALSTRING:
3235 case T_CSTR:
3236 case T_NUMERICSTRING:
3237 case T_PRINTABLESTRING:
3238 case T_IA5STRING:
3239 case T_VISIBLESTRING:
3240 case T_UTCTIME:
3241 case T_GENERALIZEDTIME:
3242 is_type_comp = true;
3243 break;
3244 default:
3245 is_type_comp = false;
3246 break;
3247 }
3248 break;
3249 // Character string group 1.
3250 case T_UTF8STRING:
3251 case T_BMPSTRING:
3252 case T_UNIVERSALSTRING:
3253 switch (t2->typetype) {
3254 case T_USTR:
3255 case T_UTF8STRING:
3256 case T_BMPSTRING:
3257 case T_UNIVERSALSTRING:
3258 case T_CSTR:
3259 case T_NUMERICSTRING:
3260 case T_PRINTABLESTRING:
3261 case T_IA5STRING:
3262 case T_VISIBLESTRING:
3263 case T_UTCTIME:
3264 case T_GENERALIZEDTIME:
3265 is_type_comp = true;
3266 break;
3267 default:
3268 is_type_comp = false;
3269 break;
3270 }
3271 break;
3272 // Character string group 2.
3273 case T_TELETEXSTRING:
3274 case T_VIDEOTEXSTRING:
3275 case T_GRAPHICSTRING:
3276 case T_OBJECTDESCRIPTOR:
3277 case T_GENERALSTRING:
3278 switch (t2->typetype) {
3279 case T_TELETEXSTRING:
3280 case T_VIDEOTEXSTRING:
3281 case T_GRAPHICSTRING:
3282 case T_OBJECTDESCRIPTOR:
3283 case T_GENERALSTRING:
3284 case T_CSTR:
3285 case T_NUMERICSTRING:
3286 case T_PRINTABLESTRING:
3287 case T_IA5STRING:
3288 case T_VISIBLESTRING:
3289 case T_UTCTIME:
3290 case T_GENERALIZEDTIME:
3291 is_type_comp = true;
3292 break;
3293 case T_USTR:
3294 // Maybe :) is ustr.is_cstr().
3295 is_type_comp = true;
3296 break;
3297 default:
3298 is_type_comp = false;
3299 break;
3300 }
3301 break;
3302 // Character string group 3.
3303 case T_CSTR:
3304 case T_NUMERICSTRING:
3305 case T_PRINTABLESTRING:
3306 case T_IA5STRING:
3307 case T_VISIBLESTRING:
3308 case T_UTCTIME:
3309 case T_GENERALIZEDTIME:
3310 switch (t2->typetype) {
3311 case T_CSTR:
3312 case T_NUMERICSTRING:
3313 case T_PRINTABLESTRING:
3314 case T_IA5STRING:
3315 case T_VISIBLESTRING:
3316 case T_UTCTIME:
3317 case T_GENERALIZEDTIME:
3318 is_type_comp = true;
3319 break;
3320 default:
3321 is_type_comp = false;
3322 break;
3323 }
3324 break;
3325 // Polymorphic built-in types.
3326 case T_BSTR:
3327 case T_BSTR_A:
3328 is_type_comp = ( t2->typetype == T_BSTR || t2->typetype == T_BSTR_A );
3329 break;
3330 case T_INT:
3331 case T_INT_A:
3332 is_type_comp = ( t2->typetype == T_INT || t2->typetype == T_INT_A );
3333 break;
3334 // ROID is visible as OID from TTCN-3.
3335 case T_OID:
3336 is_type_comp = ( t2->typetype == T_OID || (!is_asn1() && t2->typetype == T_ROID) );
3337 break;
3338 case T_ROID:
3339 is_type_comp = ( t2->typetype == T_ROID || (!p_type->is_asn1() && t2->typetype == T_OID) );
3340 break;
3341 case T_COMPONENT:
3342 is_type_comp = ( t2->typetype == T_COMPONENT && t1->u.component->is_compatible(t2->u.component) );
3343 break;
3344 case T_SEQ_A:
3345 case T_SEQ_T:
3346 is_type_comp = t1->is_compatible_record(t2, p_info, p_left_chain, p_right_chain, p_is_inline_template);
3347 break;
3348 case T_SEQOF:
3349 is_type_comp = t1->is_compatible_record_of(t2, p_info, p_left_chain, p_right_chain, p_is_inline_template);
3350 break;
3351 case T_SET_A:
3352 case T_SET_T:
3353 is_type_comp = t1->is_compatible_set(t2, p_info, p_left_chain, p_right_chain, p_is_inline_template);
3354 break;
3355 case T_SETOF:
3356 is_type_comp = t1->is_compatible_set_of(t2, p_info, p_left_chain, p_right_chain, p_is_inline_template);
3357 break;
3358 case T_ARRAY:
3359 is_type_comp = t1->is_compatible_array(t2, p_info, p_left_chain, p_right_chain, p_is_inline_template);
3360 break;
3361 case T_CHOICE_T:
3362 case T_CHOICE_A:
3363 case T_ANYTYPE:
3364 is_type_comp = t1->is_compatible_choice_anytype(t2, p_info, p_left_chain, p_right_chain, p_is_inline_template);
3365 break;
3366 case T_ENUM_A:
3367 case T_ENUM_T:
3368 case T_SIGNATURE:
3369 case T_PORT:
3370 case T_OPENTYPE:
3371 is_type_comp = ( t1 == t2 );
3372 break;
3373 case T_FUNCTION:
3374 case T_ALTSTEP:
3375 case T_TESTCASE:
3376 // TODO: Compatibility.
3377 is_type_comp = ( t1 == t2 );
3378 break;
3379 case T_ANY:
3380 is_type_comp = ( t2->typetype == T_ANY || t2->typetype == T_OSTR );
3381 break;
3382 default:
3383 FATAL_ERROR("Type::is_compatible()");
3384 }
3385 // if types are compatible then check subtype compatibility
3386 // skip check if p_info is NULL
3387 if ((p_info!=NULL) && is_type_comp && (sub_type!=NULL) && (p_type->sub_type!=NULL) &&
3388 (sub_type->get_subtypetype()==p_type->sub_type->get_subtypetype()))
3389 {
3390 if (p_info->get_str1_elem()) {
3391 if (p_info->get_str2_elem()) {
3392 // both are string elements -> nothing to do
3393 } else {
3394 // char <-> string
3395 if (!p_type->sub_type->is_compatible_with_elem()) {
3396 is_type_comp = false;
3397 p_info->set_subtype_error(
3398 string("Subtype mismatch: string element has no common value with subtype ")+
3399 p_type->sub_type->to_string());
3400 }
3401 }
3402 } else {
3403 if (p_info->get_str2_elem()) {
3404 // string <-> char
3405 if (!sub_type->is_compatible_with_elem()) {
3406 is_type_comp = false;
3407 p_info->set_subtype_error(string("Subtype mismatch: subtype ")+
3408 sub_type->to_string()+string(" has no common value with a string element"));
3409 }
3410 } else {
3411 // string <-> string
3412 if (!sub_type->is_compatible(p_type->sub_type)) {
3413 is_type_comp = false;
3414 p_info->set_subtype_error(string("Subtype mismatch: subtype ")+
3415 sub_type->to_string()+string(" has no common value with subtype ")+
3416 p_type->sub_type->to_string());
3417 }
3418 }
3419 }
3420 }
3421 return is_type_comp;
3422 }
3423
3424 bool Type::is_structured_type() const
3425 {
3426 switch (typetype) {
3427 case T_SEQ_A:
3428 case T_SEQ_T:
3429 case T_SEQOF:
3430 case T_ARRAY:
3431 case T_CHOICE_A:
3432 case T_CHOICE_T:
3433 case T_ANYTYPE:
3434 case T_SET_A:
3435 case T_SET_T:
3436 case T_SETOF:
3437 return true;
3438 default:
3439 return false;
3440 }
3441 }
3442
3443 bool Type::is_subtype_length_compatible(Type *p_type)
3444 {
3445 if (typetype != T_SEQOF && typetype != T_SETOF)
3446 FATAL_ERROR("Type::is_subtype_length_compatible()");
3447 if (!sub_type) return true;
3448 SubtypeConstraint::subtype_t st_t = typetype == T_SEQOF ?
3449 SubtypeConstraint::ST_RECORDOF : SubtypeConstraint::ST_SETOF;
3450 switch (p_type->typetype) {
3451 case T_SEQ_A:
3452 case T_SEQ_T:
3453 case T_SET_A:
3454 case T_SET_T: {
3455 vector<SubTypeParse> p_stp_v;
3456 Value *p_nof_comps = new Value(Value::V_INT,
3457 new int_val_t(p_type->get_nof_comps()));
3458 p_stp_v.add(new SubTypeParse(new Ttcn::LengthRestriction(p_nof_comps)));
3459 SubType p_st(st_t, this, NULL, &p_stp_v, NULL);
3460 p_st.chk();
3461 delete p_stp_v[0];
3462 p_stp_v.clear();
3463 return sub_type->is_length_compatible(&p_st); }
3464 case T_SEQOF:
3465 case T_SETOF:
3466 if (!p_type->sub_type) return true;
3467 else return sub_type->is_length_compatible(p_type->sub_type);
3468 case T_ARRAY: {
3469 if (p_type->u.array.dimension->get_has_error()) return false;
3470 vector<SubTypeParse> p_stp_v;
3471 Value *p_nof_comps
3472 = new Value(Value::V_INT,
3473 new int_val_t(p_type->u.array.dimension->get_size()));
3474 p_stp_v.add(new SubTypeParse(new Ttcn::LengthRestriction(p_nof_comps)));
3475 SubType p_st(st_t, this, NULL, &p_stp_v, NULL);
3476 p_st.chk(); // Convert SubTypeParse to SubType.
3477 delete p_stp_v[0];
3478 p_stp_v.clear();
3479 return sub_type->is_length_compatible(&p_st); }
3480 default:
3481 FATAL_ERROR("Type::is_subtype_length_compatible()");
3482 }
3483 }
3484
3485 // Errors and warnings are reported in an upper level. We just make a
3486 // simple decision here.
3487 bool Type::is_compatible_record(Type *p_type, TypeCompatInfo *p_info,
3488 TypeChain *p_left_chain,
3489 TypeChain *p_right_chain,
3490 bool p_is_inline_template)
3491 {
3492 if (typetype != T_SEQ_A && typetype != T_SEQ_T)
3493 FATAL_ERROR("Type::is_compatible_record()");
3494 // The get_type_refd_last() was called for both Types at this point. All
3495 // this code runs in both run-times.
3496 if (this == p_type) return true;
3497 else if (!use_runtime_2 || !p_info
3498 || (p_info && p_info->is_strict())) return false;
3499 size_t nof_comps = get_nof_comps();
3500 switch (p_type->typetype) {
3501 case T_SEQ_A:
3502 case T_SEQ_T: {
3503 // According to 6.3.2.2 the # of fields and the optionality must be
3504 // the same for record types. It's good news for compile-time checks.
3505 // Conversion is always from "p_type -> this".
3506 size_t p_nof_comps = p_type->get_nof_comps();
3507 if (nof_comps != p_nof_comps) {
3508 p_info->set_is_erroneous(this, p_type, string("The number of fields in "
3509 "record/SEQUENCE types must be the same"));
3510 return false;
3511 }
3512 // If p_info is present we have the chains as well.
3513 if (p_left_chain->empty()) p_left_chain->add(this);
3514 if (p_right_chain->empty()) p_right_chain->add(p_type);
3515 for (size_t i = 0; i < nof_comps; i++) {
3516 CompField *cf = get_comp_byIndex(i);
3517 CompField *p_cf = p_type->get_comp_byIndex(i);
3518 Type *cf_type = cf->get_type()->get_type_refd_last();
3519 Type *p_cf_type = p_cf->get_type()->get_type_refd_last();
3520 string cf_name = cf->get_name().get_dispname();
3521 string p_cf_name = p_cf->get_name().get_dispname();
3522 if (cf->get_is_optional() != p_cf->get_is_optional()) {
3523 p_info->append_ref_str(0, "." + cf_name);
3524 p_info->append_ref_str(1, "." + p_cf_name);
3525 p_info->set_is_erroneous(cf_type, p_cf_type, string("The optionality of "
3526 "fields in record/SEQUENCE types must be "
3527 "the same"));
3528 return false;
3529 }
3530 TypeCompatInfo info_tmp(p_info->get_my_module(), cf_type, p_cf_type,
3531 false, false);
3532 p_left_chain->mark_state();
3533 p_right_chain->mark_state();
3534 p_left_chain->add(cf_type);
3535 p_right_chain->add(p_cf_type);
3536 if (cf_type != p_cf_type
3537 && !(p_left_chain->has_recursion() && p_right_chain->has_recursion())
3538 && !cf_type->is_compatible(p_cf_type, &info_tmp, p_left_chain,
3539 p_right_chain, p_is_inline_template)) {
3540 p_info->append_ref_str(0, "." + cf_name + info_tmp.get_ref_str(0));
3541 p_info->append_ref_str(1, "." + p_cf_name + info_tmp.get_ref_str(1));
3542 p_info->set_is_erroneous(info_tmp.get_type(0), info_tmp.get_type(1),
3543 info_tmp.get_error_str());
3544 p_left_chain->previous_state();
3545 p_right_chain->previous_state();
3546 return false;
3547 }
3548 p_left_chain->previous_state();
3549 p_right_chain->previous_state();
3550 }
3551 if (!p_is_inline_template) {
3552 p_info->set_needs_conversion(true);
3553 p_info->add_type_conversion(p_type, this);
3554 }
3555 return true; }
3556 case T_SEQOF:
3557 if (!p_type->is_subtype_length_compatible(this)) {
3558 p_info->set_is_erroneous(this, p_type, string("Incompatible record of/SEQUENCE "
3559 "OF subtypes"));
3560 return false;
3561 }
3562 // no break
3563 case T_ARRAY: {
3564 Type *p_of_type = p_type->get_ofType()->get_type_refd_last();
3565 if (p_type->typetype == T_ARRAY) {
3566 if (p_of_type->get_typetype() == T_ARRAY) {
3567 p_info->set_is_erroneous(this, p_type, string("record/SEQUENCE types are "
3568 "compatible only with single-dimension "
3569 "arrays"));
3570 return false;
3571 }
3572 size_t nof_opt_fields = 0;
3573 for (size_t i = 0; i < nof_comps; i++)
3574 if (get_comp_byIndex(i)->get_is_optional()) nof_opt_fields++;
3575 if (p_type->u.array.dimension->get_size()
3576 < nof_comps - nof_opt_fields) {
3577 p_info->set_is_erroneous(this, p_type, string("The dimension of the array "
3578 "must be >= than the number of mandatory "
3579 "fields in the record/SEQUENCE type"));
3580 return false;
3581 }
3582 }
3583 if (p_left_chain->empty()) p_left_chain->add(this);
3584 if (p_right_chain->empty()) p_right_chain->add(p_type);
3585 for (size_t i = 0; i < nof_comps; i++) {
3586 Type *cf_type = get_comp_byIndex(i)->get_type()->get_type_refd_last();
3587 TypeCompatInfo info_tmp(p_info->get_my_module(), cf_type, p_of_type,
3588 false, false);
3589 p_left_chain->mark_state();
3590 p_right_chain->mark_state();
3591 p_left_chain->add(cf_type);
3592 p_right_chain->add(p_of_type);
3593 if (cf_type != p_of_type
3594 && !(p_left_chain->has_recursion() && p_right_chain->has_recursion())
3595 && !cf_type->is_compatible(p_of_type, &info_tmp, p_left_chain,
3596 p_right_chain, p_is_inline_template)) {
3597 p_info->append_ref_str(0, "." + get_comp_byIndex(i)
3598 ->get_name().get_dispname() + info_tmp.get_ref_str(0));
3599 p_info->append_ref_str(1, "[]" + info_tmp.get_ref_str(1));
3600 p_info->set_is_erroneous(info_tmp.get_type(0), info_tmp.get_type(1),
3601 info_tmp.get_error_str());
3602 p_left_chain->previous_state();
3603 p_right_chain->previous_state();
3604 return false;
3605 }
3606 p_left_chain->previous_state();
3607 p_right_chain->previous_state();
3608 }
3609 if (!p_is_inline_template) {
3610 p_info->set_needs_conversion(true);
3611 p_info->add_type_conversion(p_type, this);
3612 }
3613 return true; }
3614 case T_CHOICE_A:
3615 case T_CHOICE_T:
3616 case T_ANYTYPE:
3617 // 6.3.2.4 makes our job very easy...
3618 p_info->set_is_erroneous(this, p_type, string("union/CHOICE/anytype types are "
3619 "compatible only with other "
3620 "union/CHOICE/anytype types"));
3621 return false;
3622 case T_SET_A:
3623 case T_SET_T:
3624 case T_SETOF:
3625 // Only set/set of types are compatible with other set/set of types.
3626 // 6.3.2.3 is a little bit unclear about set of types, but we treat them
3627 // this way. Otherwise, it would be possible to use compatibility with
3628 // a "middle-man" set of variable between record/set types:
3629 // type set S { integer f1, integer f2 }
3630 // type record { integer f1, integer f2 }
3631 // type set of integer SO
3632 // var S s := { 1, 2 }
3633 // var R r := { 1, 2 }
3634 // var SO so
3635 // so := s
3636 // if (r == s) { ... } // Not allowed.
3637 // if (r == so) { ... } // Not allowed. (?)
3638 // Seems to be a fair decision. If we would want compatibility between
3639 // variables of record/set types, we should allow it directly.
3640 p_info->set_is_erroneous(this, p_type, string("set/SET and set of/SET OF "
3641 "types are compatible only with other set/SET "
3642 "set of/SET OF types"));
3643 return false;
3644 default:
3645 return false;
3646 }
3647 }
3648
3649 bool Type::is_compatible_record_of(Type *p_type, TypeCompatInfo *p_info,
3650 TypeChain *p_left_chain,
3651 TypeChain *p_right_chain,
3652 bool p_is_inline_template)
3653 {
3654 if (typetype != T_SEQOF) FATAL_ERROR("Type::is_compatible_record_of()");
3655 if (this == p_type) return true;
3656 else if (T_SEQOF == p_type->get_type_refd_last()->typetype &&
3657 is_pregenerated() && p_type->is_pregenerated() &&
3658 get_ofType()->get_type_refd_last()->typetype ==
3659 p_type->get_ofType()->get_type_refd_last()->typetype &&
3660 (use_runtime_2 || get_optimize_attribute() == p_type->get_optimize_attribute())) {
3661 // Pre-generated record-ofs of the same element type are compatible with
3662 // each other (in RT1 optimized record-ofs are not compatible with non-optimized ones)
3663 if (!is_subtype_length_compatible(p_type)) {
3664 p_info->set_is_erroneous(this, p_type, string("Incompatible "
3665 "record of/SEQUENCE OF subtypes"));
3666 return false;
3667 }
3668 return true;
3669 }
3670 else if (!use_runtime_2 || !p_info
3671 || (p_info && p_info->is_strict())) return false;
3672 switch (p_type->typetype) {
3673 case T_SEQ_A:
3674 case T_SEQ_T: {
3675 if (!is_subtype_length_compatible(p_type)) {
3676 p_info->set_is_erroneous(this, p_type, string("Incompatible "
3677 "record of/SEQUENCE OF subtypes"));
3678 return false;
3679 }
3680 Type *of_type = get_ofType()->get_type_refd_last();
3681 if (p_left_chain->empty()) p_left_chain->add(this);
3682 if (p_right_chain->empty()) p_right_chain->add(p_type);
3683 for (size_t i = 0; i < p_type->get_nof_comps(); i++) {
3684 CompField *p_cf = p_type->get_comp_byIndex(i);
3685 Type *p_cf_type = p_cf->get_type()->get_type_refd_last();
3686 TypeCompatInfo info_tmp(p_info->get_my_module(), of_type, p_cf_type,
3687 false, false);
3688 p_left_chain->mark_state();
3689 p_right_chain->mark_state();
3690 p_left_chain->add(of_type);
3691 p_right_chain->add(p_cf_type);
3692 if (of_type != p_cf_type
3693 && !(p_left_chain->has_recursion() && p_right_chain->has_recursion())
3694 && !of_type->is_compatible(p_cf_type, &info_tmp, p_left_chain,
3695 p_right_chain, p_is_inline_template)) {
3696 p_info->append_ref_str(0, "[]" + info_tmp.get_ref_str(0));
3697 p_info->append_ref_str(1, "." + p_cf->get_name().get_dispname() +
3698 info_tmp.get_ref_str(1));
3699 p_info->set_is_erroneous(info_tmp.get_type(0),
3700 info_tmp.get_type(1),
3701 info_tmp.get_error_str());
3702 p_left_chain->previous_state();
3703 p_right_chain->previous_state();
3704 return false;
3705 }
3706 p_left_chain->previous_state();
3707 p_right_chain->previous_state();
3708 }
3709 if (!p_is_inline_template) {
3710 p_info->set_needs_conversion(true);
3711 p_info->add_type_conversion(p_type, this);
3712 }
3713 return true; }
3714 case T_SEQOF:
3715 case T_ARRAY: {
3716 if (!is_subtype_length_compatible(p_type)) {
3717 p_info->set_is_erroneous(this, p_type, string("Incompatible "
3718 "record of/SEQUENCE OF subtypes"));
3719 return false;
3720 }
3721 Type *of_type = get_ofType()->get_type_refd_last();
3722 Type *p_of_type = p_type->get_ofType()->get_type_refd_last();
3723 if (p_left_chain->empty()) p_left_chain->add(this);
3724 if (p_right_chain->empty()) p_right_chain->add(p_type);
3725 TypeCompatInfo info_tmp(p_info->get_my_module(), of_type, p_of_type,
3726 false, false);
3727 p_left_chain->mark_state();
3728 p_right_chain->mark_state();
3729 p_left_chain->add(of_type);
3730 p_right_chain->add(p_of_type);
3731 if (of_type == p_of_type
3732 || (p_left_chain->has_recursion() && p_right_chain->has_recursion())
3733 || of_type->is_compatible(p_of_type, &info_tmp, p_left_chain,
3734 p_right_chain, p_is_inline_template)) {
3735 if (!p_is_inline_template) {
3736 p_info->set_needs_conversion(true);
3737 p_info->add_type_conversion(p_type, this);
3738 }
3739 p_left_chain->previous_state();
3740 p_right_chain->previous_state();
3741 return true;
3742 }
3743 p_left_chain->previous_state();
3744 p_right_chain->previous_state();
3745 p_info->append_ref_str(0, "[]" + info_tmp.get_ref_str(0));
3746 // Arrays already have the "[]" in their names.
3747 if (p_type->get_typetype() != T_ARRAY) p_info->append_ref_str(1, string("[]"));
3748 p_info->append_ref_str(1, info_tmp.get_ref_str(1));
3749 p_info->set_is_erroneous(info_tmp.get_type(0), info_tmp.get_type(1),
3750 info_tmp.get_error_str());
3751 return false; }
3752 case T_CHOICE_A:
3753 case T_CHOICE_T:
3754 case T_ANYTYPE:
3755 p_info->set_is_erroneous(this, p_type, string("union/CHOICE/anytype types are "
3756 "compatible only with other "
3757 "union/CHOICE/anytype types"));
3758 return false;
3759 case T_SET_A:
3760 case T_SET_T:
3761 case T_SETOF:
3762 p_info->set_is_erroneous(this, p_type, string("set/SET and set of/SET OF "
3763 "types are compatible only with other set/SET "
3764 "set of/SET OF types"));
3765 return false;
3766 default:
3767 return false;
3768 }
3769 }
3770
3771 bool Type::is_compatible_array(Type *p_type, TypeCompatInfo *p_info,
3772 TypeChain *p_left_chain,
3773 TypeChain *p_right_chain,
3774 bool p_is_inline_template)
3775 {
3776 if (typetype != T_ARRAY) FATAL_ERROR("Type::is_compatible_array()");
3777 // Copied from the original checker code. The type of the elements and
3778 // the dimension of the array must be the same.
3779 if (this == p_type) return true;
3780 if (p_type->typetype == T_ARRAY && u.array.element_type
3781 ->is_compatible(p_type->u.array.element_type, NULL, NULL, NULL, p_is_inline_template)
3782 && u.array.dimension->is_identical(p_type->u.array.dimension))
3783 return true;
3784 else if (!use_runtime_2 || !p_info
3785 || (p_info && p_info->is_strict())) return false;
3786 Type *of_type = get_ofType()->get_type_refd_last();
3787 switch (p_type->get_typetype()) {
3788 case T_SEQ_A:
3789 case T_SEQ_T: {
3790 if (of_type->get_typetype() == T_ARRAY) {
3791 p_info->set_is_erroneous(this, p_type, string("record/SEQUENCE types are "
3792 "compatible only with single-dimension "
3793 "arrays"));
3794 return false;
3795 }
3796 size_t p_nof_comps = p_type->get_nof_comps();
3797 size_t p_nof_opt_fields = 0;
3798 for (size_t i = 0; i < p_nof_comps; i++)
3799 if (p_type->get_comp_byIndex(i)->get_is_optional())
3800 p_nof_opt_fields++;
3801 if (u.array.dimension->get_size() < p_nof_comps - p_nof_opt_fields) {
3802 p_info->set_is_erroneous(this, p_type, string("The dimension of the array "
3803 "must be >= than the number of mandatory "
3804 "fields in the record/SEQUENCE type"));
3805 return false;
3806 }
3807 if (p_left_chain->empty()) p_left_chain->add(this);
3808 if (p_right_chain->empty()) p_right_chain->add(p_type);
3809 for (size_t i = 0; i < p_nof_comps; ++i) {
3810 CompField *p_cf = p_type->get_comp_byIndex(i);
3811 Type *p_cf_type = p_cf->get_type()->get_type_refd_last();
3812 string p_cf_name = p_cf->get_name().get_dispname();
3813 TypeCompatInfo info_tmp(p_info->get_my_module(), of_type, p_cf_type,
3814 false, false);
3815 p_left_chain->mark_state();
3816 p_right_chain->mark_state();
3817 p_left_chain->add(of_type);
3818 p_right_chain->add(p_cf_type);
3819 if (of_type != p_cf_type
3820 && !(p_left_chain->has_recursion() && p_right_chain->has_recursion())
3821 && !of_type->is_compatible(p_cf_type, &info_tmp, p_left_chain,
3822 p_right_chain, p_is_inline_template)) {
3823 p_info->append_ref_str(0, info_tmp.get_ref_str(0));
3824 p_info->append_ref_str(1, "." + p_cf->get_name().get_dispname() +
3825 info_tmp.get_ref_str(1));
3826 p_info->set_is_erroneous(info_tmp.get_type(0),
3827 info_tmp.get_type(1),
3828 info_tmp.get_error_str());
3829 p_left_chain->previous_state();
3830 p_right_chain->previous_state();
3831 return false;
3832 }
3833 p_left_chain->previous_state();
3834 p_right_chain->previous_state();
3835 }
3836 if (!p_is_inline_template) {
3837 p_info->set_needs_conversion(true);
3838 p_info->add_type_conversion(p_type, this);
3839 }
3840 return true; }
3841 case T_SEQOF:
3842 if (!p_type->is_subtype_length_compatible(this)) {
3843 p_info->set_is_erroneous(this, p_type, string("Incompatible "
3844 "record of/SEQUENCE OF subtypes"));
3845 return false;
3846 } // Don't break.
3847 case T_ARRAY: {
3848 if (p_type->get_typetype() == T_ARRAY
3849 && !u.array.dimension->is_identical(p_type->u.array.dimension)) {
3850 p_info->set_is_erroneous(this, p_type, string("Array types should have "
3851 "the same dimension"));
3852 return false;
3853 }
3854 Type *p_of_type = p_type->get_ofType()->get_type_refd_last();
3855 TypeCompatInfo info_tmp(p_info->get_my_module(), of_type, p_of_type,
3856 false, false);
3857 if (p_left_chain->empty()) p_left_chain->add(this);
3858 if (p_right_chain->empty()) p_right_chain->add(p_type);
3859 p_left_chain->mark_state();
3860 p_right_chain->mark_state();
3861 p_left_chain->add(of_type);
3862 p_right_chain->add(p_of_type);
3863 if (of_type == p_of_type
3864 || (p_left_chain->has_recursion() && p_right_chain->has_recursion())
3865 || of_type->is_compatible(p_of_type, &info_tmp, p_left_chain,
3866 p_right_chain, p_is_inline_template)) {
3867 if (!p_is_inline_template) {
3868 p_info->set_needs_conversion(true);
3869 p_info->add_type_conversion(p_type, this);
3870 }
3871 p_left_chain->previous_state();
3872 p_right_chain->previous_state();
3873 return true;
3874 }
3875 p_left_chain->previous_state();
3876 p_right_chain->previous_state();
3877 p_info->append_ref_str(0, info_tmp.get_ref_str(0));
3878 if (p_type->get_typetype() != T_ARRAY) p_info->append_ref_str(1, string("[]"));
3879 p_info->append_ref_str(1, info_tmp.get_ref_str(1));
3880 p_info->set_is_erroneous(info_tmp.get_type(0), info_tmp.get_type(1),
3881 info_tmp.get_error_str());
3882 return false; }
3883 case T_CHOICE_A:
3884 case T_CHOICE_T:
3885 case T_ANYTYPE:
3886 p_info->set_is_erroneous(this, p_type, string("union/CHOICE/anytype types are "
3887 "compatible only with other "
3888 "union/CHOICE/anytype types"));
3889 return false;
3890 case T_SET_A:
3891 case T_SET_T:
3892 case T_SETOF:
3893 p_info->set_is_erroneous(this, p_type, string("set/SET and set of/SET OF "
3894 "types are compatible only with other set/SET "
3895 "set of/SET OF types"));
3896 return false;
3897 default:
3898 return false;
3899 }
3900 }
3901
3902 bool Type::is_compatible_set(Type *p_type, TypeCompatInfo *p_info,
3903 TypeChain *p_left_chain,
3904 TypeChain *p_right_chain,
3905 bool p_is_inline_template)
3906 {
3907 if (typetype != T_SET_A && typetype != T_SET_T)
3908 FATAL_ERROR("Type::is_compatible_set()");
3909 if (this == p_type) return true;
3910 else if (!use_runtime_2 || !p_info
3911 || (p_info && p_info->is_strict())) return false;
3912 size_t nof_comps = get_nof_comps();
3913 switch (p_type->typetype) {
3914 case T_SET_A:
3915 case T_SET_T: {
3916 // The standard is very generous. We don't need to check for a possible
3917 // combination of compatible fields. According to 6.3.2.3, simply do
3918 // the same thing as for T_SEQ_{A,T} types. The fields are in their
3919 // textual order.
3920 size_t p_nof_comps = p_type->get_nof_comps();
3921 if (nof_comps != p_nof_comps) {
3922 p_info->set_is_erroneous(this, p_type, string("The number of fields in "
3923 "set/SET types must be the same"));
3924 return false;
3925 }
3926 if (p_left_chain->empty()) p_left_chain->add(this);
3927 if (p_right_chain->empty()) p_right_chain->add(p_type);
3928 for (size_t i = 0; i < nof_comps; i++) {
3929 CompField *cf = get_comp_byIndex(i);
3930 CompField *p_cf = p_type->get_comp_byIndex(i);
3931 Type *cf_type = cf->get_type()->get_type_refd_last();
3932 Type *p_cf_type = p_cf->get_type()->get_type_refd_last();
3933 string cf_name = cf->get_name().get_dispname();
3934 string p_cf_name = p_cf->get_name().get_dispname();
3935 if (cf->get_is_optional() != p_cf->get_is_optional()) {
3936 p_info->append_ref_str(0, "." + cf_name);
3937 p_info->append_ref_str(1, "." + p_cf_name);
3938 p_info->set_is_erroneous(cf_type, p_cf_type, string("The optionality of "
3939 "fields in set/SET types must be the "
3940 "same"));
3941 return false;
3942 }
3943 TypeCompatInfo info_tmp(p_info->get_my_module(), cf_type, p_cf_type,
3944 false, false);
3945 p_left_chain->mark_state();
3946 p_right_chain->mark_state();
3947 p_left_chain->add(cf_type);
3948 p_right_chain->add(p_cf_type);
3949 if (cf_type != p_cf_type
3950 && !(p_left_chain->has_recursion() && p_right_chain->has_recursion())
3951 && !cf_type->is_compatible(p_cf_type, &info_tmp, p_left_chain,
3952 p_right_chain, p_is_inline_template)) {
3953 p_info->append_ref_str(0, "." + cf_name + info_tmp.get_ref_str(0));
3954 p_info->append_ref_str(1, "." + p_cf_name + info_tmp.get_ref_str(1));
3955 p_info->set_is_erroneous(info_tmp.get_type(0), info_tmp.get_type(1),
3956 info_tmp.get_error_str());
3957 p_left_chain->previous_state();
3958 p_right_chain->previous_state();
3959 return false;
3960 }
3961 p_left_chain->previous_state();
3962 p_right_chain->previous_state();
3963 }
3964 if (!p_is_inline_template) {
3965 p_info->set_needs_conversion(true);
3966 p_info->add_type_conversion(p_type, this);
3967 }
3968 return true; }
3969 case T_SETOF: {
3970 if (!p_type->is_subtype_length_compatible(this)) {
3971 p_info->set_is_erroneous(this, p_type, string("Incompatible set of/SET OF "
3972 "subtypes"));
3973 return false;
3974 }
3975 if (p_left_chain->empty()) p_left_chain->add(this);
3976 if (p_right_chain->empty()) p_right_chain->add(p_type);
3977 Type *p_of_type = p_type->get_ofType()->get_type_refd_last();
3978 for (size_t i = 0; i < nof_comps; i++) {
3979 Type *cf_type = get_comp_byIndex(i)->get_type()->get_type_refd_last();
3980 TypeCompatInfo info_tmp(p_info->get_my_module(), cf_type, p_of_type,
3981 false, false);
3982 p_left_chain->mark_state();
3983 p_right_chain->mark_state();
3984 p_left_chain->add(cf_type);
3985 p_right_chain->add(p_of_type);
3986 if (cf_type != p_of_type
3987 && !(p_left_chain->has_recursion() && p_right_chain->has_recursion())
3988 && !cf_type->is_compatible(p_of_type, &info_tmp, p_left_chain,
3989 p_right_chain, p_is_inline_template)) {
3990 p_info->append_ref_str(0, "." + get_comp_byIndex(i)
3991 ->get_name().get_dispname() + info_tmp.get_ref_str(0));
3992 p_info->append_ref_str(1, "[]" + info_tmp.get_ref_str(1));
3993 p_info->set_is_erroneous(info_tmp.get_type(0), info_tmp.get_type(1),
3994 info_tmp.get_error_str());
3995 p_left_chain->previous_state();
3996 p_right_chain->previous_state();
3997 return false;
3998 }
3999 p_left_chain->previous_state();
4000 p_right_chain->previous_state();
4001 }
4002 if (!p_is_inline_template) {
4003 p_info->set_needs_conversion(true);
4004 p_info->add_type_conversion(p_type, this);
4005 }
4006 return true; }
4007 case T_CHOICE_A:
4008 case T_CHOICE_T:
4009 case T_ANYTYPE:
4010 p_info->set_is_erroneous(this, p_type, string("union/CHOICE/anytype types are "
4011 "compatible only with other "
4012 "union/CHOICE/anytype types"));
4013 return false;
4014 case T_SEQ_A:
4015 case T_SEQ_T:
4016 case T_SEQOF:
4017 case T_ARRAY:
4018 p_info->set_is_erroneous(this, p_type, string("set/SET and set of/SET OF "
4019 "types are compatible only with other set/SET "
4020 "set of/SET OF types"));
4021 return false;
4022 default:
4023 return false;
4024 }
4025 }
4026
4027 bool Type::is_compatible_set_of(Type *p_type, TypeCompatInfo *p_info,
4028 TypeChain *p_left_chain,
4029 TypeChain *p_right_chain,
4030 bool p_is_inline_template)
4031 {
4032 if (typetype != T_SETOF) FATAL_ERROR("Type::is_compatible_set_of()");
4033 if (this == p_type) return true;
4034 else if (T_SETOF == p_type->get_type_refd_last()->typetype &&
4035 is_pregenerated() && p_type->is_pregenerated() &&
4036 get_ofType()->get_type_refd_last()->typetype ==
4037 p_type->get_ofType()->get_type_refd_last()->typetype &&
4038 (use_runtime_2 || get_optimize_attribute() == p_type->get_optimize_attribute())) {
4039 // Pre-generated set-ofs of the same element type are compatible with
4040 // each other (in RT1 optimized set-ofs are not compatible with non-optimized ones)
4041 if (!is_subtype_length_compatible(p_type)) {
4042 p_info->set_is_erroneous(this, p_type, string("Incompatible "
4043 "set of/SET OF subtypes"));
4044 return false;
4045 }
4046 return true;
4047 }
4048 else if (!use_runtime_2 || !p_info
4049 || (p_info && p_info->is_strict())) return false;
4050 Type *of_type = get_ofType();
4051 switch (p_type->get_typetype()) {
4052 case T_SET_A:
4053 case T_SET_T: {
4054 if (!is_subtype_length_compatible(p_type)) {
4055 p_info->set_is_erroneous(this, p_type, string("Incompatible set of/SET OF "
4056 "subtypes"));
4057 return false;
4058 }
4059 if (p_left_chain->empty()) p_left_chain->add(this);
4060 if (p_right_chain->empty()) p_right_chain->add(p_type);
4061 for (size_t i = 0; i < p_type->get_nof_comps(); i++) {
4062 CompField *p_cf = p_type->get_comp_byIndex(i);
4063 Type *p_cf_type = p_cf->get_type()->get_type_refd_last();
4064 TypeCompatInfo info_tmp(p_info->get_my_module(), of_type, p_cf_type,
4065 false, false);
4066 p_left_chain->mark_state();
4067 p_right_chain->mark_state();
4068 p_left_chain->add(of_type);
4069 p_right_chain->add(p_cf_type);
4070 if (of_type != p_cf_type
4071 && !(p_left_chain->has_recursion() && p_right_chain->has_recursion())
4072 && !of_type->is_compatible(p_cf_type, &info_tmp, p_left_chain,
4073 p_right_chain, p_is_inline_template)) {
4074 p_info->append_ref_str(0, "[]" + info_tmp.get_ref_str(0));
4075 p_info->append_ref_str(1, "." + p_cf->get_name().get_dispname() +
4076 info_tmp.get_ref_str(1));
4077 p_info->set_is_erroneous(info_tmp.get_type(0), info_tmp.get_type(1),
4078 info_tmp.get_error_str());
4079 p_left_chain->previous_state();
4080 p_right_chain->previous_state();
4081 return false;
4082 }
4083 p_left_chain->previous_state();
4084 p_right_chain->previous_state();
4085 }
4086 if (!p_is_inline_template) {
4087 p_info->set_needs_conversion(true);
4088 p_info->add_type_conversion(p_type, this);
4089 }
4090 return true; }
4091 case T_SETOF: {
4092 if (!is_subtype_length_compatible(p_type)) {
4093 p_info->set_is_erroneous(this, p_type, string("Incompatible set of/SET OF "
4094 "subtypes"));
4095 return false;
4096 }
4097 if (p_left_chain->empty()) p_left_chain->add(this);
4098 if (p_right_chain->empty()) p_right_chain->add(p_type);
4099 Type *p_of_type = p_type->get_ofType()->get_type_refd_last();
4100 TypeCompatInfo info_tmp(p_info->get_my_module(), of_type, p_of_type,
4101 false, false);
4102 p_left_chain->mark_state();
4103 p_right_chain->mark_state();
4104 p_left_chain->add(of_type);
4105 p_right_chain->add(p_of_type);
4106 if (of_type == p_of_type
4107 || (p_left_chain->has_recursion() && p_right_chain->has_recursion())
4108 || of_type->is_compatible(p_of_type, &info_tmp, p_left_chain,
4109 p_right_chain, p_is_inline_template)) {
4110 if (!p_is_inline_template) {
4111 p_info->set_needs_conversion(true);
4112 p_info->add_type_conversion(p_type, this);
4113 }
4114 p_left_chain->previous_state();
4115 p_right_chain->previous_state();
4116 return true;
4117 }
4118 p_info->append_ref_str(0, "[]" + info_tmp.get_ref_str(0));
4119 p_info->append_ref_str(1, "[]" + info_tmp.get_ref_str(1));
4120 p_info->set_is_erroneous(info_tmp.get_type(0), info_tmp.get_type(1),
4121 info_tmp.get_error_str());
4122 p_left_chain->previous_state();
4123 p_right_chain->previous_state();
4124 return false; }
4125 case T_CHOICE_A:
4126 case T_CHOICE_T:
4127 case T_ANYTYPE:
4128 p_info->set_is_erroneous(this, p_type, string("union/CHOICE/anytype "
4129 "types are compatible only with other "
4130 "union/CHOICE/anytype types"));
4131 return false;
4132 case T_SEQ_A:
4133 case T_SEQ_T:
4134 case T_SEQOF:
4135 case T_ARRAY:
4136 p_info->set_is_erroneous(this, p_type, string("set/SET and set of/SET OF "
4137 "types are compatible only with other set/SET "
4138 "set of/SET OF types"));
4139 return false;
4140 default:
4141 return false;
4142 }
4143 }
4144
4145 bool Type::is_compatible_choice_anytype(Type *p_type,
4146 TypeCompatInfo *p_info,
4147 TypeChain *p_left_chain,
4148 TypeChain *p_right_chain,
4149 bool p_is_inline_template)
4150 {
4151 if (typetype != T_ANYTYPE && typetype != T_CHOICE_A
4152 && typetype != T_CHOICE_T)
4153 FATAL_ERROR("Type::is_compatible_choice_anytype()");
4154 if (this == p_type) return true; // Original "true" leaf...
4155 else if (!use_runtime_2 || !p_info
4156 || (p_info && p_info->is_strict())) return false; // ...and "false".
4157 if ((typetype == T_ANYTYPE && p_type->get_typetype() != T_ANYTYPE)
4158 || (p_type->get_typetype() == T_ANYTYPE && typetype != T_ANYTYPE)) {
4159 p_info->set_is_erroneous(this, p_type, string("Type anytype is compatible only "
4160 "with other anytype types"));
4161 return false;
4162 }
4163 switch (p_type->get_typetype()) {
4164 case T_SEQ_A:
4165 case T_SEQ_T:
4166 case T_SEQOF:
4167 case T_ARRAY:
4168 case T_SET_A:
4169 case T_SET_T:
4170 case T_SETOF:
4171 p_info->set_is_erroneous(this, p_type, string("union/CHOICE/anytype types are "
4172 "compatible only with other union/CHOICE/anytype "
4173 "types"));
4174 return false;
4175 case T_CHOICE_A:
4176 case T_CHOICE_T:
4177 if (typetype != T_CHOICE_A && typetype != T_CHOICE_T) {
4178 p_info->set_is_erroneous(this, p_type, string("union/CHOICE types are "
4179 "compatible only with other union/CHOICE "
4180 "types"));
4181 return false;
4182 }
4183 // no break
4184 case T_ANYTYPE: {
4185 if (p_left_chain->empty()) p_left_chain->add(this);
4186 if (p_right_chain->empty()) p_right_chain->add(p_type);
4187 // Find a field with the same name and with compatible type. There can
4188 // be more alternatives, we need to generate all conversion functions.
4189 // The same field types must be avoided. (For anytypes the "field
4190 // name = module name + field name".)
4191 bool alles_okay = false;
4192 for (size_t i = 0; i < get_nof_comps(); i++) {
4193 CompField *cf = get_comp_byIndex(i);
4194 Type *cf_type = cf->get_type()->get_type_refd_last();
4195 for (size_t j = 0; j < p_type->get_nof_comps(); ++j) {
4196 CompField *p_cf = p_type->get_comp_byIndex(j);
4197 Type *p_cf_type = p_cf->get_type()->get_type_refd_last();
4198 if (cf->get_name().get_name() != p_cf->get_name().get_name())
4199 continue;
4200 // Don't report errors for each incompatible field, it would be a
4201 // complete mess. Use this temporary for all fields. And forget
4202 // the contents.
4203 TypeCompatInfo info_tmp(p_info->get_my_module(), cf_type, p_cf_type,
4204 false, false);
4205 p_left_chain->mark_state();
4206 p_right_chain->mark_state();
4207 p_left_chain->add(cf_type);
4208 p_right_chain->add(p_cf_type);
4209 if (cf_type == p_cf_type
4210 || (p_left_chain->has_recursion() && p_right_chain->has_recursion())
4211 || cf_type->is_compatible(p_cf_type, &info_tmp, p_left_chain,
4212 p_right_chain, p_is_inline_template)) {
4213 if (cf_type != p_cf_type && cf_type->is_structured_type()
4214 && p_cf_type->is_structured_type()) {
4215 if (typetype == T_ANYTYPE && cf_type->get_my_scope()
4216 ->get_scope_mod() != p_cf_type->get_my_scope()
4217 ->get_scope_mod()) {
4218 p_left_chain->previous_state();
4219 p_right_chain->previous_state();
4220 continue;
4221 }
4222 p_info->add_type_conversion(p_cf_type, cf_type);
4223 }
4224 alles_okay = true;
4225 }
4226 p_left_chain->previous_state();
4227 p_right_chain->previous_state();
4228 }
4229 }
4230 if (alles_okay && !p_is_inline_template) {
4231 p_info->set_needs_conversion(true);
4232 p_info->add_type_conversion(p_type, this);
4233 return true;
4234 }
4235 p_info->set_is_erroneous(this, p_type, string("No compatible "
4236 "union/CHOICE/anytype field found"));
4237 return false;
4238 }
4239 default:
4240 return false;
4241 }
4242 }
4243
4244 /** \todo consider subtype constraints */
4245 bool Type::is_identical(Type *p_type)
4246 {
4247 chk();
4248 p_type->chk();
4249 Type *t1 = get_type_refd_last();
4250 Type *t2 = p_type->get_type_refd_last();
4251 if (t2->typetype == T_ERROR) return true;
4252 switch (t1->typetype) {
4253 case T_ERROR:
4254 // error type is identical to everything
4255 return true;
4256 case T_ENUM_A:
4257 case T_ENUM_T:
4258 case T_CHOICE_T:
4259 case T_CHOICE_A:
4260 case T_ANYTYPE:
4261 case T_SEQOF:
4262 case T_SETOF:
4263 case T_SEQ_A:
4264 case T_SEQ_T:
4265 case T_SET_A:
4266 case T_SET_T:
4267 case T_SIGNATURE:
4268 case T_PORT:
4269 case T_COMPONENT:
4270 case T_OPENTYPE:
4271 case T_FUNCTION:
4272 case T_ALTSTEP:
4273 case T_TESTCASE:
4274 // user-defined structured types must be identical
4275 return t1 == t2;
4276 case T_ARRAY:
4277 // the embedded type and the dimension must be identical in case of arrays
4278 return t2->typetype == T_ARRAY &&
4279 t1->u.array.element_type->is_identical(t2->u.array.element_type) &&
4280 t1->u.array.dimension->is_identical(t2->u.array.dimension);
4281 default:
4282 // in case of built-in types the TTCN-3 view of typetype must be the same
4283 return get_typetype_ttcn3(t1->typetype) ==
4284 get_typetype_ttcn3(t2->typetype);
4285 }
4286 }
4287
4288 void Type::tr_compsof(ReferenceChain *refch)
4289 {
4290 if (typetype!=T_SEQ_A && typetype!=T_SET_A)
4291 FATAL_ERROR("Type::tr_compsof()");
4292 if (u.secho.tr_compsof_ready) return;
4293 if (u.secho.block) parse_block_Se();
4294 bool auto_tagging=u.secho.ctss->needs_auto_tags();
4295 if (refch) {
4296 refch->mark_state();
4297 if (refch->add(get_fullname())) u.secho.ctss->tr_compsof(refch, false);
4298 refch->prev_state();
4299 u.secho.tr_compsof_ready = true;
4300 u.secho.ctss->tr_compsof(0, true);
4301 } else {
4302 ReferenceChain refch2(this, "While resolving COMPONENTS OF");
4303 refch2.add(get_fullname());
4304 Error_Context cntxt(this, "While resolving COMPONENTS OF");
4305 u.secho.ctss->tr_compsof(&refch2, false);
4306 u.secho.tr_compsof_ready = true;
4307 u.secho.ctss->tr_compsof(0, true);
4308 }
4309 if(auto_tagging) u.secho.ctss->add_auto_tags();
4310 }
4311
4312 bool Type::is_startable()
4313 {
4314 if(typetype != T_FUNCTION)
4315 FATAL_ERROR("Type::is_startable()");
4316 if(!checked) chk();
4317 return u.fatref.is_startable;
4318 }
4319
4320 bool Type::is_list_type(bool allow_array)
4321 {
4322 switch (get_type_refd_last()->get_typetype_ttcn3()) {
4323 case Type::T_ARRAY:
4324 return allow_array;
4325 case Type::T_CSTR:
4326 case Type::T_USTR:
4327 case Type::T_BSTR:
4328 case Type::T_HSTR:
4329 case Type::T_OSTR:
4330 case Type::T_SEQOF:
4331 case Type::T_SETOF:
4332 return true;
4333 default:
4334 return false;
4335 }
4336 }
4337
4338 void Type::set_coding_function(bool encode, const string& function_name)
4339 {
4340 string& coding_str = encode ? encoding_str : decoding_str;
4341 if (!coding_str.empty()) {
4342 error("Multiple custom %s functions declared for type '%s' (function `%s' "
4343 "is already set)", encode ? "encoding" : "decoding",
4344 get_typename().c_str(), coding_str.c_str());
4345 return;
4346 }
4347 coding_str = function_name;
4348 coding_by_function = true;
4349 }
4350
4351 void Type::chk_coding(bool encode, bool delayed /* = false */) {
4352 string& coding_str = encode ? encoding_str : decoding_str;
4353 if (!coding_str.empty())
4354 return;
4355 coding_by_function = false;
4356
4357 if (!w_attrib_path) {
4358 error("No coding rule specified for type '%s'", get_typename().c_str());
4359 return;
4360 }
4361 Type::MessageEncodingType_t coding = CT_UNDEF;
4362
4363 // Checking extension attributes
4364 Ttcn::ExtensionAttributes * extatrs = parse_extattributes(w_attrib_path);
4365 if (extatrs != 0) { // NULL means parsing error
4366 for (size_t k = 0; k < extatrs->size(); ++k) {
4367 Ttcn::ExtensionAttribute &ea = extatrs->get(k);
4368 Ttcn::TypeMappings *inmaps = 0, *maps = 0;
4369 Ttcn::TypeMapping* mapping = 0;
4370 Ttcn::TypeMappingTarget* target = 0;
4371 Type* t = 0;
4372 switch (ea.get_type()) {
4373 case Ttcn::ExtensionAttribute::ENCDECVALUE:
4374 ea.get_encdecvalue_mappings(inmaps, maps);
4375 maps = encode ? maps : inmaps;
4376 maps->set_my_scope(this->get_my_scope());
4377 maps->chk();
4378 // look for coding settings
4379 t = encode ? this : Type::get_pooltype(T_BSTR);
4380 mapping = maps->get_mapping_byType(t);
4381 if (mapping->get_nof_targets() == 0)
4382 goto end_ext;
4383 else {
4384 for (size_t ind = 0; ind < mapping->get_nof_targets(); ind++) {
4385 target = mapping->get_target_byIndex(ind);
4386 t = target->get_target_type();
4387 if ((encode && (t->get_typetype() == T_BSTR)) ||
4388 (!encode && (t->get_typename() == this->get_typename())))
4389 {
4390 if (target->get_mapping_type() ==
4391 Ttcn::TypeMappingTarget::TM_FUNCTION) {
4392 if (!coding_str.empty())
4393 target->error("Multiple definition of this target");
4394 coding_str = target->get_function()->
4395 get_genname_from_scope(my_scope);
4396 coding_by_function = true;
4397 } else {
4398 target->error("Only function is supported to do this mapping");
4399 }
4400 }
4401 }
4402 if (coding_str.empty()) {
4403 ea.warning("Extension attribute is found for %s but without "
4404 "typemappings", encode ? "encvalue" : "decvalue");
4405 }
4406 }
4407 break;
4408
4409 case Ttcn::ExtensionAttribute::ANYTYPELIST:
4410 break; // ignore (may be inherited from the module)
4411
4412 case Ttcn::ExtensionAttribute::NONE:
4413 break; // ignore erroneous attribute
4414
4415 default:
4416 ea.error("A type can only have type mapping extension attribute: "
4417 "in(...) or out(...)");
4418 break;
4419 }
4420 }
4421 delete extatrs;
4422 }
4423
4424 if (!coding_str.empty())
4425 return;
4426 end_ext:
4427
4428 const vector<SingleWithAttrib>& real_attribs
4429 = w_attrib_path->get_real_attrib();
4430 bool found = false;
4431 for (size_t i = real_attribs.size(); i > 0 && !found; i--) {
4432 if (real_attribs[i-1]->get_attribKeyword()
4433 == SingleWithAttrib::AT_ENCODE) {
4434 found = true;
4435 coding = get_enc_type(*real_attribs[i-1]);
4436 }
4437 }
4438 if (coding == CT_UNDEF) {
4439 // no "encode" attribute found
4440 error("No coding rule specified for type '%s'", get_typename().c_str());
4441 return;
4442 }
4443 if (coding != CT_CUSTOM && !has_encoding(coding)) {
4444 error("Type '%s' cannot be coded with the selected method '%s'",
4445 get_typename().c_str(),
4446 get_encoding_name(coding));
4447 return;
4448 }
4449 switch (coding) {
4450 case CT_RAW:
4451 coding_str = "RAW";
4452 break;
4453 case CT_TEXT:
4454 coding_str = "TEXT";
4455 break;
4456 case CT_PER:
4457 coding_str = "PER";
4458 break;
4459 case CT_XER:
4460 coding_str = "XER, XER_EXTENDED"; // TODO: fine tuning this parameter
4461 break;
4462 case CT_JSON:
4463 coding_str = "JSON";
4464 break;
4465 case CT_BER: {
4466 coding_str = "BER, ";
4467 BerAST* ber = berattrib;
4468 if (!ber) // use default settings if attributes are not specified
4469 ber = new BerAST;
4470 if (encode)
4471 coding_str += ber->get_encode_str();
4472 else
4473 coding_str += ber->get_decode_str();
4474 if (!berattrib)
4475 delete ber;
4476 break; }
4477 case CT_CUSTOM:
4478 if (!delayed) {
4479 // coding_str is set by the coding function's checker in this case;
4480 // it's possible, that the function exists, but has not been reached yet;
4481 // delay this function until everything else has been checked
4482 Modules::delay_type_encode_check(this, encode);
4483 }
4484 else if (coding_str.empty()) {
4485 // this is the delayed call, and the custom coding function has still
4486 // not been found
4487 error("No custom %s function found for type `%s'",
4488 encode ? "encoding" : "decoding", get_typename().c_str());
4489 }
4490 return;
4491 default:
4492 error("Unknown coding selected for type '%s'", get_typename().c_str());
4493 break;
4494 }
4495 coding_by_function = false;
4496 }
4497
4498 bool Type::is_coding_by_function() const {
4499 return coding_by_function;
4500 }
4501
4502 const string& Type::get_coding(bool encode) const {
4503 if (encode)
4504 return encoding_str;
4505 else
4506 return decoding_str;
4507 }
4508
4509 namespace { // unnamed
4510 const string ex_emm_ell("XML"), ex_ee_arr("XER");
4511 }
4512
4513 Type::MessageEncodingType_t Type::get_enc_type(const SingleWithAttrib& atr) {
4514 const string& enc = atr.get_attribSpec().get_spec();
4515 if (enc == "RAW")
4516 return CT_RAW;
4517 else if (enc == "TEXT")
4518 return CT_TEXT;
4519 else if (enc == "JSON")
4520 return CT_JSON;
4521 else if (enc == "BER:2002" || enc == "CER:2002" || enc == "DER:2002")
4522 return CT_BER;
4523 else if (enc == ex_emm_ell)
4524 return CT_XER;
4525 else if (enc == ex_ee_arr) {
4526 atr.warning("The correct name of the encoding is ''XML''");
4527 return CT_XER;
4528 }
4529 else if (enc == "PER")
4530 return CT_PER;
4531 else
4532 return CT_CUSTOM;
4533 }
4534 bool Type::has_ei_withName(const Identifier& p_id) const
4535 {
4536 switch (typetype) {
4537 case T_ENUM_T:
4538 case T_ENUM_A:
4539 if (checked) break;
4540 // no break
4541 default:
4542 FATAL_ERROR("Type::has_ei_withName()");
4543 }
4544 return u.enums.eis->has_ei_withName(p_id);
4545 }
4546
4547 EnumItem *Type::get_ei_byName(const Identifier& p_id) const
4548 {
4549 switch (typetype) {
4550 case T_ENUM_T:
4551 case T_ENUM_A:
4552 if (checked) break;
4553 // no break
4554 default:
4555 FATAL_ERROR("Type::get_ei_byName()");
4556 }
4557 return u.enums.eis->get_ei_byName(p_id);
4558 }
4559
4560 EnumItem *Type::get_ei_byIndex(size_t n) const
4561 {
4562 switch (typetype) {
4563 case T_ENUM_T:
4564 case T_ENUM_A:
4565 if (checked) break;
4566 // no break
4567 default:
4568 FATAL_ERROR("Type::get_ei_byIndex()");
4569 }
4570 return u.enums.eis->get_ei_byIndex(n);
4571 }
4572
4573 size_t Type::get_nof_comps()
4574 {
4575 switch(typetype) {
4576 case T_ANYTYPE:
4577 case T_CHOICE_T:
4578 case T_SEQ_T:
4579 case T_SET_T:
4580 case T_OPENTYPE:
4581 return u.secho.cfm->get_nof_comps();
4582 case T_SEQ_A:
4583 case T_SET_A:
4584 if(u.secho.block) parse_block_Se();
4585 return u.secho.ctss->get_nof_comps();
4586 case T_CHOICE_A:
4587 if(u.secho.block) parse_block_Choice();
4588 return u.secho.ctss->get_nof_comps();
4589 case T_ARRAY:
4590 return u.array.dimension->get_size();
4591 case T_SIGNATURE:
4592 if (u.signature.parameters)
4593 return u.signature.parameters->get_nof_params();
4594 else return 0;
4595 default:
4596 FATAL_ERROR("Type::get_nof_comps(%d)", typetype);
4597 return 0;
4598 } // switch
4599 }
4600
4601 const Identifier& Type::get_comp_id_byIndex(size_t n)
4602 {
4603 switch (typetype) {
4604 case T_ANYTYPE:
4605 case T_CHOICE_T:
4606 case T_SEQ_T:
4607 case T_SET_T:
4608 case T_OPENTYPE:
4609 return u.secho.cfm->get_comp_byIndex(n)->get_name();
4610 case T_SEQ_A:
4611 case T_SET_A:
4612 if(u.secho.block) parse_block_Se();
4613 return u.secho.ctss->get_comp_byIndex(n)->get_name();
4614 case T_CHOICE_A:
4615 if(u.secho.block) parse_block_Choice();
4616 return u.secho.ctss->get_comp_byIndex(n)->get_name();
4617 case T_SIGNATURE:
4618 return u.signature.parameters->get_param_byIndex(n)->get_id();
4619 default:
4620 FATAL_ERROR("Type::get_comp_id_byIndex()");
4621 } // switch
4622 // to avoid warnings
4623 const Identifier *fake = 0;
4624 return *fake;
4625 }
4626
4627 CompField* Type::get_comp_byIndex(size_t n)
4628 {
4629 switch(typetype) {
4630 case T_ANYTYPE:
4631 case T_CHOICE_T:
4632 case T_SEQ_T:
4633 case T_SET_T:
4634 case T_OPENTYPE:
4635 return u.secho.cfm->get_comp_byIndex(n);
4636 case T_SEQ_A:
4637 case T_SET_A:
4638 if(u.secho.block) parse_block_Se();
4639 return u.secho.ctss->get_comp_byIndex(n);
4640 case T_CHOICE_A:
4641 if(u.secho.block) parse_block_Choice();
4642 return u.secho.ctss->get_comp_byIndex(n);
4643 default:
4644 FATAL_ERROR("Type::get_comp_byIndex()");
4645 return 0;
4646 } // switch
4647 }
4648
4649 size_t Type::get_comp_index_byName(const Identifier& p_name)
4650 {
4651 Type *t = get_type_refd_last();
4652 if (!t->is_secho())
4653 FATAL_ERROR("Type::get_comp_index_byName()");
4654 if (!t->u.secho.field_by_name) {
4655 t->u.secho.field_by_name = new map<string, size_t>;
4656 size_t nof_comps = t->get_nof_comps();
4657 for (size_t i = 0; i < nof_comps; i++) {
4658 const string& field_name =
4659 t->get_comp_byIndex(i)->get_name().get_name();
4660 if (!t->u.secho.field_by_name->has_key(field_name))
4661 t->u.secho.field_by_name->add(field_name, new size_t(i));
4662 }
4663 }
4664 return *(*t->u.secho.field_by_name)[p_name.get_name()];
4665 }
4666
4667 size_t Type::get_eis_index_byName(const Identifier& p_name)
4668 {
4669 Type *t = get_type_refd_last();
4670 switch (t->typetype) {
4671 case T_ENUM_A:
4672 case T_ENUM_T:
4673 break;
4674 default:
4675 FATAL_ERROR("Type::get_eis_index_byName()");
4676 }
4677 if (!t->u.enums.eis_by_name) {
4678 t->u.enums.eis_by_name = new map<string, size_t>;
4679 size_t nof_eis = t->u.enums.eis->get_nof_eis();
4680 for (size_t i = 0; i < nof_eis; i++) {
4681 const string& enum_name =
4682 t->u.enums.eis->get_ei_byIndex(i)->get_name().get_name();
4683 if (!t->u.enums.eis_by_name->has_key(enum_name))
4684 t->u.enums.eis_by_name->add(enum_name, new size_t(i));
4685 }
4686 }
4687 return *(*t->u.enums.eis_by_name)[p_name.get_name()];
4688 }
4689
4690 const Int& Type::get_enum_val_byId(const Identifier& p_name)
4691 {
4692 if(!checked) FATAL_ERROR("Type::get_enum_val_byId(): Not checked.");
4693 switch(typetype) {
4694 case T_ENUM_T:
4695 case T_ENUM_A:
4696 break;
4697 default:
4698 FATAL_ERROR("Type::get_enum_val_byId()");
4699 }
4700 return u.enums.eis->get_ei_byName(p_name)->get_value()
4701 ->get_value_refd_last()->get_val_Int()->get_val();
4702 }
4703
4704 size_t Type::get_nof_root_comps()
4705 {
4706 switch(typetype) {
4707 case T_SEQ_A:
4708 case T_SET_A:
4709 if(u.secho.block) parse_block_Se();
4710 return u.secho.ctss->get_nof_root_comps();
4711 break;
4712 default:
4713 FATAL_ERROR("Type::get_nof_root_comps()");
4714 return 0;
4715 } // switch
4716 }
4717
4718 CompField* Type::get_root_comp_byIndex(size_t n)
4719 {
4720 switch(typetype) {
4721 case T_SEQ_A:
4722 case T_SET_A:
4723 if(u.secho.block) parse_block_Se();
4724 return u.secho.ctss->get_root_comp_byIndex(n);
4725 break;
4726 default:
4727 FATAL_ERROR("Type::get_root_comp_byIndex()");
4728 return 0;
4729 } // switch
4730 }
4731
4732 bool Type::has_comp_withName(const Identifier& p_name)
4733 {
4734 Type *t = get_type_refd_last();
4735 switch (t->typetype) {
4736 case T_CHOICE_T:
4737 case T_SEQ_T:
4738 case T_SET_T:
4739 case T_OPENTYPE:
4740 case T_ANYTYPE:
4741 return t->u.secho.cfm->has_comp_withName(p_name);
4742 case T_SEQ_A:
4743 case T_SET_A:
4744 if (t->u.secho.block) t->parse_block_Se();
4745 return t->u.secho.ctss->has_comp_withName(p_name);
4746 case T_CHOICE_A:
4747 if (t->u.secho.block) t->parse_block_Choice();
4748 return t->u.secho.ctss->has_comp_withName(p_name);
4749 case T_SIGNATURE:
4750 if (t->u.signature.parameters)
4751 return t->u.signature.parameters->has_param_withName(p_name);
4752 else return false;
4753 default:
4754 FATAL_ERROR("Type::has_comp_withName()");
4755 return 0;
4756 } // switch
4757 }
4758
4759 CompField* Type::get_comp_byName(const Identifier& p_name)
4760 {
4761 Type *t = get_type_refd_last();
4762 switch (t->typetype) {
4763 case T_CHOICE_T:
4764 case T_SEQ_T:
4765 case T_SET_T:
4766 case T_OPENTYPE:
4767 case T_ANYTYPE:
4768 return t->u.secho.cfm->get_comp_byName(p_name);
4769 case T_SEQ_A:
4770 case T_SET_A:
4771 if (t->u.secho.block) t->parse_block_Se();
4772 return t->u.secho.ctss->get_comp_byName(p_name);
4773 case T_CHOICE_A:
4774 if(t->u.secho.block) t->parse_block_Choice();
4775 return t->u.secho.ctss->get_comp_byName(p_name);
4776 default:
4777 FATAL_ERROR("Type::get_comp_byName()");
4778 return 0;
4779 } // switch
4780 }
4781
4782 void Type::add_comp(CompField *p_cf)
4783 {
4784 switch(typetype) {
4785 case T_CHOICE_T:
4786 case T_SEQ_T:
4787 case T_SET_T:
4788 case T_OPENTYPE:
4789 case T_ANYTYPE:
4790 u.secho.cfm->add_comp(p_cf);
4791 break;
4792 default:
4793 FATAL_ERROR("Type::add_comp()");
4794 } // switch
4795 }
4796
4797 Type *Type::get_ofType()
4798 {
4799 Type *t=get_type_refd_last();
4800 switch (t->typetype) {
4801 case T_SEQOF:
4802 case T_SETOF:
4803 return t->u.seof.ofType;
4804 case T_ARRAY:
4805 return t->u.array.element_type;
4806 default:
4807 FATAL_ERROR("Type::get_ofType()");
4808 return 0;
4809 }
4810 }
4811
4812 OC_defn* Type::get_my_oc()
4813 {
4814 switch(typetype) {
4815 case T_OCFT:
4816 return u.ref.oc_defn;
4817 break;
4818 case T_OPENTYPE:
4819 return u.secho.oc_defn;
4820 break;
4821 default:
4822 FATAL_ERROR("Type::get_my_oc()");
4823 return 0;
4824 } // switch
4825 }
4826
4827 const Identifier& Type::get_oc_fieldname()
4828 {
4829 switch(typetype) {
4830 case T_OCFT:
4831 return *u.ref.oc_fieldname;
4832 break;
4833 case T_OPENTYPE:
4834 return *u.secho.oc_fieldname;
4835 break;
4836 default:
4837 FATAL_ERROR("Type::get_oc_fieldname()");
4838 // to avoid warning...
4839 return *u.secho.oc_fieldname;
4840 } // switch
4841 }
4842
4843 void Type::set_my_tableconstraint(const TableConstraint *p_tc)
4844 {
4845 switch(typetype) {
4846 case T_OPENTYPE:
4847 u.secho.my_tableconstraint=p_tc;
4848 break;
4849 default:
4850 FATAL_ERROR("Type::set_my_tableconstraint()");
4851 } // switch
4852 }
4853
4854 const TableConstraint* Type::get_my_tableconstraint()
4855 {
4856 switch(typetype) {
4857 case T_OPENTYPE:
4858 return u.secho.my_tableconstraint;
4859 break;
4860 default:
4861 FATAL_ERROR("Type::get_my_tableconstraint()");
4862 return 0;
4863 } // switch
4864 }
4865
4866 Ttcn::ArrayDimension *Type::get_dimension() const
4867 {
4868 if (typetype != T_ARRAY) FATAL_ERROR("Type::get_dimension()");
4869 return u.array.dimension;
4870 }
4871
4872 Ttcn::PortTypeBody *Type::get_PortBody() const
4873 {
4874 if (typetype != T_PORT) FATAL_ERROR("Type::get_PortBody()");
4875 return u.port;
4876 }
4877
4878 ComponentTypeBody *Type::get_CompBody() const
4879 {
4880 if (typetype != T_COMPONENT) FATAL_ERROR("Type::get_CompBody()");
4881 return u.component;
4882 }
4883
4884 SignatureParamList *Type::get_signature_parameters() const
4885 {
4886 if (typetype != T_SIGNATURE || !checked)
4887 FATAL_ERROR("Type::get_signature_parameters()");
4888 return u.signature.parameters;
4889 }
4890
4891 SignatureExceptions *Type::get_signature_exceptions() const
4892 {
4893 if (typetype != T_SIGNATURE || !checked)
4894 FATAL_ERROR("Type::get_signature_exceptions()");
4895 return u.signature.exceptions;
4896 }
4897
4898 Type *Type::get_signature_return_type() const
4899 {
4900 if (typetype != T_SIGNATURE || !checked)
4901 FATAL_ERROR("Type::get_signature_return_type()");
4902 return u.signature.return_type;
4903 }
4904
4905 bool Type::is_nonblocking_signature() const
4906 {
4907 if (typetype != T_SIGNATURE || !checked)
4908 FATAL_ERROR("Type::is_nonblocking_signature()");
4909 return u.signature.no_block;
4910 }
4911
4912 Ttcn::FormalParList *Type::get_fat_parameters()
4913 {
4914 if(!checked) FATAL_ERROR("Type::get_fat_parameteres()");
4915 switch(typetype) {
4916 case T_FUNCTION:
4917 case T_ALTSTEP:
4918 case T_TESTCASE:
4919 return u.fatref.fp_list;
4920 default:
4921 FATAL_ERROR("Type::get_fat_parameteres()");
4922 return 0;
4923 }
4924 }
4925
4926 Type *Type::get_function_return_type()
4927 {
4928 if(!checked) FATAL_ERROR("Type::get_function_return_type()");
4929 switch(typetype) {
4930 case T_FUNCTION:
4931 return u.fatref.return_type;
4932 default:
4933 FATAL_ERROR("Type::get_function_return_type()");
4934 return 0;
4935 }
4936 }
4937
4938 Type *Type::get_fat_runs_on_type()
4939 {
4940 if(!checked) FATAL_ERROR("Type::get_fat_runs_on_type()");
4941 switch(typetype) {
4942 case T_FUNCTION:
4943 case T_ALTSTEP:
4944 case T_TESTCASE:
4945 return u.fatref.runs_on.type;
4946 default:
4947 FATAL_ERROR("Type::get_fat_runs_on_type()");
4948 return 0;
4949 }
4950 }
4951
4952 bool Type::get_fat_runs_on_self()
4953 {
4954 if(!checked) FATAL_ERROR("Type::get_fat_runs_on_self()");
4955 switch(typetype) {
4956 case T_FUNCTION:
4957 case T_ALTSTEP:
4958 case T_TESTCASE:
4959 return u.fatref.runs_on.self;
4960 default:
4961 FATAL_ERROR("Type::get_fat_runs_on_self()");
4962 return false;
4963 }
4964 }
4965
4966 bool Type::get_returns_template()
4967 {
4968 if (!checked || typetype != T_FUNCTION)
4969 FATAL_ERROR("Type::Returns_template()");
4970 return u.fatref.returns_template;
4971 }
4972
4973 void Type::add_tag(Tag *p_tag)
4974 {
4975 if(!tags) tags=new Tags();
4976 tags->add_tag(p_tag);
4977 }
4978
4979 void Type::add_constraints(Constraints *p_constraints)
4980 {
4981 if(!p_constraints) return;
4982 if(constraints)
4983 FATAL_ERROR("This type already has its constraints");
4984 constraints=p_constraints;
4985 constraints->set_my_type(this);
4986 }
4987
4988 Reference* Type::get_Reference()
4989 {
4990 return u.ref.ref;
4991 }
4992
4993 void Type::chk_table_constraints()
4994 {
4995 if(!tbl_cons_checked) {
4996 tbl_cons_checked=true;
4997 if (constraints) constraints->chk_table();
4998 switch (typetype) {
4999 case T_CHOICE_A:
5000 case T_CHOICE_T:
5001 case T_SEQ_A:
5002 case T_SEQ_T:
5003 case T_SET_A:
5004 case T_SET_T:
5005 case T_OPENTYPE:
5006 for(size_t i=0; i<get_nof_comps(); i++)
5007 get_comp_byIndex(i)->get_type()->chk_table_constraints();
5008 break;
5009 case T_SEQOF:
5010 case T_SETOF:
5011 u.seof.ofType->chk_table_constraints();
5012 break;
5013 default:
5014 break;
5015 }
5016 }
5017 }
5018
5019 void Type::check_subtype_constraints()
5020 {
5021 if (sub_type!=NULL) FATAL_ERROR("Type::check_subtype_constraints()");
5022
5023 // get parent subtype or NULL if it doesn't exist
5024 SubType* parent_subtype = NULL;
5025 if (is_ref()) parent_subtype = get_type_refd()->sub_type;
5026
5027 // if the parent subtype is erroneous then ignore it, the error was already
5028 // reported there
5029 if ( (parent_subtype!=NULL) &&
5030 (parent_subtype->get_subtypetype()==SubtypeConstraint::ST_ERROR) )
5031 parent_subtype = NULL;
5032
5033 // return if there are neither inherited nor own constraints
5034 if ( (parent_subtype==NULL) && (parsed_restr==NULL) && (constraints==NULL)
5035 && (SubtypeConstraint::get_asn_type_constraint(this)==NULL) ) return;
5036
5037 // the subtype type is determined by the type of this type
5038 if (get_type_refd_last()->get_typetype()==T_ERROR) return;
5039 SubtypeConstraint::subtype_t s_t = get_subtype_type();
5040 if (s_t==SubtypeConstraint::ST_ERROR) {
5041 error("Subtype constraints are not applicable to type `%s'",
5042 get_typename().c_str());
5043 return;
5044 }
5045
5046 // create the aggregate subtype for this type
5047 sub_type = new SubType(s_t, this, parent_subtype, parsed_restr, constraints);
5048 sub_type->chk();
5049 }
5050
5051 bool Type::has_multiple_tags()
5052 {
5053 if (tags) return false;
5054 switch (typetype) {
5055 case T_CHOICE_A:
5056 case T_CHOICE_T:
5057 return true;
5058 case T_REFD:
5059 case T_SELTYPE:
5060 case T_REFDSPEC:
5061 case T_OCFT:
5062 return get_type_refd()->has_multiple_tags();
5063 default:
5064 return false;
5065 }
5066 }
5067
5068 Tag *Type::get_tag()
5069 {
5070 if (tags) {
5071 Tag *tag=tags->get_tag_byIndex(tags->get_nof_tags()-1);
5072 tag->chk();
5073 return tag;
5074 }
5075 else return get_default_tag();
5076 }
5077
5078 void Type::get_tags(TagCollection& coll, map<Type*, void>& chain)
5079 {
5080 if(typetype!=T_CHOICE_A)
5081 FATAL_ERROR("Type::get_tags()");
5082 if (chain.has_key(this)) return;
5083 chain.add(this, 0);
5084 if(u.secho.block) parse_block_Choice();
5085 size_t n_alts = u.secho.ctss->get_nof_comps();
5086 for(size_t i=0; i<n_alts; i++) {
5087 CompField *cf = u.secho.ctss->get_comp_byIndex(i);
5088 Type *type = cf->get_type();
5089 if(type->has_multiple_tags()) {
5090 type=type->get_type_refd_last();
5091 type->get_tags(coll, chain);
5092 }
5093 else {
5094 const Tag *tag=type->get_tag();
5095 if(coll.hasTag(tag))
5096 error("Alternative `%s' in CHOICE has non-distinct tag",
5097 cf->get_name().get_dispname().c_str());
5098 else coll.addTag(tag);
5099 }
5100 } // for i
5101 if(u.secho.ctss->has_ellipsis()) coll.setExtensible();
5102 }
5103
5104 Tag *Type::get_smallest_tag()
5105 {
5106 if(!has_multiple_tags()) return get_tag()->clone();
5107 Type *t=get_type_refd_last();
5108 TagCollection tagcoll;
5109 map<Type*, void> chain;
5110 t->get_tags(tagcoll, chain);
5111 chain.clear();
5112 return tagcoll.getSmallestTag()->clone();
5113 }
5114
5115 bool Type::needs_explicit_tag()
5116 {
5117 switch (typetype) {
5118 case T_CHOICE_A:
5119 case T_CHOICE_T:
5120 case T_ANY:
5121 case T_OPENTYPE:
5122 return true;
5123 case T_REFD: {
5124 if(!dynamic_cast<Asn::Ref_pard*>(u.ref.ref)) {
5125 Scope *s=u.ref.ref->get_refd_assignment()->get_my_scope();
5126 if(s->get_parent_scope()!=s->get_scope_mod()) {
5127 // Not in the module scope, so it is a dummyreference (X.680
5128 // 30.6c)
5129 /*
5130 WARNING("%s is a dummyreference, i give him an explicit tag :)",
5131 get_fullname().c_str());
5132 WARNING("0: %s", s->get_scope_name().c_str());
5133 WARNING("1: %s", s->get_parent_scope()->get_scope_name().c_str());
5134 WARNING("2: %s", s->get_scope_mod()->get_scope_name().c_str());
5135 */
5136 return true;
5137 }
5138 }
5139 // no break;
5140 } // case T_REFD
5141 case T_SELTYPE:
5142 case T_REFDSPEC:
5143 case T_OCFT: {
5144 Type *t = get_type_refd();
5145 if(t->is_tagged()) return false;
5146 else return t->needs_explicit_tag();
5147 break;}
5148 default:
5149 // T_ANYTYPE probably does not need explicit tagging
5150 return false;
5151 }
5152 }
5153
5154 void Type::cut_auto_tags()
5155 {
5156 if (tags) {
5157 tags->cut_auto_tags();
5158 if (tags->get_nof_tags() == 0) {
5159 delete tags;
5160 tags = 0;
5161 }
5162 }
5163 }
5164
5165 /**
5166 * I suppose in this function that tags->chk() and
5167 * tags->set_plicit() are already done.
5168 */
5169 Tags* Type::build_tags_joined(Tags *p_tags)
5170 {
5171 if(!p_tags) p_tags=new Tags();
5172 switch(typetype) {
5173 // is_ref() true:
5174 case T_REFD:
5175 case T_SELTYPE:
5176 case T_REFDSPEC:
5177 case T_OCFT:
5178 get_type_refd()->build_tags_joined(p_tags);
5179 break;
5180 case T_CHOICE_A:
5181 case T_CHOICE_T:
5182 //TODO case T_ANYTYPE: for build_tags_joined ?
5183 case T_OPENTYPE:
5184 case T_ANY:
5185 break;
5186 default:
5187 p_tags->add_tag(get_default_tag()->clone());
5188 break;
5189 } // switch
5190 if(tags) {
5191 for(size_t i=0; i<tags->get_nof_tags(); i++) {
5192 Tag *tag=tags->get_tag_byIndex(i);
5193 switch(tag->get_plicit()) {
5194 case Tag::TAG_EXPLICIT:
5195 p_tags->add_tag(tag->clone());
5196 break;
5197 case Tag::TAG_IMPLICIT: {
5198 Tag *t_p_tag=p_tags->get_tag_byIndex(p_tags->get_nof_tags()-1);
5199 t_p_tag->set_tagclass(tag->get_tagclass());
5200 t_p_tag->set_tagvalue(tag->get_tagvalue());
5201 break;}
5202 default:
5203 FATAL_ERROR("Type::build_tags_joined()");
5204 } // switch
5205 } // for
5206 } // if tags
5207 return p_tags;
5208 }
5209
5210 void Type::set_with_attr(Ttcn::MultiWithAttrib* p_attrib)
5211 {
5212 if(!w_attrib_path)
5213 {
5214 w_attrib_path = new WithAttribPath();
5215 }
5216
5217 w_attrib_path->set_with_attr(p_attrib);
5218 }
5219
5220 void Type::set_parent_path(WithAttribPath* p_path)
5221 {
5222 if(!w_attrib_path)
5223 {
5224 w_attrib_path = new WithAttribPath();
5225 }
5226 w_attrib_path->set_parent(p_path);
5227 if (typetype == T_COMPONENT)
5228 u.component->set_parent_path(w_attrib_path);
5229 }
5230
5231 WithAttribPath* Type::get_attrib_path() const
5232 {
5233 return w_attrib_path;
5234 }
5235
5236 bool Type::hasRawAttrs()
5237 {
5238 if(rawattrib) return true;
5239
5240 if(w_attrib_path)
5241 {
5242 if(w_attrib_path->get_had_global_variants()) return true;
5243
5244 vector<SingleWithAttrib> const &real_attribs
5245 = w_attrib_path->get_real_attrib();
5246
5247 for (size_t i = 0; i < real_attribs.size(); i++)
5248 if (real_attribs[i]->get_attribKeyword()
5249 == SingleWithAttrib::AT_VARIANT)
5250 {
5251 return true;
5252 }
5253
5254 MultiWithAttrib* temp_attrib = w_attrib_path->get_with_attr();
5255 if(temp_attrib)
5256 for(size_t i = 0; i < temp_attrib->get_nof_elements(); i++)
5257 if(temp_attrib->get_element(i)->get_attribKeyword()
5258 == SingleWithAttrib::AT_VARIANT
5259 && (!temp_attrib->get_element(i)->get_attribQualifiers()
5260 || temp_attrib->get_element(i)->get_attribQualifiers()
5261 ->get_nof_qualifiers() == 0))
5262 {
5263 w_attrib_path->set_had_global_variants( true );
5264 return true;
5265 }
5266 }
5267
5268 return false;
5269 }
5270
5271 bool Type::hasNeedofRawAttrs()
5272 {
5273 if(rawattrib) return true;
5274 size_t nof_comps;
5275 switch(typetype){
5276 case T_CHOICE_T:
5277 case T_ANYTYPE:
5278 case T_SEQ_T:
5279 case T_SET_T:
5280 nof_comps = get_nof_comps();
5281 for(size_t i=0; i < nof_comps; i++)
5282 {
5283 if(get_comp_byIndex(i)->get_type()->hasNeedofRawAttrs())
5284 {
5285 return true;
5286 }
5287 }
5288 break;
5289 default:
5290 break;
5291 }
5292 return false;
5293 }
5294
5295 bool Type::hasNeedofTextAttrs()
5296 {
5297 if(textattrib) return true;
5298 size_t nof_comps;
5299 switch(typetype){
5300 case T_CHOICE_T:
5301 case T_ANYTYPE:
5302 case T_SEQ_T:
5303 case T_SET_T:
5304 nof_comps = get_nof_comps();
5305 for(size_t i=0; i < nof_comps; i++)
5306 {
5307 if(get_comp_byIndex(i)->get_type()->hasNeedofTextAttrs())
5308 {
5309 return true;
5310 }
5311 }
5312 break;
5313 default:
5314 break;
5315 }
5316 return false;
5317 }
5318
5319 bool Type::hasNeedofJsonAttrs()
5320 {
5321 if(jsonattrib) return true;
5322 size_t nof_comps;
5323 switch(typetype) {
5324 case T_CHOICE_T:
5325 case T_ANYTYPE:
5326 case T_SEQ_T:
5327 case T_SET_T:
5328 nof_comps = get_nof_comps();
5329 for (size_t i = 0; i < nof_comps; ++i)
5330 {
5331 if (get_comp_byIndex(i)->get_type()->hasNeedofJsonAttrs())
5332 {
5333 return true;
5334 }
5335 }
5336 break;
5337 default:
5338 break;
5339 }
5340 return false;
5341 }
5342
5343 bool Type::hasNeedofXerAttrs()
5344 {
5345 if(xerattrib && !xerattrib->empty()) return true;
5346 size_t nof_comps;
5347 switch(typetype){
5348 case T_CHOICE_T:
5349 case T_ANYTYPE:
5350 case T_SEQ_T:
5351 case T_SET_T:
5352 nof_comps = get_nof_comps();
5353 for(size_t i=0; i < nof_comps; i++)
5354 {
5355 if(get_comp_byIndex(i)->get_type()->hasNeedofXerAttrs())
5356 {
5357 return true;
5358 }
5359 }
5360 break;
5361 default:
5362 break;
5363 }
5364 return false;
5365 }
5366
5367 bool Type::hasVariantAttrs()
5368 {
5369 if(w_attrib_path)
5370 {
5371 if(w_attrib_path->get_had_global_variants()) return true;
5372
5373 vector<SingleWithAttrib> const &real_attribs
5374 = w_attrib_path->get_real_attrib();
5375
5376 for (size_t i = 0; i < real_attribs.size(); i++)
5377 if (real_attribs[i]->get_attribKeyword()
5378 == SingleWithAttrib::AT_VARIANT)
5379 {
5380 return true;
5381 }
5382
5383 MultiWithAttrib* temp_attrib = w_attrib_path->get_with_attr();
5384 if(temp_attrib)
5385 for(size_t i = 0; i < temp_attrib->get_nof_elements(); i++)
5386 if(temp_attrib->get_element(i)->get_attribKeyword()
5387 == SingleWithAttrib::AT_VARIANT
5388 && (!temp_attrib->get_element(i)->get_attribQualifiers()
5389 || temp_attrib->get_element(i)->get_attribQualifiers()
5390 ->get_nof_qualifiers() != 0))
5391 {
5392 w_attrib_path->set_had_global_variants( true );
5393 return true;
5394 }
5395 }
5396
5397 return false;
5398 }
5399
5400 bool Type::hasEncodeAttr(const char* encoding_name)
5401 {
5402 if (0 == strcmp(encoding_name, "JSON") && (implicit_json_encoding
5403 || is_asn1() || (is_ref() && get_type_refd()->is_asn1()))) {
5404 // ASN.1 types automatically support JSON encoding
5405 return true;
5406 }
5407 // Check the type itself first, then the root type
5408 WithAttribPath *aps[2] = { 0, 0 };
5409 size_t num_aps = ((aps[0] = get_attrib_path()) != 0);
5410 // assign, compare, then add 0 or 1
5411 if (is_ref()) {
5412 num_aps += ((aps[num_aps] = get_type_refd()->get_attrib_path()) != 0);
5413 }
5414 for (size_t a = 0; a < num_aps; ++a) {
5415 const vector<SingleWithAttrib>& real = aps[a]->get_real_attrib();
5416 const size_t num_atr = real.size();
5417 for (size_t i = 0; i < num_atr; ++i) {
5418 const SingleWithAttrib& s = *real[i];
5419 if (s.get_attribKeyword() == SingleWithAttrib::AT_ENCODE) {
5420 const string& spec = s.get_attribSpec().get_spec();
5421 if (spec == encoding_name) {
5422 return true;
5423 }
5424 } // if ENCODE
5425 } // for
5426 } // next a
5427 return false;
5428 }
5429
5430 namespace { // unnamed
5431
5432 enum state { PROCESSING = -1, ANSWER_NO, ANSWER_YES };
5433
5434 struct memoizer : private map<Type*, state> {
5435 memoizer() : map<Type*, state>() {}
5436
5437 ~memoizer() {
5438 for (int i = size()-1; i >= 0; --i) {
5439 delete get_nth_elem(i);
5440 }
5441 clear();
5442 }
5443
5444 bool remember (Type *t, state s) {
5445 if (has_key(t)) {
5446 *operator[](t) = s;
5447 }
5448 else {
5449 add(t, new state(s));
5450 }
5451 return s == ANSWER_YES;
5452 }
5453
5454 bool has_key(Type *t) {
5455 return map<Type*, state>::has_key(t);
5456 }
5457
5458 state* get(Type *t) {
5459 return operator [](t);
5460 }
5461 };
5462
5463 }
5464
5465 bool Type::has_encoding(MessageEncodingType_t encoding_type, const string* custom_encoding /* = NULL */)
5466 {
5467 static memoizer memory;
5468 static memoizer json_mem;
5469 Type *t = this;
5470 switch (encoding_type) {
5471 case CT_BER:
5472 case CT_PER:
5473 for ( ; ; ) {
5474 if (t->is_asn1()) return true;
5475 else if (t->is_ref()) t = t->get_type_refd();
5476 else {
5477 switch (t->typetype) {
5478 case T_ERROR:
5479 case T_BOOL:
5480 case T_INT:
5481 case T_REAL:
5482 case T_BSTR:
5483 case T_OSTR:
5484 case T_OID:
5485 // these basic TTCN-3 types have ASN.1 equivalents
5486 return true;
5487 default:
5488 return false;
5489 }
5490 }
5491 }
5492
5493 case CT_XER: {
5494 if (memory.has_key(this)) {
5495 state *s = memory.get(this);
5496 switch (*s){
5497 case PROCESSING:
5498 break;
5499 case ANSWER_NO:
5500 return false;
5501 case ANSWER_YES:
5502 return true;
5503 }
5504 }
5505
5506 for (;;) {
5507 // For ASN.1 types, the answer depends solely on the -a switch.
5508 // They are all considered to have Basic (i.e. useless) XER,
5509 // unless the -a switch says removes XER from all ASN.1 types.
5510 if (t->is_asn1()) return memory.remember(t,
5511 asn1_xer ? ANSWER_YES : ANSWER_NO);
5512 else if (t->is_ref()) t = t->get_type_refd();
5513 else { // at the end of the ref. chain
5514 switch (t->typetype) {
5515 case T_BOOL:
5516 case T_INT:
5517 case T_REAL:
5518 case T_BSTR:
5519 case T_OSTR:
5520 // The octetstring type can always be encoded in XER.
5521 // XSD:base64Binary is only needed for Type::is_charenc()
5522 case T_OID:
5523 case T_HSTR: // TTCN-3 hexstring
5524 case T_VERDICT: // TTCN-3 verdict
5525 case T_CSTR: // TTCN3 charstring
5526 case T_USTR: // TTCN3 universal charstring
5527 return memory.remember(t, ANSWER_YES);
5528
5529 case T_ENUM_T:
5530 break; // the switch; skip to checking if it has encode "XML";
5531
5532 case T_PORT: // TTCN-3 port (the list of in's, out's, inout's)
5533 case T_COMPONENT: // TTCN-3 comp. type (extends, and { ... })
5534 case T_DEFAULT: // TTCN-3
5535 case T_SIGNATURE: // TTCN-3
5536 case T_FUNCTION: // TTCN-3
5537 case T_ALTSTEP: // TTCN-3
5538 case T_TESTCASE: // TTCN-3
5539 case T_ANYTYPE: // TTCN-3 anytype
5540 return memory.remember(t, ANSWER_NO);
5541
5542 case T_UNDEF:
5543 case T_ERROR:
5544 case T_REFDSPEC:
5545 return false; // why don't we remember these ?
5546
5547 case T_SEQ_T:
5548 case T_SET_T:
5549 case T_CHOICE_T: {
5550 // No field may reject XER
5551 size_t ncomp = t->get_nof_comps();
5552 for (size_t i = 0; i < ncomp; ++i) {
5553 Type *t2 = t->get_comp_byIndex(i)->get_type();
5554 bool subresult = false;
5555 if (memory.has_key(t2)) {
5556 switch (*memory.get(t2)) {
5557 case PROCESSING:
5558 // This type contains itself and is in the process
5559 // of being checked. Pretend it doesn't exist.
5560 // The answer will be determined by the other fields,
5561 // and it will propagate back up.
5562 // Avoids infinite recursion for self-referencing types.
5563 continue;
5564 case ANSWER_NO:
5565 subresult = false;
5566 break;
5567 case ANSWER_YES:
5568 subresult = true;
5569 break;
5570 }
5571 }
5572 else {
5573 memory.remember(t2, PROCESSING);
5574 subresult = t2->has_encoding(CT_XER);
5575 }
5576
5577 if (subresult) memory.remember(t2, ANSWER_YES);
5578 else return memory.remember(t2, ANSWER_NO);
5579 // Note: return only if the answer (false) is known.
5580 // If the answer is true, keep checking.
5581 } // next i
5582 // Empty record, or all fields supported XER: answer maybe yes.
5583 break; }
5584
5585 case T_SEQOF:
5586 case T_SETOF: {
5587 bool subresult = false;
5588 Type *t2 = t->u.seof.ofType;
5589 if (memory.has_key(t2)) {
5590 switch (*memory.get(t2)) {
5591 case PROCESSING:
5592 // Recursive record-of. This is OK because the recursion
5593 // can always be broken with an empty record-of.
5594 subresult = true;
5595 break;
5596 case ANSWER_NO:
5597 subresult = false;
5598 break;
5599 case ANSWER_YES:
5600 subresult = true;
5601 break;
5602 }
5603 }
5604 else {
5605 memory.remember(t2, PROCESSING);
5606 // Check the contained type
5607 subresult = t2->has_encoding(CT_XER);
5608 }
5609 if (subresult) break; // continue checking
5610 else return memory.remember(t, ANSWER_NO); // No means no.
5611 }
5612
5613 case T_NULL: // ASN.1 null
5614 case T_INT_A: // ASN.1 integer
5615 case T_ENUM_A:// ASN.1 enum
5616 case T_BSTR_A:// ASN.1 bitstring
5617 case T_UTF8STRING: // ASN.1
5618 case T_NUMERICSTRING:
5619 case T_PRINTABLESTRING:
5620 case T_TELETEXSTRING:
5621 case T_VIDEOTEXSTRING:
5622 case T_IA5STRING:
5623 case T_GRAPHICSTRING:
5624 case T_VISIBLESTRING:
5625 case T_GENERALSTRING:
5626 case T_UNIVERSALSTRING:
5627 case T_BMPSTRING:
5628 case T_UNRESTRICTEDSTRING: // still ASN.1
5629 case T_UTCTIME: // ASN.1 string
5630 case T_GENERALIZEDTIME: // ASN.1 string
5631 case T_OBJECTDESCRIPTOR: // ASN.1 string
5632 case T_ROID: // relative OID (ASN.1)
5633
5634 case T_CHOICE_A: //
5635 case T_SEQ_A: // ASN.1 versions of choice,sequence,set
5636 case T_SET_A: //
5637
5638 case T_OCFT: // ObjectClassFieldType (ASN.1)
5639 case T_OPENTYPE: // ASN.1 open type
5640 case T_ANY: // deprecated ASN.1 ANY
5641
5642 case T_EXTERNAL: // ASN.1 external
5643 case T_EMBEDDED_PDV: // ASN.1 embedded pdv
5644 case T_SELTYPE: // selection type (ASN.1)
5645 FATAL_ERROR("Type::has_encoding(): typetype %d should be asn1",
5646 t->typetype);
5647 break; // not reached
5648
5649 case T_REFD: // reference to another type
5650 case T_ADDRESS: // TTCN-3 address type
5651 case T_ARRAY: // TTCN-3 array
5652 default: // FIXME: if compiling with -Wswitch, the default should be removed
5653 return memory.remember(t, ANSWER_NO);
5654 } // switch t->typetype
5655
5656 // Check to see if it has an encode "XML"; first the type itself,
5657 // then the root type.
5658 WithAttribPath *aps[2] = {0,0};
5659 size_t num_aps = ((aps[0] = this->get_attrib_path()) != 0);
5660 // assign, compare, then add 0 or 1
5661 if (this != t) {
5662 num_aps += ((aps[num_aps] = t->get_attrib_path()) != 0);
5663 }
5664 for (size_t a = 0; a < num_aps; ++a) {
5665 const vector<SingleWithAttrib>& real = aps[a]->get_real_attrib();
5666 const size_t num_atr = real.size();
5667 for (size_t i = 0; i < num_atr; ++i) {
5668 const SingleWithAttrib& s = *real[i];
5669 if (s.get_attribKeyword() == SingleWithAttrib::AT_ENCODE) {
5670 const string& spec = s.get_attribSpec().get_spec();
5671 if (spec == ex_emm_ell // the right answer
5672 ||spec == ex_ee_arr) // the acceptable answer
5673 return memory.remember(t, ANSWER_YES);
5674 } // if ENCODE
5675 } // for
5676 } // next a
5677 return memory.remember(t, ANSWER_NO); // no encode XER
5678 } // if(!asn1)
5679 } // for(ever)
5680 return memory.remember(t, ANSWER_NO); }
5681
5682 case CT_RAW:
5683 for ( ; ; ) {
5684 if (t->rawattrib) return true;
5685 else if (t->is_ref()) t = t->get_type_refd();
5686 else {
5687 switch (t->typetype) {
5688 case T_ERROR:
5689 case T_BOOL:
5690 case T_INT:
5691 case T_REAL:
5692 case T_BSTR:
5693 case T_HSTR:
5694 case T_OSTR:
5695 case T_CSTR:
5696 // these basic types support RAW encoding by default
5697 return true;
5698 default:
5699 return false;
5700 }
5701 }
5702 }
5703
5704 case CT_TEXT:
5705 for ( ; ; ) {
5706 if (t->textattrib) return true;
5707 else if (t->is_ref()) t = t->get_type_refd();
5708 else {
5709 switch (t->typetype) {
5710 case T_ERROR:
5711 case T_BOOL:
5712 case T_INT:
5713 case T_OSTR:
5714 case T_CSTR:
5715 case T_USTR: // TTCN3 universal charstring
5716 // these basic types support TEXT encoding by default
5717 return true;
5718 default:
5719 return false;
5720 }
5721 }
5722 }
5723
5724 case CT_JSON:
5725 while (true) {
5726 if (json_mem.has_key(t)) {
5727 switch (*json_mem.get(t)) {
5728 case PROCESSING:
5729 break;
5730 case ANSWER_NO:
5731 return false;
5732 case ANSWER_YES:
5733 return true;
5734 }
5735 }
5736 if (t->jsonattrib) {
5737 return json_mem.remember(t, ANSWER_YES);
5738 }
5739 if (t->is_ref()) {
5740 t = t->get_type_refd();
5741 }
5742 else {
5743 switch (t->typetype) {
5744 case T_ERROR:
5745 case T_BOOL:
5746 case T_INT:
5747 case T_INT_A:
5748 case T_REAL:
5749 case T_BSTR:
5750 case T_BSTR_A:
5751 case T_HSTR:
5752 case T_OSTR:
5753 case T_CSTR:
5754 case T_USTR:
5755 case T_UTF8STRING:
5756 case T_NUMERICSTRING:
5757 case T_PRINTABLESTRING:
5758 case T_TELETEXSTRING:
5759 case T_VIDEOTEXSTRING:
5760 case T_IA5STRING:
5761 case T_GRAPHICSTRING:
5762 case T_VISIBLESTRING:
5763 case T_GENERALSTRING:
5764 case T_UNIVERSALSTRING:
5765 case T_BMPSTRING:
5766 case T_VERDICT:
5767 case T_NULL:
5768 case T_OID:
5769 case T_ROID:
5770 case T_ANY:
5771 // these basic types support JSON encoding by default
5772 return json_mem.remember(t, ANSWER_YES);
5773 case T_SEQ_T:
5774 case T_SEQ_A:
5775 case T_OPENTYPE:
5776 case T_SET_T:
5777 case T_SET_A:
5778 case T_CHOICE_T:
5779 case T_CHOICE_A:
5780 case T_ANYTYPE: {
5781 // all fields must also support JSON encoding
5782 size_t ncomp = t->get_nof_comps();
5783 for (size_t i = 0; i < ncomp; ++i) {
5784 Type *t2 = t->get_comp_byIndex(i)->get_type();
5785 if (json_mem.has_key(t2)) {
5786 switch (*json_mem.get(t2)) {
5787 case ANSWER_YES:
5788 // This field is OK, but we still need to check the others
5789 case PROCESSING:
5790 // This type contains itself and is in the process
5791 // of being checked. Pretend it doesn't exist.
5792 // The answer will be determined by the other fields,
5793 // and it will propagate back up.
5794 // Avoids infinite recursion for self-referencing types.
5795 continue;
5796 case ANSWER_NO:
5797 // One field is not OK => the structure is not OK
5798 return json_mem.remember(t, ANSWER_NO);
5799 }
5800 }
5801 else {
5802 json_mem.remember(t2, PROCESSING);
5803 bool enabled = t2->has_encoding(CT_JSON);
5804 json_mem.remember(t2, enabled ? ANSWER_YES : ANSWER_NO);
5805 if (!enabled) {
5806 // One field is not OK => the structure is not OK
5807 return json_mem.remember(t, ANSWER_NO);
5808 }
5809 }
5810 }
5811 break; // check for an encode attribute
5812 }
5813 case T_SEQOF:
5814 case T_SETOF:
5815 case T_ARRAY: {
5816 Type *t2 = t->u.seof.ofType;
5817 if (json_mem.has_key(t2)) {
5818 switch (*json_mem.get(t2)) {
5819 case ANSWER_YES:
5820 // Continue checking
5821 case PROCESSING:
5822 // Recursive record-of. This is OK because the recursion
5823 // can always be broken with an empty record-of.
5824 break;
5825 case ANSWER_NO:
5826 return json_mem.remember(t, ANSWER_NO);
5827 break;
5828 }
5829 }
5830 else {
5831 json_mem.remember(t2, PROCESSING);
5832 bool enabled = t2->has_encoding(CT_JSON);
5833 json_mem.remember(t2, enabled ? ANSWER_YES : ANSWER_NO);
5834 if (!enabled) {
5835 // One field is not OK => the structure is not OK
5836 return json_mem.remember(t, ANSWER_NO);
5837 }
5838 }
5839 break; // check for an encode attribute
5840 }
5841 case T_ENUM_T:
5842 case T_ENUM_A:
5843 break; // check for an encode attribute
5844 default:
5845 return json_mem.remember(t, ANSWER_NO);
5846 } // switch
5847 return json_mem.remember(t, hasEncodeAttr(get_encoding_name(CT_JSON)) ? ANSWER_YES : ANSWER_NO);
5848 } // else
5849 } // while
5850
5851 case CT_CUSTOM:
5852 // the encoding name parameter has to be the same as the encoding name
5853 // specified for the type
5854 return custom_encoding ? hasEncodeAttr(custom_encoding->c_str()) : false;
5855
5856 default:
5857 FATAL_ERROR("Type::has_encoding()");
5858 return false;
5859 }
5860 }
5861
5862
5863 bool Type::is_pure_refd()
5864 {
5865 switch (typetype) {
5866 case T_REFD:
5867 // ASN.1 parameterized references are not pure :)
5868 if(dynamic_cast<Asn::Ref_pard*>(u.ref.ref)) return false;
5869 // no break;
5870 case T_REFDSPEC:
5871 case T_SELTYPE:
5872 case T_OCFT:
5873 if (sub_type || constraints) return false;
5874 else if (tags && enable_ber()) return false;
5875 else if (rawattrib && enable_raw()) return false;
5876 else if (textattrib && enable_text()) return false;
5877 else if (enable_xer()) return false;
5878 else if (jsonattrib && enable_json()) return false;
5879 else return true;
5880 default:
5881 return false;
5882 }
5883 }
5884
5885 string Type::create_stringRepr()
5886 {
5887 if(is_tagged() || hasRawAttrs())
5888 return get_genname_own();
5889 switch(typetype) {
5890 case T_NULL:
5891 return string("NULL");
5892 case T_BOOL:
5893 return string("BOOLEAN");
5894 case T_INT:
5895 case T_INT_A:
5896 return string("INTEGER");
5897 case T_REAL:
5898 return string("REAL");
5899 case T_BSTR:
5900 case T_BSTR_A:
5901 return string("BIT__STRING");
5902 case T_HSTR:
5903 return string("HEX__STRING");
5904 case T_OSTR:
5905 return string("OCTET__STRING");
5906 case T_CSTR:
5907 return string("CHAR__STRING");
5908 case T_USTR:
5909 return string("UNIVERSAL__CHARSTRING");
5910 case T_UTF8STRING:
5911 return string("UTF8String");
5912 case T_NUMERICSTRING:
5913 return string("NumericString");
5914 case T_PRINTABLESTRING:
5915 return string("PrintableString");
5916 case T_TELETEXSTRING:
5917 return string("TeletexString");
5918 case T_VIDEOTEXSTRING:
5919 return string("VideotexString");
5920 case T_IA5STRING:
5921 return string("IA5String");
5922 case T_GRAPHICSTRING:
5923 return string("GraphicString");
5924 case T_VISIBLESTRING:
5925 return string("VisibleString");
5926 case T_GENERALSTRING:
5927 return string("GeneralString");
5928 case T_UNIVERSALSTRING:
5929 return string("UniversalString");
5930 case T_BMPSTRING:
5931 return string("BMPString");
5932 case T_UNRESTRICTEDSTRING:
5933 return string("CHARACTER__STRING");
5934 case T_UTCTIME:
5935 return string("UTCTime");
5936 case T_GENERALIZEDTIME:
5937 return string("GeneralizedTime");
5938 case T_OBJECTDESCRIPTOR:
5939 return string("ObjectDescriptor");
5940 case T_OID:
5941 return string("OBJECT__IDENTIFIER");
5942 case T_ROID:
5943 return string("RELATIVE__OID");
5944 case T_ANY:
5945 return string("ANY");
5946 case T_REFD:
5947 case T_SELTYPE:
5948 case T_REFDSPEC:
5949 case T_OCFT:
5950 if (tags || constraints ||
5951 (w_attrib_path && w_attrib_path->has_attribs()))
5952 return get_genname_own();
5953 else return get_type_refd()->get_stringRepr();
5954 case T_ERROR:
5955 return string("<Error_type>");
5956 default:
5957 return get_genname_own();
5958 } // switch
5959 }
5960
5961 Identifier Type::get_otaltname(bool& is_strange)
5962 {
5963 string s;
5964 if (is_tagged() || is_constrained() || hasRawAttrs()) {
5965 s = get_genname_own();
5966 is_strange = true;
5967 } else if (typetype == T_REFD) {
5968 Ref_simple* t_ref=dynamic_cast<Ref_simple*>(u.ref.ref);
5969 if (t_ref) {
5970 const Identifier *id = t_ref->get_id();
5971 const string& dispname = id->get_dispname();
5972 if (dispname.find('.') < dispname.size()) {
5973 // id is not regular because t_ref is a parameterized reference
5974 // use that id anyway
5975 s += id->get_name();
5976 is_strange = true;
5977 } else {
5978 Scope *ass_scope = t_ref->get_refd_assignment()->get_my_scope();
5979 if (ass_scope->get_parent_scope() == ass_scope->get_scope_mod()) {
5980 // t_ref points to an assignment at module scope
5981 // use the simple id of the reference (in lowercase)
5982 s = id->get_name();
5983 is_strange = false;
5984 } else {
5985 // t_ref is a dummy reference in a parameterized assignment
5986 // (i.e. it points to a parameter assignment of an instantiation)
5987 // perform the same examination recursively on the referenced type
5988 // (which is the actual parameter)
5989 return get_type_refd()->get_otaltname(is_strange);
5990 }
5991 }
5992 } else {
5993 // the type comes from an information object [class]
5994 // examine the referenced type recursively
5995 return get_type_refd()->get_otaltname(is_strange);
5996 }
5997 } else {
5998 s = get_stringRepr();
5999 // throw away the leading @ if this is an instantiated type
6000 // (e.g. an in-line SEQUENCE from a parameterized reference)
6001 if (!strncmp(s.c_str(), "_root_", 6)) s.replace(0, 6, "");
6002 // the name is strange if it contains a single underscore
6003 string s2(s);
6004 // transform "__" -> "-"
6005 for (size_t pos = 0; ; ) {
6006 pos = s2.find("__", pos);
6007 if (pos < s2.size()) {
6008 s2.replace(pos, 2, "-");
6009 pos++;
6010 } else break;
6011 }
6012 is_strange = s2.find('_') < s2.size();
6013 }
6014 /*
6015 size_t pos=s.find_if(0, s.size(), isupper);
6016 if(pos==s.size()) FATAL_ERROR("Type::get_otaltname() (`%s')", s.c_str());
6017 s[pos]=tolower(s[pos]);
6018 */
6019 s[0]=tolower(s[0]);
6020 Identifier tmp_id(Identifier::ID_NAME, s, true);
6021 /* This is because the origin of the returned ID must be ASN. */
6022 return Identifier(Identifier::ID_ASN, tmp_id.get_asnname());
6023 }
6024
6025 string Type::get_genname_value(Scope *p_scope)
6026 {
6027 Type *t = get_type_refd_last();
6028 switch (t->typetype) {
6029 case T_UNDEF:
6030 case T_ERROR:
6031 case T_UNRESTRICTEDSTRING:
6032 case T_OCFT:
6033 case T_EXTERNAL:
6034 case T_EMBEDDED_PDV:
6035 case T_REFD:
6036 case T_REFDSPEC:
6037 case T_SELTYPE:
6038 FATAL_ERROR("Type::get_genname_value()");
6039 case T_NULL:
6040 return string("ASN_NULL");
6041 case T_BOOL:
6042 return string("BOOLEAN");
6043 case T_INT:
6044 case T_INT_A:
6045 return string("INTEGER");
6046 case T_REAL:
6047 return string("FLOAT");
6048 case T_BSTR:
6049 case T_BSTR_A:
6050 return string("BITSTRING");
6051 case T_HSTR:
6052 return string("HEXSTRING");
6053 case T_OSTR:
6054 return string("OCTETSTRING");
6055 case T_CSTR:
6056 case T_NUMERICSTRING:
6057 case T_PRINTABLESTRING:
6058 case T_IA5STRING:
6059 case T_VISIBLESTRING:
6060 case T_UTCTIME:
6061 case T_GENERALIZEDTIME:
6062 return string("CHARSTRING");
6063 case T_USTR: // ttcn3 universal charstring
6064 case T_UTF8STRING:
6065 case T_TELETEXSTRING:
6066 case T_VIDEOTEXSTRING:
6067 case T_GRAPHICSTRING:
6068 case T_GENERALSTRING:
6069 case T_UNIVERSALSTRING:
6070 case T_BMPSTRING:
6071 case T_OBJECTDESCRIPTOR:
6072 return string("UNIVERSAL_CHARSTRING");
6073 case T_OID:
6074 case T_ROID:
6075 return string("OBJID");
6076 case T_ANY:
6077 return string("ASN_ANY");
6078 case T_VERDICT:
6079 return string("VERDICTTYPE");
6080 case T_COMPONENT:
6081 return string("COMPONENT");
6082 case T_DEFAULT:
6083 return string("DEFAULT");
6084 case T_ARRAY:
6085 if (!t->u.array.in_typedef)
6086 return t->u.array.dimension->get_value_type(t->u.array.element_type,
6087 p_scope);
6088 // no break
6089 default:
6090 return t->get_genname_own(p_scope);
6091 } // switch
6092 }
6093
6094 string Type::get_genname_template(Scope *p_scope)
6095 {
6096 Type *t = get_type_refd_last();
6097 string ret_val;
6098 switch (t->typetype) {
6099 case T_ERROR:
6100 case T_PORT:
6101 // template classes do not exist for these types
6102 FATAL_ERROR("Type::get_genname_template()");
6103 case T_ARRAY:
6104 // a template class has to be instantiated in case of arrays
6105 // outside type definitions
6106 if (!t->u.array.in_typedef) {
6107 ret_val = t->u.array.dimension->get_template_type(
6108 t->u.array.element_type, p_scope);
6109 break;
6110 }
6111 // no break
6112 default:
6113 // in case of other types the name of the template class is derived
6114 // from the value class by appending a suffix
6115 ret_val = t->get_genname_value(p_scope);
6116 ret_val += "_template";
6117 break;
6118 }
6119 return ret_val;
6120 }
6121
6122 string Type::get_genname_altname()
6123 {
6124 Type *t_last = get_type_refd_last();
6125 Scope *t_scope = t_last->get_my_scope();
6126 switch (t_last->typetype) {
6127 case T_UNDEF:
6128 case T_ERROR:
6129 case T_UNRESTRICTEDSTRING:
6130 case T_OCFT:
6131 case T_EXTERNAL:
6132 case T_EMBEDDED_PDV:
6133 case T_REFD:
6134 case T_REFDSPEC:
6135 case T_SELTYPE:
6136 FATAL_ERROR("Type::get_genname_altname()");
6137 case T_ENUM_A:
6138 case T_ENUM_T:
6139 case T_CHOICE_A:
6140 case T_CHOICE_T:
6141 case T_SEQOF:
6142 case T_SETOF:
6143 case T_SEQ_A:
6144 case T_SEQ_T:
6145 case T_SET_A:
6146 case T_SET_T:
6147 case T_OPENTYPE:
6148 case T_ANYTYPE: // FIXME this does not yet work
6149 case T_PORT:
6150 case T_COMPONENT:
6151 case T_ARRAY:
6152 case T_SIGNATURE:
6153 case T_FUNCTION:
6154 case T_ALTSTEP:
6155 case T_TESTCASE: {
6156 // user-defined types
6157 // always use the qualified name (including module identifier)
6158 string ret_val(t_scope->get_scope_mod_gen()->get_modid().get_name());
6159 ret_val += '_';
6160 ret_val += t_last->get_genname_own();
6161 return ret_val; }
6162 default:
6163 // built-in types
6164 // use the simple class name from the base library
6165 return t_last->get_genname_value(t_scope);
6166 }
6167 }
6168
6169 string Type::get_typename()
6170 {
6171 Type *t = get_type_refd_last();
6172 const char* tn = get_typename_builtin(t->typetype);
6173 if (tn != 0) return string(tn);
6174 switch (t->typetype) {
6175 case T_COMPONENT:
6176 case T_SIGNATURE:
6177 case T_CHOICE_A:
6178 case T_CHOICE_T:
6179 case T_ANYTYPE:
6180 case T_SEQ_A:
6181 case T_SEQ_T:
6182 case T_SET_A:
6183 case T_SET_T:
6184 case T_SEQOF:
6185 case T_SETOF:
6186 case T_ENUM_A:
6187 case T_ENUM_T:
6188 case T_PORT:
6189 case T_FUNCTION:
6190 case T_ALTSTEP:
6191 case T_TESTCASE:
6192 return t->get_fullname();
6193 case T_ARRAY: {
6194 string dimensions(t->u.array.dimension->get_stringRepr());
6195 t = t->u.array.element_type;
6196 while (t->typetype == T_ARRAY) {
6197 dimensions += t->u.array.dimension->get_stringRepr();
6198 t = t->u.array.element_type;
6199 }
6200 return t->get_typename() + dimensions; }
6201 default:
6202 FATAL_ERROR("Type::get_typename()");
6203 return string();
6204 } // switch
6205 }
6206
6207 // static
6208 const char* Type::get_typename_builtin(typetype_t tt)
6209 {
6210 switch (tt) {
6211 case T_ERROR:
6212 return "Erroneous type";
6213 case T_NULL:
6214 return "NULL";
6215 case T_BOOL:
6216 return "boolean";
6217 case T_INT:
6218 case T_INT_A:
6219 return "integer";
6220 case T_REAL:
6221 return "float";
6222 case T_BSTR:
6223 case T_BSTR_A:
6224 return "bitstring";
6225 case T_HSTR:
6226 return "hexstring";
6227 case T_OSTR:
6228 return "octetstring";
6229 case T_CSTR:
6230 return "charstring";
6231 case T_USTR:
6232 return "universal charstring";
6233 case T_UTF8STRING:
6234 return "UTF8String";
6235 case T_NUMERICSTRING:
6236 return "NumericString";
6237 case T_PRINTABLESTRING:
6238 return "PrintableString";
6239 case T_TELETEXSTRING:
6240 return "TeletexString";
6241 case T_VIDEOTEXSTRING:
6242 return "VideotexString";
6243 case T_IA5STRING:
6244 return "IA5String";
6245 case T_GRAPHICSTRING:
6246 return "GraphicString";
6247 case T_VISIBLESTRING:
6248 return "VisibleString";
6249 case T_GENERALSTRING:
6250 return "GeneralString";
6251 case T_UNIVERSALSTRING:
6252 return "UniversalString";
6253 case T_BMPSTRING:
6254 return "BMPString";
6255 case T_UTCTIME:
6256 return "UTCTime";
6257 case T_GENERALIZEDTIME:
6258 return "GeneralizedTime";
6259 case T_OBJECTDESCRIPTOR:
6260 return "ObjectDescriptor";
6261 case T_OID:
6262 case T_ROID:
6263 return "objid";
6264 case T_ANY:
6265 return "ANY";
6266 case T_VERDICT:
6267 return "verdicttype";
6268 case T_DEFAULT:
6269 return "default";
6270 case T_EXTERNAL:
6271 return "EXTERNAL";
6272 case T_EMBEDDED_PDV:
6273 return "EMBEDDED PDV";
6274 case T_UNRESTRICTEDSTRING:
6275 return "CHARACTER STRING";
6276 case T_OPENTYPE:
6277 return "open type";
6278 case T_ADDRESS:
6279 return "address";
6280 default:
6281 return 0;
6282 }
6283 }
6284
6285 string Type::get_genname_typedescriptor(Scope *p_scope)
6286 {
6287 Type *t = this;
6288 for ( ; ; ) {
6289 /* If it has tags or encoding attributes, then its encoding may be
6290 * different from the other "equivalent" types and needs to have its own
6291 * descriptor.
6292 */
6293 if (t->is_tagged() || t->rawattrib || t->textattrib || t->jsonattrib ||
6294 (t->xerattrib && !t->xerattrib->empty() ))
6295 {
6296 return t->get_genname_own(p_scope);
6297 }
6298 else if (t->is_ref()) {
6299 if (t->has_encoding(CT_XER)) {
6300 // just fetch the referenced type and return
6301 return t->get_type_refd()->get_genname_own(p_scope);
6302 }
6303 else
6304 { // follow the white rabbit
6305 t = t->get_type_refd();
6306 }
6307 }
6308 else break;
6309 }
6310 return t->get_genname_typename(p_scope);
6311 }
6312
6313 string Type::get_genname_typename(Scope *p_scope)
6314 {
6315 Type *t = get_type_refd_last();
6316 switch (t->typetype) {
6317 case T_UTF8STRING:
6318 return string("UTF8String");
6319 case T_NUMERICSTRING:
6320 return string("NumericString");
6321 case T_PRINTABLESTRING:
6322 return string("PrintableString");
6323 case T_TELETEXSTRING:
6324 return string("TeletexString");
6325 case T_VIDEOTEXSTRING:
6326 return string("VideotexString");
6327 case T_IA5STRING:
6328 return string("IA5String");
6329 case T_GRAPHICSTRING:
6330 return string("GraphicString");
6331 case T_VISIBLESTRING:
6332 return string("VisibleString");
6333 case T_GENERALSTRING:
6334 return string("GeneralString");
6335 case T_UNIVERSALSTRING:
6336 return string("UniversalString");
6337 case T_BMPSTRING:
6338 return string("BMPString");
6339 case T_UTCTIME:
6340 return string("ASN_UTCTime");
6341 case T_GENERALIZEDTIME:
6342 return string("ASN_GeneralizedTime");
6343 case T_OBJECTDESCRIPTOR:
6344 return string("ObjectDescriptor");
6345 case T_ROID:
6346 return string("ASN_ROID");
6347 default:
6348 return t->get_genname_value(p_scope);
6349 } // switch
6350 }
6351
6352 string Type::get_genname_berdescriptor()
6353 {
6354 Type *t = this;
6355 for ( ; ; ) {
6356 if (t->is_tagged()) return t->get_genname_own(my_scope);
6357 else if (t->is_ref()) t = t->get_type_refd();
6358 else break;
6359 }
6360 switch (t->typetype) {
6361 case T_ENUM_A:
6362 case T_ENUM_T:
6363 return string("ENUMERATED");
6364 case T_CHOICE_A:
6365 case T_CHOICE_T:
6366 case T_OPENTYPE:
6367 return string("CHOICE");
6368 case T_SEQ_A:
6369 case T_SEQ_T:
6370 case T_SEQOF:
6371 return string("SEQUENCE");
6372 case T_SET_A:
6373 case T_SET_T:
6374 case T_SETOF:
6375 return string("SET");
6376 default:
6377 return t->get_genname_typename(my_scope);
6378 } // switch
6379 }
6380
6381 string Type::get_genname_rawdescriptor()
6382 {
6383 Type *t = this;
6384 for ( ; ; ) {
6385 if (t->rawattrib) return t->get_genname_own(my_scope);
6386 else if (t->is_ref()) t = t->get_type_refd();
6387 else break;
6388 }
6389 return t->get_genname_typename(my_scope);
6390 }
6391
6392 string Type::get_genname_textdescriptor()
6393 {
6394 Type *t = this;
6395 for ( ; ; ) {
6396 if (t->textattrib) return t->get_genname_own(my_scope);
6397 else if (t->is_ref()) t = t->get_type_refd();
6398 else break;
6399 }
6400 return t->get_genname_typename(my_scope);
6401 }
6402
6403 string Type::get_genname_xerdescriptor()
6404 {
6405 if (T_REFDSPEC == typetype) {
6406 return get_genname_typedescriptor(my_scope);
6407 }
6408 else return genname;
6409 }
6410
6411 string Type::get_genname_jsondescriptor()
6412 {
6413 Type *t = this;
6414 while (true) {
6415 if (t->jsonattrib) return t->get_genname_own(my_scope);
6416 else if (t->is_ref()) t = t->get_type_refd();
6417 else break;
6418 }
6419 return t->get_genname_typename(my_scope);
6420 }
6421
6422 const char* Type::get_genname_typedescr_asnbasetype()
6423 {
6424 switch (get_type_refd_last()->typetype) {
6425 case T_BMPSTRING:
6426 return "BMPSTRING";
6427 case T_UNIVERSALSTRING:
6428 return "UNIVERSALSTRING";
6429 case T_UTF8STRING:
6430 return "UTF8STRING";
6431 case T_TELETEXSTRING:
6432 return "TELETEXSTRING";
6433 case T_VIDEOTEXSTRING:
6434 return "VIDEOTEXSTRING";
6435 case T_OBJECTDESCRIPTOR:
6436 case T_GRAPHICSTRING:
6437 return "GRAPHICSTRING";
6438 case T_GENERALSTRING:
6439 return "GENERALSTRING";
6440 case T_OID:
6441 return "OBJID";
6442 case T_ROID:
6443 return "ROID";
6444 default:
6445 return "DONTCARE";
6446 } // switch
6447 }
6448
6449 void Type::dump(unsigned level) const
6450 {
6451 DEBUG(level, "Type @ %p, '%s'", (const void*)this, get_fullname().c_str());
6452 switch(typetype) {
6453 case T_ERROR:
6454 DEBUG(level, "Type: <erroneous>");
6455 break;
6456 case T_NULL:
6457 DEBUG(level, "Type: NULL");
6458 break;
6459 case T_BOOL:
6460 DEBUG(level, "Type: boolean");
6461 break;
6462 case T_INT:
6463 DEBUG(level, "Type: integer");
6464 break;
6465 case T_INT_A:
6466 DEBUG(level, "Type: INTEGER");
6467 if(u.namednums.block)
6468 DEBUG(level, "with unparsed block");
6469 if(u.namednums.nvs) {
6470 DEBUG(level, "with named numbers (%lu pcs.)",
6471 (unsigned long) u.namednums.nvs->get_nof_nvs());
6472 u.namednums.nvs->dump(level+1);
6473 }
6474 break;
6475 case T_REAL:
6476 DEBUG(level, "Type: float/REAL");
6477 break;
6478 case T_ENUM_A:
6479 case T_ENUM_T:
6480 DEBUG(level, "Type: enumerated");
6481 u.enums.eis->dump(level+1);
6482 break;
6483 case T_BSTR:
6484 DEBUG(level, "Type: bitstring");
6485 break;
6486 case T_BSTR_A:
6487 DEBUG(level, "Type: BIT STRING");
6488 if(u.namednums.block)
6489 DEBUG(level, "with unparsed block");
6490 if(u.namednums.nvs) {
6491 DEBUG(level, "with named numbers (%lu pcs.)",
6492 (unsigned long) u.namednums.nvs->get_nof_nvs());
6493 u.namednums.nvs->dump(level+1);
6494 }
6495 break;
6496 case T_HSTR:
6497 DEBUG(level, "Type: hexstring");
6498 break;
6499 case T_OSTR:
6500 DEBUG(level, "Type: octetstring");
6501 break;
6502 case T_CSTR:
6503 DEBUG(level, "Type: charstring");
6504 break;
6505 case T_USTR:
6506 DEBUG(level, "Type: universal charstring");
6507 break;
6508 case T_UTF8STRING:
6509 DEBUG(level, "Type: UTF8String");
6510 break;
6511 case T_NUMERICSTRING:
6512 DEBUG(level, "Type: NumericString");
6513 break;
6514 case T_PRINTABLESTRING:
6515 DEBUG(level, "Type: PrintableString");
6516 break;
6517 case T_TELETEXSTRING:
6518 DEBUG(level, "Type: TeletexString");
6519 break;
6520 case T_VIDEOTEXSTRING:
6521 DEBUG(level, "Type: VideotexString");
6522 break;
6523 case T_IA5STRING:
6524 DEBUG(level, "Type: IA5String");
6525 break;
6526 case T_GRAPHICSTRING:
6527 DEBUG(level, "Type: GraphicString");
6528 break;
6529 case T_VISIBLESTRING:
6530 DEBUG(level, "Type: VisibleString");
6531 break;
6532 case T_GENERALSTRING:
6533 DEBUG(level, "Type: GeneralString");
6534 break;
6535 case T_UNIVERSALSTRING:
6536 DEBUG(level, "Type: UniversalString");
6537 break;
6538 case T_BMPSTRING:
6539 DEBUG(level, "Type: BMPString");
6540 break;
6541 case T_UNRESTRICTEDSTRING:
6542 DEBUG(level, "Type: CHARACTER STRING");
6543 break;
6544 case T_UTCTIME:
6545 DEBUG(level, "Type: UTCTime");
6546 break;
6547 case T_GENERALIZEDTIME:
6548 DEBUG(level, "Type: GeneralizedTime");
6549 break;
6550 case T_OBJECTDESCRIPTOR:
6551 DEBUG(level, "Type: OBJECT DESCRIPTOR");
6552 break;
6553 case T_OID:
6554 DEBUG(level, "Type: objid/OBJECT IDENTIFIER");
6555 break;
6556 case T_ROID:
6557 DEBUG(level, "Type: RELATIVE-OID");
6558 break;
6559 case T_ANYTYPE:
6560 DEBUG(level, "Type: anytype!!!");
6561 u.secho.cfm->dump(level+1);
6562 break;
6563 case T_CHOICE_T:
6564 DEBUG(level, "Type: union");
6565 u.secho.cfm->dump(level+1);
6566 break;
6567 case T_CHOICE_A:
6568 DEBUG(level, "Type: CHOICE");
6569 if(u.secho.block)
6570 DEBUG(level, "with unparsed block");
6571 if(u.secho.ctss) {
6572 DEBUG(level, "with alternatives (%lu pcs.)",
6573 (unsigned long) u.secho.ctss->get_nof_comps());
6574 u.secho.ctss->dump(level+1);
6575 }
6576 break;
6577 case T_SEQOF:
6578 DEBUG(level, "Type: record of/SEQUENCE OF");
6579 DEBUG(level+1, "of type:");
6580 u.seof.ofType->dump(level+2);
6581 break;
6582 case T_SETOF:
6583 DEBUG(level, "Type: set of/SET OF");
6584 DEBUG(level+1, "of type:");
6585 u.seof.ofType->dump(level+2);
6586 break;
6587 case T_SEQ_T:
6588 DEBUG(level, "Type: record");
6589 u.secho.cfm->dump(level+1);
6590 break;
6591 case T_SET_T:
6592 DEBUG(level, "Type: set");
6593 u.secho.cfm->dump(level+1);
6594 break;
6595 case T_SEQ_A:
6596 DEBUG(level, "Type: SEQUENCE");
6597 if(u.secho.block)
6598 DEBUG(level, "with unparsed block");
6599 if(u.secho.ctss) {
6600 DEBUG(level, "with components (%lu pcs.)",
6601 (unsigned long) u.secho.ctss->get_nof_comps());
6602 u.secho.ctss->dump(level+1);
6603 }
6604 break;
6605 case T_SET_A:
6606 DEBUG(level, "Type: SET");
6607 if(u.secho.block)
6608 DEBUG(level, "with unparsed block");
6609 if(u.secho.ctss) {
6610 DEBUG(level, "with components (%lu pcs.)",
6611 (unsigned long) u.secho.ctss->get_nof_comps());
6612 u.secho.ctss->dump(level+1);
6613 }
6614 break;
6615 case T_OCFT:
6616 DEBUG(level, "Type: ObjectClassFieldType (%s)",
6617 const_cast<Type*>(this)->get_type_refd()->get_stringRepr().c_str());
6618 break;
6619 case T_OPENTYPE:
6620 DEBUG(level, "Type: opentype (mapped to CHOICE)");
6621 u.secho.cfm->dump(level+1);
6622 break;
6623 case T_ANY:
6624 DEBUG(level, "Type: ANY");
6625 break;
6626 case T_EXTERNAL:
6627 DEBUG(level, "Type: EXTERNAL");
6628 break;
6629 case T_EMBEDDED_PDV:
6630 DEBUG(level, "Type: EMBEDDED PDV");
6631 break;
6632 case T_REFD:
6633 DEBUG(level, "Type: reference");
6634 u.ref.ref->dump(level+1);
6635 if(u.ref.type_refd && u.ref.type_refd->typetype==T_OPENTYPE)
6636 u.ref.type_refd->dump(level+1);
6637 break;
6638 case T_REFDSPEC:
6639 DEBUG(level, "Type: reference (spec) to %s:",
6640 u.ref.type_refd->get_fullname().c_str());
6641 u.ref.type_refd->dump(level + 1);
6642 break;
6643 case T_SELTYPE:
6644 DEBUG(level, "Type: selection type");
6645 DEBUG(level+1, "`%s' <", u.seltype.id->get_dispname().c_str());
6646 u.seltype.type->dump(level+1);
6647 break;
6648 case T_VERDICT:
6649 DEBUG(level, "Type: verdicttype");
6650 break;
6651 case T_PORT:
6652 DEBUG(level, "Type: port");
6653 u.port->dump(level + 1);
6654 break;
6655 case T_COMPONENT:
6656 DEBUG(level, "Type: component");
6657 u.component->dump(level + 1);
6658 break;
6659 case T_ADDRESS:
6660 DEBUG(level, "Type: address");
6661 break;
6662 case T_DEFAULT:
6663 DEBUG(level, "Type: default");
6664 break;
6665 case T_ARRAY:
6666 DEBUG(level, "Type: array");
6667 DEBUG(level + 1, "element type:");
6668 u.array.element_type->dump(level + 2);
6669 DEBUG(level + 1, "dimension:");
6670 u.array.dimension->dump(level + 2);
6671 break;
6672 case T_SIGNATURE:
6673 DEBUG(level, "Type: signature");
6674 if (u.signature.parameters) {
6675 DEBUG(level+1,"parameter(s):");
6676 u.signature.parameters->dump(level+2);
6677 }
6678 if (u.signature.return_type) {
6679 DEBUG(level+1,"return type");
6680 u.signature.return_type->dump(level+2);
6681 }
6682 if (u.signature.no_block) DEBUG(level+1,"no block");
6683 if (u.signature.exceptions) {
6684 DEBUG(level+1,"exception(s):");
6685 u.signature.exceptions->dump(level+2);
6686 }
6687 break;
6688 case T_FUNCTION:
6689 DEBUG(level, "Type: function");
6690 DEBUG(level+1, "Parameters:");
6691 u.fatref.fp_list->dump(level+2);
6692 if (u.fatref.return_type) {
6693 if (!u.fatref.returns_template) {
6694 DEBUG(level+1, "Return type:");
6695 } else {
6696 if (u.fatref.template_restriction==TR_OMIT)
6697 DEBUG(level+1, "Returns template of type:");
6698 else
6699 DEBUG(level+1, "Returns template(%s) of type:",
6700 Template::get_restriction_name(u.fatref.template_restriction));
6701 }
6702 u.fatref.return_type->dump(level+2);
6703 }
6704 if(u.fatref.runs_on.ref) {
6705 DEBUG(level+1, "Runs on clause:");
6706 u.fatref.runs_on.ref->dump(level+2);
6707 } else {
6708 if (u.fatref.runs_on.self) DEBUG(level+1, "Runs on self");
6709 }
6710 break;
6711 case T_ALTSTEP:
6712 DEBUG(level, "Type: altstep");
6713 DEBUG(level+1, "Parameters:");
6714 u.fatref.fp_list->dump(level+2);
6715 if(u.fatref.runs_on.ref) {
6716 DEBUG(level+1, "Runs on clause:");
6717 u.fatref.runs_on.ref->dump(level+2);
6718 } else {
6719 if (u.fatref.runs_on.self) DEBUG(level+1, "Runs on self");
6720 }
6721 break;
6722 case T_TESTCASE:
6723 DEBUG(level, "Type: testcase");
6724 DEBUG(level+1, "Parameters:");
6725 u.fatref.fp_list->dump(level+2);
6726 if(u.fatref.runs_on.ref) {
6727 DEBUG(level+1, "Runs on clause:");
6728 u.fatref.runs_on.ref->dump(level+2);
6729 }
6730 if(u.fatref.system.ref) {
6731 DEBUG(level+1, "System clause:");
6732 u.fatref.system.ref->dump(level+2);
6733 }
6734 break;
6735 default:
6736 DEBUG(level, "type (%d - %s)", typetype, const_cast<Type*>(this)->get_stringRepr().c_str());
6737 } // switch
6738 DEBUG(level, "ownertype %2d", ownertype);
6739 if(sub_type!=NULL) {
6740 DEBUG(level, "with subtype");
6741 sub_type->dump(level+1);
6742 }
6743 if(tags) {
6744 DEBUG(level, "with tags");
6745 tags->dump(level+1);
6746 }
6747
6748 if(w_attrib_path && w_attrib_path->get_with_attr())
6749 {
6750 DEBUG(level, "Attributes");
6751 w_attrib_path->dump(level);
6752 //w_attrib_path->get_with_attr()->dump(level);
6753 }
6754
6755 if (xerattrib) {
6756 xerattrib->print(get_fullname().c_str());
6757 }
6758 }
6759
6760 SubtypeConstraint::subtype_t Type::get_subtype_type()
6761 {
6762 Type* t = get_type_refd_last();
6763 switch (t->get_typetype()) {
6764 case T_INT:
6765 case T_INT_A:
6766 return SubtypeConstraint::ST_INTEGER;
6767 case T_REAL:
6768 return SubtypeConstraint::ST_FLOAT;
6769 case T_BOOL:
6770 return SubtypeConstraint::ST_BOOLEAN;
6771 case T_VERDICT:
6772 return SubtypeConstraint::ST_VERDICTTYPE;
6773 case T_OID:
6774 case T_ROID:
6775 return SubtypeConstraint::ST_OBJID;
6776 case T_BSTR:
6777 case T_BSTR_A:
6778 return SubtypeConstraint::ST_BITSTRING;
6779 case T_HSTR:
6780 return SubtypeConstraint::ST_HEXSTRING;
6781 case T_OSTR:
6782 return SubtypeConstraint::ST_OCTETSTRING;
6783 case T_TELETEXSTRING:
6784 case T_VIDEOTEXSTRING:
6785 case T_GRAPHICSTRING:
6786 case T_GENERALSTRING:
6787 case T_OBJECTDESCRIPTOR:
6788 // iso2022str
6789 case T_CSTR:
6790 case T_NUMERICSTRING:
6791 case T_PRINTABLESTRING:
6792 case T_IA5STRING:
6793 case T_VISIBLESTRING:
6794 case T_UTCTIME:
6795 case T_GENERALIZEDTIME:
6796 return SubtypeConstraint::ST_CHARSTRING;
6797 case T_USTR:
6798 case T_UTF8STRING:
6799 case T_UNIVERSALSTRING:
6800 case T_BMPSTRING:
6801 return SubtypeConstraint::ST_UNIVERSAL_CHARSTRING;
6802 case T_ENUM_T:
6803 case T_ENUM_A:
6804 case T_NULL: // FIXME: this should have it's own ST_NULL case
6805 return SubtypeConstraint::ST_ENUM;
6806 case T_CHOICE_T:
6807 case T_CHOICE_A:
6808 case T_ANYTYPE: // (titan's hacked anytype is a choice)
6809 case T_OPENTYPE:
6810 return SubtypeConstraint::ST_UNION;
6811 case T_SEQOF:
6812 return SubtypeConstraint::ST_RECORDOF;
6813 case T_SETOF:
6814 return SubtypeConstraint::ST_SETOF;
6815 case T_SEQ_T:
6816 case T_SEQ_A:
6817 case T_EXTERNAL: // associated ASN.1 type is a SEQUENCE
6818 case T_EMBEDDED_PDV: // associated ASN.1 type is a SEQUENCE
6819 case T_UNRESTRICTEDSTRING: // associated ASN.1 type is a SEQUENCE
6820 return SubtypeConstraint::ST_RECORD;
6821 case T_SET_T:
6822 case T_SET_A:
6823 return SubtypeConstraint::ST_SET;
6824 case T_FUNCTION:
6825 return SubtypeConstraint::ST_FUNCTION;
6826 case T_ALTSTEP:
6827 return SubtypeConstraint::ST_ALTSTEP;
6828 case T_TESTCASE:
6829 return SubtypeConstraint::ST_TESTCASE;
6830 default:
6831 return SubtypeConstraint::ST_ERROR;
6832 }
6833 }
6834
6835 void Type::set_parsed_restrictions(vector<SubTypeParse> *stp)
6836 {
6837 if(!parsed_restr)parsed_restr=stp;
6838 else FATAL_ERROR("Type::set_parsed_restrictions(): restrictions "
6839 "are already set.");
6840 }
6841
6842 bool Type::is_component_internal()
6843 {
6844 if (!checked) chk();
6845 switch (typetype) {
6846 case T_DEFAULT:
6847 case T_PORT:
6848 return true;
6849 case T_FUNCTION:
6850 case T_ALTSTEP:
6851 return u.fatref.runs_on.self;
6852 case T_CHOICE_T:
6853 case T_SEQ_T:
6854 case T_SET_T:
6855 return u.secho.component_internal;
6856 case T_SEQOF:
6857 case T_SETOF:
6858 return u.seof.component_internal;
6859 case T_ARRAY:
6860 return u.array.component_internal;
6861 case T_SIGNATURE:
6862 return u.signature.component_internal;
6863 case T_REFD:
6864 case T_REFDSPEC:
6865 return u.ref.component_internal;
6866 default:
6867 return false;
6868 } //switch
6869 }
6870
6871 void Type::chk_component_internal(map<Type*,void>& type_chain,
6872 const char* p_what)
6873 {
6874 Type* t_last = get_type_refd_last();
6875 switch (t_last->typetype) {
6876 // types that cannot be sent
6877 case T_DEFAULT:
6878 error("Default type cannot be %s", p_what);
6879 break;
6880 case T_PORT:
6881 error("Port type `%s' cannot be %s", t_last->get_typename().c_str(),
6882 p_what);
6883 break;
6884 case T_FUNCTION:
6885 if (t_last->u.fatref.runs_on.self) {
6886 error("Function type `%s' with 'runs on self' clause cannot be %s",
6887 t_last->get_typename().c_str(), p_what);
6888 }
6889 break;
6890 case T_ALTSTEP:
6891 if (t_last->u.fatref.runs_on.self) {
6892 error("Altstep type `%s' with 'runs on self' clause cannot be %s",
6893 t_last->get_typename().c_str(), p_what);
6894 }
6895 break;
6896 // structured types that may contain types that cannot be sent
6897 case T_CHOICE_T:
6898 case T_SEQ_T:
6899 case T_SET_T:
6900 case T_SEQOF:
6901 case T_SETOF:
6902 case T_ARRAY:
6903 case T_SIGNATURE: {
6904 if (type_chain.has_key(t_last)) break;
6905 type_chain.add(t_last, 0);
6906 Error_Context cntxt(this, "In type `%s'", get_typename().c_str());
6907 switch (t_last->typetype) {
6908 case T_CHOICE_T:
6909 case T_SEQ_T:
6910 case T_SET_T: {
6911 size_t nof_comps = t_last->get_nof_comps();
6912 for (size_t i=0; i<nof_comps; i++) {
6913 Type* t = t_last->get_comp_byIndex(i)->get_type();
6914 if (t->is_component_internal())
6915 t->chk_component_internal(type_chain, p_what);
6916 }
6917 } break;
6918 case T_SEQOF:
6919 case T_SETOF:
6920 if (t_last->u.seof.ofType->is_component_internal())
6921 t_last->u.seof.ofType->chk_component_internal(type_chain, p_what);
6922 break;
6923 case T_ARRAY:
6924 if (t_last->u.array.element_type->is_component_internal())
6925 t_last->u.array.element_type->chk_component_internal(type_chain,
6926 p_what);
6927 break;
6928 case T_SIGNATURE:
6929 if (t_last->u.signature.parameters) {
6930 size_t nof_params = t_last->u.signature.parameters->get_nof_params();
6931 for (size_t i=0; i<nof_params; i++) {
6932 Type* t = t_last->u.signature.parameters->
6933 get_param_byIndex(i)->get_type();
6934 if (t->is_component_internal())
6935 t->chk_component_internal(type_chain, p_what);
6936 }
6937 }
6938 if (t_last->u.signature.return_type &&
6939 t_last->u.signature.return_type->is_component_internal()) {
6940 t_last->u.signature.return_type->chk_component_internal(type_chain,
6941 p_what);
6942 }
6943 if (t_last->u.signature.exceptions) {
6944 size_t nof_types = t_last->u.signature.exceptions->get_nof_types();
6945 for (size_t i=0; i<nof_types; i++) {
6946 Type* t = t_last->u.signature.exceptions->get_type_byIndex(i);
6947 if (t->is_component_internal())
6948 t->chk_component_internal(type_chain, p_what);
6949 }
6950 }
6951 break;
6952 default:
6953 FATAL_ERROR("Type::chk_component_internal()");
6954 }
6955 type_chain.erase(t_last);
6956 } break;
6957 default: //all other types are Ok.
6958 break;
6959 } // switch
6960 }
6961
6962 Type::typetype_t Type::search_for_not_allowed_type(map<Type*,void>& type_chain,
6963 map<typetype_t, void>& not_allowed)
6964 {
6965 if (!checked) chk();
6966 Type* t_last = get_type_refd_last();
6967 Type::typetype_t ret = t_last->typetype;
6968
6969 if (not_allowed.has_key(t_last->typetype)) {
6970 return ret;
6971 }
6972
6973 switch (t_last->typetype) {
6974 case T_CHOICE_T:
6975 case T_SEQ_T:
6976 case T_SET_T:
6977 case T_SEQOF:
6978 case T_SETOF:
6979 case T_ARRAY: {
6980 if (type_chain.has_key(t_last)) {
6981 break;
6982 }
6983 type_chain.add(t_last, 0);
6984 switch (t_last->typetype) {
6985 case T_CHOICE_T:
6986 case T_SEQ_T:
6987 case T_SET_T: {
6988 size_t nof_comps = t_last->get_nof_comps();
6989 for (size_t i = 0; i < nof_comps; ++i) {
6990 Type* t = t_last->get_comp_byIndex(i)->get_type();
6991 ret = t->search_for_not_allowed_type(type_chain, not_allowed);
6992 if (not_allowed.has_key(ret)) {
6993 return ret;
6994 }
6995 }
6996 } break;
6997 case T_SEQOF:
6998 case T_SETOF:
6999 case T_ARRAY:
7000 ret = t_last->get_ofType()->search_for_not_allowed_type(type_chain, not_allowed);
7001 if (not_allowed.has_key(ret)) {
7002 return ret;
7003 }
7004 break;
7005 default:
7006 break;
7007 }
7008 type_chain.erase(t_last);
7009 }
7010 break;
7011 default:
7012 break;
7013 }
7014 return t_last->typetype;
7015 }
7016
7017 string Type::get_dispname() const
7018 {
7019 string dispname = genname;
7020 size_t pos = 0;
7021 while(pos < dispname.size()) {
7022 pos = dispname.find("__", pos);
7023 if (pos == dispname.size()) {
7024 break;
7025 }
7026 dispname.replace(pos, 1, "");
7027 ++pos;
7028 }
7029 return dispname;
7030 }
7031
7032 bool Type::is_pregenerated()
7033 {
7034 // records/sets of base types are already pre-generated, only a type alias will be generated
7035 // exception: record of universal charstring with the XER coding instruction "anyElement"
7036 if (!force_gen_seof && (T_SEQOF == get_type_refd_last()->typetype ||
7037 T_SETOF == get_type_refd_last()->typetype) &&
7038 (NULL == xerattrib || /* check for "anyElement" at the record of type */
7039 NamespaceRestriction::UNUSED == xerattrib->anyElement_.type_) &&
7040 (NULL == u.seof.ofType->xerattrib || /* check for "anyElement" at the element type */
7041 NamespaceRestriction::UNUSED == u.seof.ofType->xerattrib->anyElement_.type_)) {
7042 switch(u.seof.ofType->get_type_refd_last()->typetype) {
7043 case T_BOOL:
7044 case T_INT:
7045 case T_INT_A:
7046 case T_REAL:
7047 case T_BSTR:
7048 case T_BSTR_A:
7049 case T_HSTR:
7050 case T_OSTR:
7051 case T_CSTR:
7052 case T_NUMERICSTRING:
7053 case T_PRINTABLESTRING:
7054 case T_IA5STRING:
7055 case T_VISIBLESTRING:
7056 case T_UNRESTRICTEDSTRING:
7057 case T_UTCTIME:
7058 case T_GENERALIZEDTIME:
7059 case T_USTR:
7060 case T_UTF8STRING:
7061 case T_TELETEXSTRING:
7062 case T_VIDEOTEXSTRING:
7063 case T_GRAPHICSTRING:
7064 case T_GENERALSTRING:
7065 case T_UNIVERSALSTRING:
7066 case T_BMPSTRING:
7067 case T_OBJECTDESCRIPTOR:
7068 return true;
7069 default:
7070 return false;
7071 }
7072 }
7073 return false;
7074 }
7075
7076 bool Type::has_as_value_union()
7077 {
7078 if (jsonattrib != NULL && jsonattrib->as_value) {
7079 return true;
7080 }
7081 Type* t = get_type_refd_last();
7082 switch (t->get_typetype_ttcn3()) {
7083 case T_CHOICE_T:
7084 if (t->jsonattrib != NULL && t->jsonattrib->as_value) {
7085 return true;
7086 }
7087 // no break, check alternatives
7088 case T_SEQ_T:
7089 case T_SET_T:
7090 for (size_t i = 0; i < t->get_nof_comps(); ++i) {
7091 if (t->get_comp_byIndex(i)->get_type()->has_as_value_union()) {
7092 return true;
7093 }
7094 }
7095 return false;
7096 case T_SEQOF:
7097 case T_ARRAY:
7098 return t->get_ofType()->has_as_value_union();
7099 default:
7100 return false;
7101 }
7102 }
7103
7104 } // namespace Common
7105
This page took 0.19737 seconds and 5 git commands to generate.