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