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