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