Sync with 5.2.0
[deliverable/titan.core.git] / compiler2 / Type_chk.cc
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #include "../common/dbgnew.hh"
9 #include "Type.hh"
10 #include "Typestuff.hh" // FIXME CTs
11 #include "CompField.hh"
12 #include "CompType.hh"
13 #include "TypeCompat.hh"
14 #include "EnumItem.hh"
15 #include "SigParam.hh"
16
17 #include "Valuestuff.hh"
18 #include "main.hh"
19
20 #include "ttcn3/Ttcnstuff.hh"
21 #include "ttcn3/TtcnTemplate.hh"
22 #include "ttcn3/Templatestuff.hh"
23 #include "ttcn3/Attributes.hh"
24 #include "ttcn3/ArrayDimensions.hh"
25 #include "ttcn3/PatternString.hh"
26
27 #include "asn1/Tag.hh"
28 #include "XerAttributes.hh"
29
30 #include <ctype.h>
31 #include <stdlib.h> // for qsort
32 #include <string.h>
33
34 extern int rawAST_debug;
35
36 namespace Common {
37
38 using Ttcn::MultiWithAttrib;
39 using Ttcn::SingleWithAttrib;
40 using Ttcn::WithAttribPath;
41 using Ttcn::Qualifier;
42 using Ttcn::Qualifiers;
43
44 void Type::chk()
45 {
46 if(w_attrib_path) w_attrib_path->chk_global_attrib();
47 parse_attributes();
48 if(!tags_checked) {
49 tags_checked = true;
50 if(tags) tags->chk();
51 }
52 if (checked) return;
53 switch(typetype) {
54 case T_ERROR:
55 case T_NULL:
56 case T_BOOL:
57 case T_INT:
58 case T_REAL:
59 case T_BSTR:
60 case T_HSTR:
61 case T_OSTR:
62 case T_CSTR:
63 case T_USTR:
64 case T_UTF8STRING:
65 case T_NUMERICSTRING:
66 case T_PRINTABLESTRING:
67 case T_TELETEXSTRING:
68 case T_VIDEOTEXSTRING:
69 case T_IA5STRING:
70 case T_GRAPHICSTRING:
71 case T_VISIBLESTRING:
72 case T_GENERALSTRING:
73 case T_UNIVERSALSTRING:
74 case T_BMPSTRING:
75 case T_UTCTIME:
76 case T_GENERALIZEDTIME:
77 case T_OBJECTDESCRIPTOR:
78 case T_OID:
79 case T_ROID:
80 case T_ANY:
81 case T_EXTERNAL:
82 case T_EMBEDDED_PDV:
83 case T_UNRESTRICTEDSTRING:
84 case T_VERDICT:
85 case T_DEFAULT:
86 break;
87 case T_INT_A:
88 chk_Int_A();
89 break;
90 case T_ENUM_A:
91 chk_Enum_A();
92 break;
93 case T_ENUM_T:
94 chk_Enum_T();
95 break;
96 case T_BSTR_A:
97 chk_BStr_A();
98 break;
99 case T_OPENTYPE:
100 chk_SeCho_T();
101 break;
102 case T_ANYTYPE:
103 // TODO maybe check for address type and add it automagically, then fall through
104 case T_SEQ_T:
105 case T_SET_T:
106 case T_CHOICE_T:
107 chk_SeCho_T();
108 // If this sequence type has no attributes but one of its fields does,
109 // create an empty attribute structure.
110 if(!rawattrib && hasVariantAttrs() && hasNeedofRawAttrs())
111 rawattrib = new RawAST;
112 if(!textattrib && hasVariantAttrs() && hasNeedofTextAttrs())
113 textattrib = new TextAST;
114 if(!xerattrib && hasVariantAttrs() && hasNeedofXerAttrs())
115 xerattrib = new XerAttributes;
116 if (!jsonattrib && (hasVariantAttrs() || hasEncodeAttr(CT_JSON) || hasNeedofJsonAttrs())) {
117 jsonattrib = new JsonAST;
118 }
119 break;
120 case T_CHOICE_A:
121 chk_Choice_A();
122 // TODO create an empty XerAttrib as above, when ASN.1 gets XER ?
123 // The code was originally for TTCN-only encodings.
124 break;
125 case T_SEQ_A:
126 case T_SET_A:
127 chk_Se_A();
128 // TODO create an empty XerAttrib as above, when ASN.1 gets XER ?
129 break;
130 case T_SEQOF:
131 case T_SETOF:
132 chk_SeOf();
133 break;
134 case T_REFD:
135 case T_ADDRESS:
136 chk_refd();
137 break;
138 case T_SELTYPE:
139 chk_seltype();
140 break;
141 case T_REFDSPEC:
142 case T_OCFT:
143 u.ref.type_refd->chk();
144 u.ref.component_internal = u.ref.type_refd->is_component_internal();
145 break;
146 case T_ARRAY:
147 chk_Array();
148 break;
149 case T_PORT:
150 u.port->chk();
151 if (w_attrib_path) u.port->chk_attributes(w_attrib_path);
152 break;
153 case T_SIGNATURE:
154 chk_Signature();
155 break;
156 case T_COMPONENT:
157 u.component->chk();
158 break;
159 case T_FUNCTION:
160 case T_ALTSTEP:
161 case T_TESTCASE:
162 chk_Fat();
163 break;
164 default:
165 FATAL_ERROR("Type::chk()");
166 } // switch
167
168 if(w_attrib_path) {
169 switch (get_type_refd_last()->typetype) {
170 case T_SEQ_T:
171 case T_SET_T:
172 case T_CHOICE_T:
173 // These types may have qualified attributes
174 break;
175 case T_SEQOF: case T_SETOF:
176 break;
177 default:
178 w_attrib_path->chk_no_qualif();
179 break;
180 }
181 }
182 checked = true;
183 if(tags) tags->set_plicit(this);
184
185 /*
186 Check all non-table subtype constraints. Table/relational constraints
187 are ignored here.
188 TODO: non-relational table constraints shall not be ignored.
189 */
190 if (check_subtype) check_subtype_constraints();
191
192 /*
193 * Checking the constraints can be done only if the entire type
194 * (including the nested typedefs) is checked, because the
195 * component relation constraint has to 'look' into other
196 * components.
197 */
198 if (!parent_type) chk_table_constraints();
199
200 if(rawattrib || is_root_basic()){
201 chk_raw();
202 }
203 if(textattrib || is_root_basic()) {
204 chk_text();
205 }
206
207 if (jsonattrib || is_root_basic()) {
208 chk_json();
209 }
210
211 // We need to call chk_xer() always because it is collecting
212 // XER attributes from parent types.
213 chk_xer();
214
215 chk_finished = true;
216 }
217
218 void Type::parse_attributes()
219 {
220 if (raw_parsed) return;
221
222 // The type has no attributes of its own; connect it to the nearest group
223 // or the module. This allows global attributes to propagate.
224 for (Type *t = this; t && w_attrib_path == 0; t = t->parent_type) {
225 switch (t->ownertype) {
226 case OT_TYPE_DEF: {
227 Ttcn::Def_Type *pwn = static_cast<Ttcn::Def_Type*>(t->owner);
228 Ttcn::Group *nearest_group = pwn->get_parent_group();
229
230 w_attrib_path = new WithAttribPath;
231 if (nearest_group) { // there is a group
232 w_attrib_path->set_parent(nearest_group->get_attrib_path());
233 }
234 else { // no group, use the module
235 Common::Module *mymod = t->my_scope->get_scope_mod();
236 // OT_TYPE_DEF is always from a TTCN-3 module
237 Ttcn::Module *my_ttcn_module = static_cast<Ttcn::Module *>(mymod);
238 w_attrib_path->set_parent(my_ttcn_module->get_attrib_path());
239 }
240 break; }
241
242 case OT_RECORD_OF:
243 case OT_COMP_FIELD:
244 continue; // try the enclosing type
245
246 default:
247 break;
248 }
249 break;
250 }
251
252 if ((hasVariantAttrs())
253 && (enable_text() || enable_raw() || enable_xer())) {
254 #ifndef NDEBUG
255 const char *fn = get_fullname().c_str();
256 if (rawAST_debug) {
257 fprintf(stderr, "parse_attributes for %s\n", fn);
258 }
259 #endif
260 bool new_raw=false; // a RawAST object was allocated here
261 bool new_text=false; // a TextAST object was allocated here
262 bool new_xer=false; // a XerAttribute object was allocated here
263 bool new_ber=false; // a BerAST object was allocated here
264 bool new_json = false; // a JsonAST object was allocated here
265 bool raw_found=false; // a raw attribute was found by the parser
266 bool text_found=false; // a text attribute was found by the parser
267 bool xer_found=false; // a XER attribute was found by the parser
268 bool ber_found=false; // a BER attribute was found by the parser
269 bool json_found = false; // a JSON attribute was found by the parser
270 raw_checked=false;
271 text_checked=false;
272 json_checked = false;
273 xer_checked=false;
274 bool override_ref=false;
275 // Parse RAW attributes
276 switch(typetype) {
277 case T_REFD: {
278 ReferenceChain refch(this, "While checking attributes");
279 if(w_attrib_path)
280 {
281 // Get all the attributes that apply (from outer scopes too).
282 // Outer (generic) first, inner (specific) last.
283 const vector<SingleWithAttrib> & real_attribs
284 = w_attrib_path->get_real_attrib();
285
286 // see if there's an encode with override
287 for(size_t i = real_attribs.size(); i > 0 && !override_ref; i--)
288 {
289 if(real_attribs[i-1]->has_override()
290 && real_attribs[i-1]->get_attribKeyword()
291 != SingleWithAttrib::AT_ENCODE)
292 override_ref = true;
293 }
294 }
295 if(!rawattrib && !override_ref){
296 Type *t=get_type_refd_last(&refch);
297 typetype_t basic_type=t->typetype;
298 t=this; // go back to the beginning
299 refch.reset();
300 while(!t->rawattrib && t->is_ref()) t=t->get_type_refd(&refch);
301 rawattrib=new RawAST(t->rawattrib,basic_type==T_INT);
302 if(!t->rawattrib && basic_type==T_REAL) rawattrib->fieldlength=64;
303 new_raw=true;
304 }
305 if(!textattrib && !override_ref){
306 Type *t=this;
307 refch.reset();
308 while(!t->textattrib && t->is_ref()) t=t->get_type_refd(&refch);
309 textattrib=new TextAST(t->textattrib);
310 new_text=true;
311 }
312 if (!jsonattrib && !override_ref){
313 Type *t = this;
314 refch.reset();
315 while (!t->jsonattrib && t->is_ref()) {
316 t = t->get_type_refd(&refch);
317 }
318 jsonattrib = new JsonAST(t->jsonattrib);
319 new_json = true;
320 }
321 }
322 // no break
323 case T_BOOL:
324 case T_INT:
325 case T_REAL:
326 case T_BSTR:
327 case T_HSTR:
328 case T_OSTR:
329 case T_CSTR: // TTCN-3 charstring
330 case T_ENUM_T:
331 /* The list of types supporting RAW encoding is described in the
332 * API guide, section 3.3; this batch of labels plus the next three
333 * accurately match the list.
334 *
335 * For TEXT, it's section 3.4; the list does not include real and
336 * bin/hex/octet strings
337 */
338 case T_USTR: // TTCN-3 universal charstring, this is an addition for XER attributes
339 case T_VERDICT: // TTCN-3 verdict, for XER
340
341 if(rawattrib==NULL){
342 rawattrib= new RawAST(typetype==T_INT);
343 if(typetype==T_REAL) rawattrib->fieldlength=64;
344 new_raw=true;
345 }
346 if(textattrib==NULL){textattrib= new TextAST; new_text=true;}
347 if (xerattrib==NULL) {
348 xerattrib = new XerAttributes; new_xer = true;
349 }
350 if (berattrib==NULL) {
351 berattrib = new BerAST;
352 new_ber = true;
353 }
354
355 if (NULL == jsonattrib) {
356 jsonattrib = new JsonAST;
357 new_json = true;
358 }
359
360 if(w_attrib_path)
361 {
362 vector<SingleWithAttrib> const &real_attribs
363 = w_attrib_path->get_real_attrib();
364 // These are attributes without qualifiers.
365
366 size_t nof_elements = real_attribs.size();
367 for(size_t i = 0; i < nof_elements; i++)
368 {
369 SingleWithAttrib *temp_single = real_attribs[i];
370 if (temp_single->get_attribKeyword() ==
371 SingleWithAttrib::AT_VARIANT) { // only "variant" is parsed
372 parse_rawAST(rawattrib, textattrib, xerattrib, berattrib, jsonattrib,
373 temp_single->get_attribSpec(), get_length_multiplier(),
374 my_scope->get_scope_mod(),
375 raw_found, text_found, xer_found, ber_found, json_found);
376 // textattrib->print_TextAST();
377 // rawattrib->print_RawAST();
378 // xerattrib->print(get_fullname().c_str());
379 } // if AT_VARIANT
380 } // next i
381 }
382
383 if(!raw_found && new_raw){ delete rawattrib; rawattrib=NULL;}
384 if(!text_found && new_text){ delete textattrib; textattrib=NULL;}
385 if(!xer_found && new_xer){ delete xerattrib; xerattrib = NULL; }
386 if(!ber_found && new_ber){ delete berattrib; berattrib = NULL; }
387 if (!json_found && new_json) {
388 delete jsonattrib;
389 jsonattrib = NULL;
390 }
391 break;
392 case T_SEQOF:
393 case T_SETOF:
394 case T_CHOICE_T:
395 case T_SEQ_T:
396 case T_SET_T:
397 case T_ANYTYPE:
398 if(rawattrib==NULL) {rawattrib= new RawAST; new_raw=true;}
399 if(textattrib==NULL){textattrib= new TextAST; new_text=true;}
400 if(xerattrib==NULL) {xerattrib = new XerAttributes; new_xer = true;}
401 if(berattrib==NULL) {berattrib = new BerAST; new_ber = true;}
402 if (NULL == jsonattrib) {
403 jsonattrib = new JsonAST;
404 new_json = true;
405 }
406
407 if(w_attrib_path)
408 {
409 vector<SingleWithAttrib> const &real_attribs
410 = w_attrib_path->get_real_attrib();
411
412 //calculate the type's attributes (the qualifierless ones)
413 size_t nof_elements = real_attribs.size();
414 for(size_t i = 0; i < nof_elements; i++)
415 {
416 SingleWithAttrib *temp_single = real_attribs[i];
417 if(temp_single->get_attribKeyword() == SingleWithAttrib::AT_VARIANT
418 && (!temp_single->get_attribQualifiers()
419 || temp_single->get_attribQualifiers()->get_nof_qualifiers()
420 == 0)){
421 // raw/text/xer/ber/json attributes for the whole record/seq.
422 // (own or inherited)
423 parse_rawAST(rawattrib, textattrib, xerattrib, berattrib, jsonattrib,
424 temp_single->get_attribSpec(), get_length_multiplier(),
425 my_scope->get_scope_mod(),
426 raw_found, text_found, xer_found, ber_found, json_found);
427 }
428 }
429 //calculate the components attributes
430 MultiWithAttrib* self_attribs = w_attrib_path->get_with_attr();
431 if(self_attribs)
432 {
433 MultiWithAttrib* new_self_attribs = new MultiWithAttrib;
434 SingleWithAttrib* swa = 0;
435
436 // copy all the "encode" attributes
437 for(size_t i = 0; i < self_attribs->get_nof_elements(); i++)
438 {
439 if(self_attribs->get_element(i)->get_attribKeyword()
440 == SingleWithAttrib::AT_ENCODE)
441 {
442 // Copy the attribute without qualifiers
443 const SingleWithAttrib* swaref = self_attribs->get_element(i);
444 swa = new SingleWithAttrib(swaref->get_attribKeyword(),
445 swaref->has_override(), 0, swaref->get_attribSpec().clone());
446 new_self_attribs->add_element(swa);
447 }
448 }
449
450 if(new_self_attribs->get_nof_elements() > 0)
451 { // One or more "encode"s were copied; create a context for them.
452 // This is a member because is has to be owned by this Type
453 // (the components only refer to it).
454 encode_attrib_path = new WithAttribPath;
455 encode_attrib_path->set_with_attr(new_self_attribs);
456 encode_attrib_path->set_parent(w_attrib_path->get_parent());
457 }
458 else delete new_self_attribs;
459
460 // This should be bool, but gcc 4.1.2-sol8 generates incorrect code
461 // with -O2 :(
462 const int se_of = (typetype == T_SEQOF || typetype == T_SETOF);
463 const size_t nof_comps = se_of ? 1 : get_nof_comps();
464
465 // Distribute the attributes with qualifiers to the components.
466 // If the type is a sequence-of or set-of, we pretend it to have
467 // one component with the name "_0" (a valid TTCN-3 identifier
468 // can't begin with an underscore). compiler.y has created
469 // the appropriate identifier in the qualifier for a "[-]".
470 for(size_t i = 0; i < nof_comps; i++)
471 {
472 const Identifier& comp_id =
473 se_of ? underscore_zero : get_comp_id_byIndex(i);
474 MultiWithAttrib* component_attribs = new MultiWithAttrib;
475
476 for(size_t j = 0; j < self_attribs->get_nof_elements(); j++)
477 {
478 const SingleWithAttrib *temp_single =
479 self_attribs->get_element(j);
480 Qualifiers* temp_qualifiers =
481 temp_single->get_attribQualifiers();
482 if( !temp_qualifiers
483 || temp_qualifiers->get_nof_qualifiers() == 0) continue;
484
485 Qualifiers* calculated_qualifiers = new Qualifiers;
486 bool qualifier_added = false;
487 for(size_t k=0; k < temp_qualifiers->get_nof_qualifiers(); )
488 {
489 const Qualifier* temp_qualifier =
490 temp_qualifiers->get_qualifier(k);
491 if(temp_qualifier->get_nof_identifiers() > 0
492 && (*temp_qualifier->get_identifier(0) == comp_id))
493 {
494 // Found a qualifier whose first identifier matches
495 // the component name. Remove the qualifier from the
496 // enclosing type, chop off its head,
497 // and add it to the component's qualifiers.
498 calculated_qualifiers->add_qualifier(
499 temp_qualifier->get_qualifier_without_first_id());
500 temp_qualifiers->delete_qualifier(k);
501 qualifier_added = true;
502 }
503 else k++;
504 } // next qualifier
505
506 if(qualifier_added)
507 {
508 // A copy of temp_single, with new qualifiers
509 SingleWithAttrib* temp_single2
510 = new SingleWithAttrib(temp_single->get_attribKeyword(),
511 temp_single->has_override(),
512 calculated_qualifiers,
513 temp_single->get_attribSpec().clone());
514 temp_single2->set_location(*temp_single);
515 component_attribs->add_element(temp_single2);
516 }
517 else delete calculated_qualifiers;
518 } // next attrib
519
520 if (component_attribs->get_nof_elements() > 0) {
521 Type* component_type = se_of ?
522 get_ofType() : get_comp_byIndex(i)->get_type();
523
524 if(encode_attrib_path)
525 // The record's "encode" attributes (only) apply to the fields.
526 // Interpose them in the path of the field.
527 component_type->set_parent_path(encode_attrib_path);
528 else
529 component_type->set_parent_path(w_attrib_path->get_parent());
530
531 component_type->set_with_attr(component_attribs);
532 }
533 else delete component_attribs;
534 } // next component index
535
536 // Any remaining attributes with qualifiers are erroneous
537 for(size_t i = 0; i < self_attribs->get_nof_elements();)
538 {
539 Qualifiers *temp_qualifiers = self_attribs->get_element(i)
540 ->get_attribQualifiers();
541 if(temp_qualifiers && temp_qualifiers->get_nof_qualifiers() != 0)
542 {
543 size_t nof_qualifiers = temp_qualifiers->get_nof_qualifiers();
544 for(size_t j = 0; j < nof_qualifiers; j++)
545 {
546 const Qualifier *temp_qualifier =
547 temp_qualifiers->get_qualifier(j);
548 const Identifier& tmp_id = *temp_qualifier->get_identifier(0);
549 // Special case when trying to reference the inner type
550 // of a record-of when it wasn't a record-of.
551 if (tmp_id == underscore_zero) temp_qualifier->error(
552 "Invalid field qualifier [-]");
553 else temp_qualifier->error("Invalid field qualifier %s",
554 tmp_id.get_dispname().c_str());
555 }
556 self_attribs->delete_element(i);
557 }else{
558 i++;
559 }
560 } // next i
561 } // end if(self_attribs)
562 } // end if(w_attrib_path)
563 if (!raw_found && new_raw) { delete rawattrib; rawattrib = NULL; }
564 if (!text_found && new_text){ delete textattrib; textattrib= NULL; }
565 if (!xer_found && new_xer) { delete xerattrib; xerattrib = NULL; }
566 if (!ber_found && new_ber) { delete berattrib; berattrib = NULL; }
567 if (!json_found && new_json) {
568 delete jsonattrib;
569 jsonattrib = NULL;
570 }
571 break;
572 default:
573 // nothing to do, ASN1 types or types without defined raw attribute
574 break;
575 } // switch
576 if (rawattrib && !enable_raw()) { delete rawattrib; rawattrib = NULL;}
577 if (textattrib&& !enable_text()){ delete textattrib; textattrib= NULL;}
578 if (xerattrib && !enable_xer()) { delete xerattrib; xerattrib = NULL;}
579 if (berattrib && !enable_ber()) { delete berattrib; berattrib = NULL;}
580 if (NULL != jsonattrib && !enable_json()) {
581 delete jsonattrib;
582 jsonattrib = NULL;
583 }
584 } // endif( hasVariantAttrs && enable_{raw,text,xer} )
585
586 raw_parsed = true;
587 }
588
589 // Implements "NAME AS ..." transformations.
590 void change_name(string &name, XerAttributes::NameChange change) {
591 switch (change.kw_) {
592 case NamespaceSpecification::NO_MANGLING:
593 break; // cool, nothing to do!
594
595 case NamespaceSpecification::UPPERCASED:
596 // Walking backwards calls size() only once. Loop var must be signed.
597 for (int i = name.size()-1; i >= 0; --i) {
598 name[i] = toupper(name[i]);
599 }
600 break;
601
602 case NamespaceSpecification::LOWERCASED:
603 for (int i = name.size()-1; i >= 0; --i) {
604 name[i] = tolower(name[i]);
605 }
606 break;
607
608 case NamespaceSpecification::CAPITALIZED:
609 name[0] = toupper(name[0]);
610 break;
611
612 case NamespaceSpecification::UNCAPITALIZED:
613 name[0] = tolower(name[0]);
614 break;
615
616 default: // explicitly specified name
617 name = change.nn_;
618 break;
619 } // switch for NAME
620 }
621
622 void Type::chk_xer_any_attributes()
623 {
624 Type * const last = get_type_refd_last();
625 switch (last->typetype == T_SEQOF ?
626 last->u.seof.ofType->get_type_refd_last()->typetype : 0) {
627 case T_UTF8STRING: // SEQUENCE OF UTF8String, ASN.1
628 case T_USTR: // record of universal charstring
629 break;
630 // fall through
631 default:
632 error("ANY-ATTRIBUTES can only be applied to record of string");
633 break;
634 } // switch
635
636 switch (parent_type != NULL ? parent_type->typetype : 0) {
637 case T_SEQ_A: case T_SET_A:
638 case T_SEQ_T: case T_SET_T:
639 for (size_t x = 0; x < parent_type->get_nof_comps(); ++x) {
640 CompField * cf = parent_type->get_comp_byIndex(x);
641 if (cf->get_type() != this) continue;
642 if (cf->has_default()) {
643 error("The field with ANY-ATTRIBUTES cannot have DEFAULT");
644 }
645 }
646 break;
647 default:
648 error("ANY-ATTRIBUTES can only be applied to a member of "
649 "SEQUENCE, SET, record or set");
650 break;
651 }
652
653 if (xerattrib->untagged_
654 || (parent_type && parent_type->xerattrib && parent_type->xerattrib->untagged_)) {
655 error("Neither the type with ANY-ATTRIBUTES, nor its enclosing type "
656 "may be marked UNTAGGED");
657 }
658 }
659
660 void Type::chk_xer_any_element()
661 {
662 Type *const last = get_type_refd_last();
663 switch (last->typetype) {
664 case T_UTF8STRING: // UTF8String, ASN.1
665 case T_USTR: // universal charstring
666 break; // acceptable
667 case T_SEQOF: {
668 /* A special case for TTCN-3 where applying ANY-ELEMENT to the record-of
669 * has the same effect as applying it to the string member.
670 * This should no longer be necessary now that we can refer
671 * to the embedded type of a record-of with [-], but it has to stay
672 * unless the standard deprecates it. */
673 Type *oftype = last->u.seof.ofType;
674 if (oftype->xerattrib == 0) oftype->xerattrib = new XerAttributes;
675 // Transfer the ANY-ATTRIBUTE from the record-of to its member type
676 oftype->xerattrib->anyElement_ = xerattrib->anyElement_;
677 xerattrib->anyElement_.nElements_ = 0;
678 xerattrib->anyElement_.uris_ = 0;
679 // Re-check the member type since we fiddled with it
680 const char * type_name = "record of";
681 Error_Context cntxt(this, "In embedded type of %s", type_name);
682 oftype->xer_checked = false;
683 oftype->chk_xer();
684 break; }
685 default:
686 error("ANY-ELEMENT can only be applied to UTF8String "
687 "or universal charstring type");
688 break;
689 } // switch
690
691 if (xerattrib->attribute_ || xerattrib->base64_ || xerattrib->untagged_
692 || xerattrib->defaultForEmpty_ != NULL
693 || xerattrib->whitespace_ != XerAttributes::PRESERVE) {
694 error("A type with ANY-ELEMENT may not have any of the following encoding instructions: "
695 "ATTRIBUTE, BASE64, DEFAULT-FOR-EMPTY, PI-OR-COMMENT, UNTAGGED or WHITESPACE");
696 }
697 }
698
699 void Type::chk_xer_attribute()
700 {
701 if (xerattrib->element_) {
702 error("ELEMENT and ATTRIBUTE are incompatible");
703 }
704
705 switch (parent_type!=NULL ? parent_type->typetype :-0) {
706 case 0: // no parent accepted in case a field of this type is declared
707 case T_SEQ_A: case T_SEQ_T:
708 case T_SET_A: case T_SET_T:
709 break; // acceptable
710 default:
711 error("A type with ATTRIBUTE must be a member of "
712 "SEQUENCE, SET, record or set");
713 break;
714 }
715
716 if (xerattrib->untagged_
717 || (parent_type && parent_type->xerattrib && parent_type->xerattrib->untagged_)) {
718 error("Neither the type with ATTRIBUTE, nor its enclosing type "
719 "may be marked UNTAGGED");
720 }
721
722 if (has_ae(xerattrib)) {
723 // TODO: || (xerattrib->defaultForEmpty_ && it is an ASN.1 type)
724 // DEFAULT-FOR-EMPTY is allowed only for TTCN-3
725 error("A type with ATTRIBUTE shall not also have any of the final "
726 "encoding instructions ANY-ELEMENT" /*", DEFAULT-FOR-EMPTY"*/ " or PI-OR-COMMENT");
727 }
728 }
729
730 /// CompField cache
731 struct CFCache {
732 /// Pointer to the field
733 CompField *cf;
734 /// The type of the field
735 Type *top;
736 /// The ultimate type, top->get_type_refd_last()
737 Type *last;
738 /// The typetype of last, on which we sort. Its name is meant to be
739 /// mnemonic (it belongs to \c last, not \c top)
740 Type::typetype_t lastt;
741 };
742
743 /// Comparison function for CFCache based on typetype
744 int tcomp(const void *l, const void *r)
745 {
746 int retval = ((const CFCache*)l)->lastt - ((const CFCache*)r)->lastt;
747 return retval;
748 }
749
750 /** Find the original component name if it was changed by TEXT
751 *
752 * If there is a TEXT whose \a new_text matches \p text, return
753 * the corresponding \a target.
754 *
755 * If there are no TEXT coding instructions, always returns \p text.
756 *
757 * @param[in,out] text on input, a name possibly modified by any TEXT encoding
758 * instruction; on output, the actual component name
759 */
760 void Type::target_of_text(string & text)
761 {
762 for (size_t t = 0; t < xerattrib->num_text_; ++t) {
763 NamespaceSpecification& txt = xerattrib->text_[t];
764
765 if ((unsigned long)txt.prefix == 0
766 ||(unsigned long)txt.prefix == NamespaceSpecification::ALL) {
767 FATAL_ERROR("Type::target_of_text()");
768 continue;
769 }
770
771 string target(txt.target);
772
773 switch ((unsigned long)txt.new_text) {
774 case NamespaceSpecification::CAPITALIZED: // tARGET -> TARGET
775 target[0] = toupper(target[0]);
776 break;
777 case NamespaceSpecification::UNCAPITALIZED:
778 target[0] = tolower(target[0]); // TARGET -> tARGET
779 break;
780 case NamespaceSpecification::UPPERCASED:
781 for (int si = target.size() - 1; si >= 0; --si) {
782 target[si] = toupper(target[si]);
783 }
784 break;
785 case NamespaceSpecification::LOWERCASED:
786 for (int si = target.size() - 1; si >= 0; --si) {
787 target[si] = tolower(target[si]);
788 }
789 break;
790
791 case 0: // "text" not possible
792 FATAL_ERROR("Type::target_of_text() Text with no target and DFE");
793 break;
794
795 default: // it's a string, "text 'field' as 'string'"
796 target = txt.uri;
797 break;
798 } // switch new_text
799
800 if (target == text) {
801 text = txt.target; // we want the value before the change
802 break;
803 }
804 } // next text
805 }
806
807 // The suffix of the name of the variable which contains the D-F-E value.
808 static const string dfe_suffix("_dfe");
809
810 /** Construct a Value to represent defaultForEmpty
811 *
812 * @param last pointer to a Type which is the end of the reference chain,
813 * usually this->get_type_refd_last()
814 * @param dfe_str string containing the value from defaultForEmpty
815 * @return a newly allocated Common::Value
816 */
817 Value *Type::new_value_for_dfe(Type *last, const char *dfe_str)
818 {
819 string defaultstring(dfe_str);
820 switch (last->typetype) {
821 case T_CSTR:
822 case T_USTR:
823 case T_UTF8STRING:
824 return new Value(Common::Value::V_CSTR,
825 new string(defaultstring));
826
827 case T_INT:
828 case T_INT_A:
829 return new Value(Common::Value::V_INT,
830 new int_val_t(dfe_str, *this));
831
832 case T_REAL: {
833 const Real& rval = string2Real(dfe_str, *this);
834 return new Value(Value::V_REAL, rval);
835 }
836
837 case T_BOOL: {
838 if (!strcmp(dfe_str, "true")
839 ||!strcmp(dfe_str, "1")) {
840 return new Value(Value::V_BOOL, true);
841 }
842 else if (!strcmp(dfe_str, "false")
843 || !strcmp(dfe_str, "0")) {
844 return new Value(Value::V_BOOL, false);
845 }
846 else error("Invalid boolean default value");
847 break;
848 }
849
850 case T_ENUM_A: case T_ENUM_T: {
851 // If there is a TEXT, the DFE value corresponds to TextToBeUsed.
852 // Fetch the "real" name of the field (Target).
853
854 target_of_text(defaultstring);
855
856 Identifier *val_id = new Identifier(Common::Identifier::ID_TTCN, // FIXME when ASN1 is supported
857 defaultstring);
858
859 if (!last->has_ei_withName(*val_id)) {
860 error("No enumeration item item '%s'", defaultstring.c_str());
861 #ifndef NDEBUG
862 for (size_t ee=0; ee < last->u.enums.eis->get_nof_eis(); ++ee) {
863 note("Maybe %s", last->u.enums.eis->get_ei_byIndex(ee)->get_name().get_name().c_str());
864 }
865 #endif
866 }
867
868 return new Value(Common::Value::V_ENUM, val_id);
869 }
870
871 case T_CHOICE_A: case T_CHOICE_T: {
872 // Try to guess which alternative the given DFE text belongs to.
873 // Sort the fields based on typetype, so BOOL, INT, REAL, ENUM
874 // are tried before the various string types
875 // (any string looks 'right' for a string value).
876 size_t num_comps = last->get_nof_comps();
877 CFCache *sorted = new CFCache[num_comps];
878 for (size_t c = 0; c < num_comps; c++) {
879 CompField *cf = last->get_comp_byIndex(c);
880 Type *cft = cf->get_type();
881 Type *cftlast = cft->get_type_refd_last();
882 sorted[c].cf = cf;
883 sorted[c].top = cft;
884 sorted[c].last = cftlast;
885 sorted[c].lastt = cftlast->typetype;
886 }
887 qsort(sorted, num_comps, sizeof(CFCache), tcomp);
888
889 Value * retval = 0;
890 size_t c;
891 for (c = 0; c < num_comps && retval == 0; c++) {
892 CFCache &current = sorted[c];
893 // We can't just call new_value_for_dfe(), because some alternatives
894 // would generate errors even if a later type could accept the value.
895 switch (current.lastt) {
896 case T_BOOL:
897 if (!strcmp(dfe_str, "true")
898 ||!strcmp(dfe_str, "1")) {
899 retval = new Value(Value::V_BOOL, true);
900 }
901 else if (!strcmp(dfe_str, "false")
902 || !strcmp(dfe_str, "0")) {
903 retval = new Value(Value::V_BOOL, false);
904 }
905 break;
906
907 case T_INT: case T_INT_A: {
908 const char *start = dfe_str, *end;
909 while (isspace((const unsigned char)*start)) ++start;
910 if (*start == '+') ++start;
911 int ndigits = BN_dec2bn(NULL, start); // includes any '-' sign
912 end = start + ndigits;
913 // Pretend that all trailing whitespace characters were digits
914 while (isspace(*end)) ++ndigits, ++end;
915
916 // Check that all the string was used up in the conversion,
917 // otherwise "3.1415" and "1e6" would appear as integers.
918 if (defaultstring.size() == (size_t)ndigits + (start - dfe_str )) {
919 retval = current.top->new_value_for_dfe(current.last, start);
920 }
921 break; }
922
923 case T_REAL: {
924 float f;
925 char tail[2];
926 int num_converted = sscanf(dfe_str, "%f %1s", &f, tail);
927 // If tail was converted (num_converted>1) that's an error
928 if (num_converted == 1) { // sscanf was happy
929 retval = current.top->new_value_for_dfe(current.last, dfe_str);
930 }
931 break; }
932
933 case T_ENUM_A: case T_ENUM_T: {
934 current.top->target_of_text(defaultstring);
935 Identifier alt(Identifier::ID_TTCN, defaultstring);
936 if (current.last->has_ei_withName(alt)) {
937 retval = current.top->new_value_for_dfe(current.last, dfe_str);
938 }
939 break; }
940
941 case T_CSTR:
942 case T_USTR:
943 case T_UTF8STRING: {
944 retval = current.top->new_value_for_dfe(current.last, dfe_str);
945 break; }
946
947 default:
948 break;
949 } // switch
950 } // next c
951
952 if (retval != 0) {
953 c--;
954 retval->set_genname(sorted[c].top->genname, dfe_suffix);
955 retval->set_my_scope(sorted[c].top->my_scope);
956 retval->set_my_governor(sorted[c].top);
957 Value *choice_retval = new Value(Value::V_CHOICE,
958 new Identifier(sorted[c].cf->get_name()), retval);
959 retval = choice_retval;
960 }
961
962 delete [] sorted;
963 return retval; }
964
965 /* Useless without a properly constructed Value(V_SEQ)
966 case T_SEQ_A: case T_SEQ_T: {
967 NamedValues *nvs = new NamedValues;
968 //NamedValue *nv = new NamedValue(new Identifier, new Value);
969 nvs->add_nv(nv);
970 xerattrib->defaultValue_ = new Value(Value::V_SEQ, nvs);
971 break; }
972 */
973
974 default: // complain later
975 break;
976 } // switch
977 return 0;
978 }
979
980 void Type::chk_xer_dfe()
981 {
982 Type * const last = get_type_refd_last();
983
984 if (/* TODO xerattrib->attribute_ is error for ASN.1 only */
985 xerattrib->untagged_ || has_ae(xerattrib)) {
986 error("A type with DEFAULT-FOR-EMPTY shall not have any of the final "
987 "encoding instructions ANY-ELEMENT, ATTRIBUTE, UNTAGGED."); // 23.2.8
988 }
989
990 if (is_charenc() == Yes) {
991 xerattrib->defaultValue_ = new_value_for_dfe(last, xerattrib->defaultForEmpty_);
992
993 if (xerattrib->defaultValue_ != 0) {
994 xerattrib->defaultValue_->set_genname(this->genname, dfe_suffix);
995 xerattrib->defaultValue_->set_my_scope(this->my_scope);
996 xerattrib->defaultValue_->set_my_governor(last);
997 }
998 else {
999 error("DEFAULT-FOR-EMPTY not supported for character-encodable type %s",
1000 last->get_stringRepr().c_str());
1001 }
1002 }
1003 else if (last->typetype == T_SEQ_A || last->typetype == T_SEQ_T) {
1004 // If DEFAULT-FOR-EMPTY applies to a record (SEQUENCE), then only one
1005 // component can produce element content, and it should be the last,
1006 // because all the others should have ATTRIBUTE or ANY-ATTRIBUTE,
1007 // and those are moved to the front. 23.2.2 b)
1008 // FIXME only b) appears to have this restriction, not c)d)e)
1009 const size_t num_cf = last->get_nof_comps();
1010 if (num_cf > 0) {
1011 CompField *cf = last->get_comp_byIndex(num_cf-1); // last field
1012 Type *cft = cf->get_type(); // cft: CompField type
1013 cft = cft->get_type_refd_last();
1014 //typetype_t cftt = cft->get_typetype();
1015
1016 xerattrib->defaultValue_ = new_value_for_dfe(cft, xerattrib->defaultForEmpty_);
1017 if (xerattrib->defaultValue_ != 0) {
1018 xerattrib->defaultValue_->set_genname(last->genname, string("_dfe"));
1019 xerattrib->defaultValue_->set_my_scope(cft->my_scope);
1020 xerattrib->defaultValue_->set_my_governor(cft);
1021 }
1022 else {
1023 error("DEFAULT-FOR-EMPTY not supported for fields of type %s",
1024 cft->get_stringRepr().c_str());
1025 }
1026 } // endif comps >0
1027 } // if SEQ/SET
1028 else {
1029 error("DEFAULT-FOR-EMPTY not applicable to type");
1030 }
1031 }
1032
1033 void Type::chk_xer_embed_values(int num_attributes)
1034 {
1035 Type * const last = get_type_refd_last();
1036
1037 enum complaint_type { ALL_GOOD, OPTIONAL_OR_DEFAULT, UNTAGGED_EMBEDVAL,
1038 NOT_SEQUENCE, EMPTY_SEQUENCE, FIRST_NOT_SEQOF, SEQOF_NOT_STRING,
1039 SEQOF_BAD_LENGTH, UNTAGGED_OTHER } ;
1040 complaint_type complaint = ALL_GOOD;
1041 size_t expected_length = (size_t)-1;
1042 Type *cf0t = 0; // type of first component
1043 CompField *cf = 0;
1044 switch (last->typetype) {
1045 case T_SEQ_A: case T_SEQ_T: { // 25.2.1, the type must be a sequence
1046 const size_t num_cf = last->get_nof_comps();
1047 if (num_cf == 0) {
1048 complaint = EMPTY_SEQUENCE; // must have a "first component"
1049 break;
1050 }
1051 CompField *cf0 = last->get_comp_byIndex(0);
1052 cf0t = cf0->get_type()->get_type_refd_last();
1053 if (cf0->get_is_optional() || cf0->has_default()) {
1054 complaint = OPTIONAL_OR_DEFAULT;
1055 break; // 25.2.1 first component cannot be optional or have default
1056 }
1057
1058 switch (cf0t->get_typetype()) { // check the first component
1059 case T_SEQOF: {
1060 Type *cfot = cf0t->get_ofType(); // embedded type
1061 switch (cfot->get_type_refd_last()->get_typetype()) {
1062 case T_UTF8STRING:
1063 case T_USTR: { // hooray, a SEQUENCE OF some string
1064 if ( (cf0t->xerattrib && cf0t->xerattrib->untagged_)
1065 || (cfot->xerattrib && cfot->xerattrib->untagged_)) {
1066 complaint = UNTAGGED_EMBEDVAL; // 25.2.2
1067 break;
1068 }
1069
1070 // Check length restriction on the record of. If there is one,
1071 // it better be the correct number.
1072 // FIXME: if there is also a USE-NIL, it cannot have a length restriction; only check at runtime
1073 const SubType *sub = cf0t->sub_type;
1074 const Int len = sub ? sub->get_length_restriction() :-1;
1075 // get_length_restriction() itself may return -1
1076 expected_length = num_cf -num_attributes -xerattrib->useOrder_;
1077 if (len > 0 && (size_t)len != expected_length) {
1078 // The +1 from 25.2.6 b) is compensated because
1079 // the EMBED-VALUES member itself is ignored.
1080 complaint = SEQOF_BAD_LENGTH;
1081 break;
1082 }
1083 break; } //acceptable
1084
1085 default: // 25.2.1
1086 complaint = SEQOF_NOT_STRING;
1087 break;
1088 } // switch
1089 break; }
1090
1091 default: // 25.2.1
1092 complaint = FIRST_NOT_SEQOF;
1093 break;
1094 } // switch(type of first component)
1095
1096 for (size_t c = 1; c < num_cf; ++c) { // check the other components
1097 cf = last->get_comp_byIndex(c);
1098 Type *cft = cf->get_type()->get_type_refd_last();
1099 if (cft->xerattrib && cft->xerattrib->untagged_ && (cft->is_charenc() == Yes)){
1100 complaint = UNTAGGED_OTHER;
1101 break;
1102 }
1103 }
1104 break; } // case T_SEQ*
1105
1106 default:
1107 complaint = NOT_SEQUENCE;
1108 break;
1109 } // switch typetype
1110
1111 // TODO 25.2.4, 25.2.5
1112 if (complaint == ALL_GOOD) embed_values_possible = true;
1113 else if (xerattrib->embedValues_) {
1114 switch (complaint) {
1115 case ALL_GOOD: // Not possible; present in the switch so GCC checks
1116 // that all enum values are handled (make sure there's no default).
1117 break;
1118 case NOT_SEQUENCE:
1119 case EMPTY_SEQUENCE:
1120 case FIRST_NOT_SEQOF:
1121 case SEQOF_NOT_STRING:
1122 case OPTIONAL_OR_DEFAULT:
1123 error("A type with EMBED-VALUES must be a sequence type. "
1124 "The first component of the sequence shall be SEQUENCE OF UTF8String "
1125 "and shall not be marked OPTIONAL or DEFAULT");
1126 break;
1127 case SEQOF_BAD_LENGTH:
1128 cf0t->error("Wrong length of SEQUENCE-OF for EMBED-VALUES, should be %lu",
1129 (unsigned long)expected_length);
1130 break;
1131 case UNTAGGED_EMBEDVAL:
1132 error("Neither the SEQUENCE-OF supporting EMBED-VALUES,"
1133 "nor its component shall have UNTAGGED."); // 25.2.2
1134 break;
1135 case UNTAGGED_OTHER:
1136 cf->error("There shall be no UNTAGGED on any character-encodable "
1137 "component of a type with DEFAULT-FOR-EMPTY"); // 25.2.3
1138 break;
1139 } // switch(complaint)
1140 } // if complaint and embedValues
1141 }
1142
1143 /** Wraps a C string but compares by contents, not by pointer */
1144 class stringval {
1145 const char * str;
1146 public:
1147 explicit stringval(const char *s = 0) : str(s) {}
1148 // no destructor
1149 bool operator<(const stringval& right) const {
1150 if ( str > (const char*)NamespaceSpecification::ALL
1151 && right.str > (const char*)NamespaceSpecification::ALL)
1152 {
1153 return strcmp(str, right.str) < 0;
1154 }
1155 else return str < right.str;
1156 }
1157 bool operator==(const stringval& right) const {
1158 if ( str > (const char*)NamespaceSpecification::ALL
1159 && right.str > (const char*)NamespaceSpecification::ALL)
1160 {
1161 return strcmp(str, right.str) == 0;
1162 }
1163 else return str == right.str;
1164 }
1165 //bool operator!() const { return str==0; }
1166 const char *c_str() const { return str; }
1167 };
1168
1169
1170 void Type::chk_xer_text()
1171 {
1172 if (xerattrib->num_text_ == 0
1173 ||xerattrib->text_ == 0 ) FATAL_ERROR("Type::chk_xer_text()");
1174 Type * const last = get_type_refd_last();
1175 static const stringval empty; // NULL pointer
1176
1177 // Check the type and quit early if wrong
1178 switch (last->typetype) {
1179 case T_BOOL:
1180 break;
1181 case T_ENUM_A: // not yet
1182 error("No XER yet for ASN.1 enumerations");
1183 return;
1184 case T_ENUM_T:
1185 break;
1186 case T_BSTR_A: // ASN.1 bit string with named bits, not yet
1187 error("No XER yet for ASN.1 bit strings");
1188 return;
1189 case T_INT_A: // ASN.1 integer with named numbers, not yet
1190 error("No XER yet for ASN.1 named numbers");
1191 return;
1192 default:
1193 error("TEXT not allowed for type %s", get_typename().c_str());
1194 return;
1195 }
1196
1197 // Build a map to eliminate duplicates (new assignment to the same
1198 // enum item/field overwrites previous text).
1199 // Keys are the identifiers, values are the texts.
1200 typedef map<stringval, char> text_map_t;
1201 text_map_t text_map;
1202
1203 for (size_t t = 0; t < xerattrib->num_text_; ++t) {
1204 NamespaceSpecification & txt = xerattrib->text_[t];
1205 switch ((unsigned long)txt.target) {
1206 case 0: { // just "TEXT".
1207 // target=0 and new_text!=0 would have to come from "TEXT AS ..."
1208 // but that's not allowed by syntax, hence FATAL_ERROR.
1209 if (txt.new_text) FATAL_ERROR("Type::chk_xer_text");
1210 if (!text_map.has_key(empty)) {
1211 text_map.add(empty, txt.new_text);
1212 }
1213 if (last->typetype != T_BOOL) {
1214 error("Lone 'TEXT' only allowed for boolean"); // only in TTCN-3 !
1215 }
1216 break; }
1217
1218 case NamespaceSpecification::ALL: {// TEXT ALL AS ...
1219 switch (txt.keyword) {
1220 case NamespaceSpecification::NO_MANGLING:
1221 // Not possible due to syntax; there is no TTCN source from which
1222 // the bison parser would create such a NamespaceSpecification.
1223 FATAL_ERROR("Type::chk_xer_text");
1224 break;
1225 case NamespaceSpecification::CAPITALIZED:
1226 case NamespaceSpecification::UNCAPITALIZED:
1227 case NamespaceSpecification::LOWERCASED:
1228 case NamespaceSpecification::UPPERCASED:
1229 break; // OK
1230
1231 default: // TEXT ALL AS "some string" is not allowed
1232 error("text all as 'string' is not allowed");
1233 continue;
1234 } // switch(keyword)
1235
1236 // Expand the "all"
1237 switch (last->typetype) {
1238 case T_BOOL:
1239 text_map.add(stringval(mcopystr("true")), txt.new_text);
1240 text_map.add(stringval(mcopystr("false")), txt.new_text);
1241 break;
1242
1243 //case T_ENUM_A:
1244 case T_ENUM_T: {
1245 size_t n_eis = last->u.enums.eis->get_nof_eis();
1246 for (size_t i = 0; i < n_eis; ++i) {
1247 EnumItem *ei = last->u.enums.eis->get_ei_byIndex(i);
1248 const stringval enum_name(mcopystr(ei->get_name().get_ttcnname().c_str()));
1249 if (text_map.has_key(enum_name)) {
1250 // Duplicate enum name, flagged elsewhere as error.
1251 // Don't bother with: text_map[enum_name] = txt.new_text;
1252 Free(const_cast<char*>(enum_name.c_str()));
1253 }
1254 else text_map.add(enum_name, txt.new_text);
1255 }
1256 break; }
1257
1258 default:
1259 FATAL_ERROR("Type::chk_xer_text");
1260 break;
1261 } // switch (typetype)
1262 break;
1263 }
1264
1265 default: {// a string: TEXT 'member' AS ...
1266 if (txt.keyword == NamespaceSpecification::NO_MANGLING) {
1267 // Attribute syntax does not allow this combination
1268 FATAL_ERROR("Type::chk_xer_text");
1269 }
1270 // HR39956: empty string is disregarded
1271 if (txt.keyword>NamespaceSpecification::LOWERCASED && !strcmp(txt.new_text,""))
1272 {
1273 txt.new_text = (char*)Realloc(txt.new_text, sizeof(" "));
1274 strcpy(txt.new_text," ");
1275 }
1276 stringval ttarget(txt.target);
1277 if (text_map.has_key(ttarget)) {
1278 // Override the earlier TEXT instruction
1279 free_name_or_kw(text_map[ttarget]);
1280 text_map[ttarget] = txt.new_text;
1281 free_name_or_kw(txt.target);
1282 }
1283 else text_map.add(ttarget, txt.new_text);
1284 break; }
1285 } // switch(target)
1286 } // next text
1287
1288 xerattrib->text_ = (NamespaceSpecification*)Realloc(xerattrib->text_,
1289 text_map.size() * sizeof(NamespaceSpecification));
1290
1291 // Zero out the newly allocated part
1292 if (text_map.size() > xerattrib->num_text_) {
1293 memset(
1294 xerattrib->text_ + xerattrib->num_text_,
1295 0,
1296 (text_map.size() - xerattrib->num_text_) * sizeof(NamespaceSpecification)
1297 );
1298 }
1299
1300 xerattrib->num_text_ = text_map.size(); // accept the new size
1301
1302 // Another map, to check for duplicate text (decoding would be impossible)
1303 text_map_t map2;
1304
1305 // Reconstruct the TEXT structure from the map
1306 for (size_t t = 0; t < xerattrib->num_text_; ++t) {
1307 const stringval& k = text_map.get_nth_key(t);
1308 char * v = text_map.get_nth_elem(t);
1309 char * newstr = const_cast<char*>(k.c_str());
1310
1311 xerattrib->text_[t].target = newstr;
1312 xerattrib->text_[t].new_text = v;
1313
1314 stringval txtval(v); // somebody else owns v
1315 if (map2.has_key(txtval)) {
1316 switch (xerattrib->text_[t].keyword) {
1317 case NamespaceSpecification::NO_MANGLING:
1318 FATAL_ERROR("nope");
1319 break; // not possible
1320
1321 case NamespaceSpecification::CAPITALIZED:
1322 case NamespaceSpecification::UNCAPITALIZED:
1323 case NamespaceSpecification::LOWERCASED:
1324 case NamespaceSpecification::UPPERCASED:
1325 // Duplication may have been caused by expanding TEXT ALL ...
1326 break; // accept it
1327
1328 default: // string must be unique
1329 error("Duplicate text '%s'", v);
1330 break;
1331 }
1332 }
1333 else map2.add(txtval, newstr);
1334 }
1335 text_map.clear();
1336 map2.clear();
1337 // // //
1338 for (size_t t = 0; t < xerattrib->num_text_; ++t) {
1339 if (xerattrib->useNumber_) {
1340 error("USE-NUMBER and TEXT are incompatible");
1341 break;
1342 }
1343 NamespaceSpecification & txt = xerattrib->text_[t];
1344
1345 switch (last->typetype) {
1346 case T_BOOL:
1347 /* In ASN.1, Only Booleantype:ALL can have TEXT
1348 * Currently for TTCN, only the following three case are supported:
1349 * "text"
1350 * "text 'true' as '1'"
1351 * "text 'false' as '0'"
1352 * and we convert the last two to the first
1353 */
1354 switch ((unsigned long)txt.prefix) {
1355 case 0: // no Target (ok);
1356 if (txt.uri != 0) error("Only \"text\" implemented for boolean");
1357 break;
1358 case NamespaceSpecification::ALL: // Target = 'all' not allowed for boolean
1359 error("TEXT all not implemented for boolean");
1360 break;
1361 default: // a string, must be "true" or "false"
1362 if (!strcmp(txt.prefix, "true")) {
1363 // only "1" is allowed for "true"
1364 switch ((unsigned long)txt.uri) {
1365 default: // it's a string
1366 if (txt.uri[0] == '1' && txt.uri[1] == '\0') {
1367 // Free the strings to pretend it was a simple "text"
1368 Free(txt.prefix); txt.prefix = 0;
1369 Free(txt.uri); txt.uri = 0;
1370 // These should come in pairs, warn if not
1371 if (xerattrib->num_text_ == 1) warning("\"text 'false' as '0'\" was implied");
1372 break;
1373 }
1374 // else fall through
1375 case NamespaceSpecification::CAPITALIZED:
1376 case NamespaceSpecification::UNCAPITALIZED:
1377 case NamespaceSpecification::UPPERCASED:
1378 case NamespaceSpecification::LOWERCASED:
1379 error("Only '1' is supported for 'true'");
1380 break;
1381
1382 case 0: // "text 'true'" is not correct syntax, cannot get here
1383 FATAL_ERROR("Type::chk_xer_text()");
1384 } // switch uri
1385 }
1386 else if (!strcmp(txt.prefix, "false")) {
1387 // only "0" is allowed for "false"
1388 switch ((unsigned long)txt.uri) {
1389 default: // it's a string
1390 if (txt.uri[0] == '0' && txt.uri[1] == '\0') {
1391 // Free the strings to pretend it was a simple "text"
1392 Free(txt.prefix); txt.prefix = 0;
1393 Free(txt.uri); txt.uri = 0;
1394 // These should come in pairs, warn if not
1395 if (xerattrib->num_text_ == 1) warning("\"text 'true' as '1'\" was implied");
1396 break;
1397 }
1398 // else fall through
1399 case NamespaceSpecification::CAPITALIZED:
1400 case NamespaceSpecification::UNCAPITALIZED:
1401 case NamespaceSpecification::UPPERCASED:
1402 case NamespaceSpecification::LOWERCASED:
1403 error("Only '0' is supported for 'false'");
1404 break;
1405
1406 case 0: // "text 'false'" is not correct syntax, cannot get here
1407 FATAL_ERROR("Type::chk_xer_text()");
1408 } // switch uri
1409 } // if ("true")
1410 break;
1411 } // switch prefix
1412
1413 break;
1414
1415 //case T_ENUM_A: // fall through
1416 case T_ENUM_T: {
1417 switch ((unsigned long)txt.target) {
1418 case 0: // "text as ..."
1419 case NamespaceSpecification::ALL: { // "text all as ..."
1420 size_t neis = last->u.enums.eis->get_nof_eis();
1421 for (size_t i = 0; i < neis; ++i) {
1422 EnumItem *ei = last->u.enums.eis->get_ei_byIndex(i);
1423 string ei_name(ei->get_name().get_dispname()); // use the element's own name
1424 XerAttributes::NameChange chg;
1425 chg.nn_ = txt.uri;
1426 change_name(ei_name, chg);
1427 ei->set_text(ei_name);
1428 }
1429 break; }
1430
1431 default: { // target is member name, from "text 'member' as ..."
1432 // FIXME: ID_TTCN will not be right if we implement XER for ASN.1
1433 Common::Identifier id(Identifier::ID_TTCN, string(txt.prefix));
1434 if (last->u.enums.eis->get_nof_eis()==0) FATAL_ERROR("No enum items!");
1435 if (last->u.enums.eis->has_ei_withName(id)) {
1436 EnumItem *ei = last->u.enums.eis->get_ei_byName(id);
1437 string ei_name(id.get_dispname());
1438 XerAttributes::NameChange chg;
1439 chg.nn_ = txt.uri;
1440 change_name(ei_name, chg);
1441 ei->set_text(ei_name);
1442 }
1443 else {
1444 error("No enumeration item %s", txt.prefix);
1445 }
1446 break; }
1447 } // switch(target)
1448
1449 break; }
1450
1451 //case T_INT_A:
1452 /*
1453 if (last->u.namednums.nvs->get_nof_nvs()) {
1454 Common::Identifier id(Identifier::ID_TTCN, txt.uri);
1455 NamedValue *nv = last->u.namednums.nvs->get_nv_byName(id);
1456 if (nv != 0) {
1457 // good
1458 }
1459 else {
1460 error("No component %s in %s", txt.uri, fn);
1461 }
1462 }
1463 else {
1464 error("TEXT cannot be assigned to an integer without named numbers");
1465 }
1466 */
1467 //break;
1468
1469 default:
1470 FATAL_ERROR("Type::chk_xer_text");
1471 break;
1472 } // switch
1473 } // next type for TEXT
1474 }
1475
1476 void Type::chk_xer_untagged()
1477 {
1478 Type * const last = get_type_refd_last();
1479 switch (parent_type ? parent_type->typetype :-0) {
1480 case 0: // "no parent" is acceptable
1481 // Do not nag ("UNTAGGED encoding attribute is ignored on top-level type");
1482 // do it in Def_ExtFunction::chk_function_type when the type is actually
1483 // used as input for an encoding function.
1484 // fall through
1485 case T_SEQ_A: case T_SEQ_T:
1486 case T_SET_A: case T_SET_T:
1487 case T_CHOICE_A: case T_CHOICE_T:
1488 case T_SEQOF: case T_SETOF:
1489 break; // acceptable
1490 default:
1491 error("UNTAGGED can only be applied to a member of sequence, set, "
1492 "choice, sequence-of, or set-of type"); // X.693amd1, 32.2.1
1493 break;
1494 }
1495
1496 if ( has_aa(xerattrib)
1497 || has_ae(xerattrib)
1498 || xerattrib->attribute_ || 0 != xerattrib->defaultForEmpty_
1499 || xerattrib->embedValues_ || xerattrib->useNil_
1500 || (xerattrib->useOrder_ && is_asn1()) || xerattrib->useType_) {
1501 error("A type with final encoding attribute UNTAGGED shall not have"
1502 " any of the final encoding instructions ANY-ATTRIBUTES, ANY-ELEMENT,"
1503 " ATTRIBUTE, DEFAULT-FOR-EMPTY, EMBED-VALUES, PI-OR-COMMENT,"
1504 " USE-NIL%s or USE-TYPE",
1505 is_asn1() ? ", USE-ORDER" : ""); // X.693amd1, 32.2.6
1506 }
1507
1508 bool can_become_empty= last->has_empty_xml();
1509 if (can_become_empty) { // checking 32.2.4
1510 switch (parent_type ? parent_type->typetype :-0) {
1511 case 0:
1512 break; // no parent, no problem
1513
1514 case T_SEQ_A: case T_SEQ_T:
1515 case T_SET_A: case T_SET_T: {
1516 // This type can not have OPTIONAL or DEFAULT, 32.2.4 a)
1517 // No get_comp_byType(); do a linear search.
1518 size_t num_fields = parent_type->get_nof_comps();
1519 for (size_t i = 0; i < num_fields; ++i) {
1520 CompField *cf = parent_type->get_comp_byIndex(i);
1521 if (cf->get_type() != this) continue;
1522 // found the component
1523 if (cf->get_is_optional() || cf->get_defval() != 0) {
1524 error("Type with final encoding attribute UNTAGGED"
1525 " shall not have OPIONAL or DEFAULT");
1526 }
1527 break;
1528 }
1529 break; }
1530
1531 case T_SEQOF: case T_SETOF: // X.693amd1, 32.2.4 b)
1532 error("UNTAGGED type with possibly empty XML value can not be "
1533 "the member of a sequence-of or set-of"); // X.693amd1, 32.2.4 b)
1534 break;
1535
1536 case T_CHOICE_T: {
1537 size_t num_fields = parent_type->get_nof_comps();
1538 size_t num_empty = 0;
1539 for (size_t i = 0; i < num_fields; ++i) {
1540 CompField *cf = parent_type->get_comp_byIndex(i);
1541 Type *cft = cf->get_type();
1542 if (cft->has_empty_xml()) ++num_empty;
1543 }
1544 if (num_empty > 1) { // X.693amd1, 32.2.4 c)
1545 /* FIXME: this should be error */
1546 warning("More than one alternative can be empty and has UNTAGGED");
1547 }
1548 break; }
1549
1550 default: // do nothing
1551 break;
1552 }
1553 } // end if(can_become_empty)
1554 }
1555
1556 void Type::chk_xer_use_nil()
1557 {
1558 Type * const last = get_type_refd_last();
1559
1560 enum complaint_type { ALL_GOOD, NO_CONTROLNS, NOT_SEQUENCE, EMPTY_SEQUENCE,
1561 UNTAGGED_USENIL, COMPONENT_NOT_ATTRIBUTE, LAST_IS_ATTRIBUTE,
1562 LAST_NOT_OPTIONAL, INCOMPATIBLE, WRONG_OPTIONAL_TYPE, EMBED_CHARENC };
1563 complaint_type complaint = ALL_GOOD;
1564 CompField *cf = 0;
1565 CompField *cf_last = 0;
1566 const char *ns, *prefix;
1567 my_scope->get_scope_mod()->get_controlns(ns, prefix);
1568
1569 if (!prefix) complaint = NO_CONTROLNS; // don't bother checking further
1570 else switch (last->typetype) {
1571 default:
1572 complaint = NOT_SEQUENCE;
1573 break;
1574
1575 case T_SEQ_A:
1576 error("No XER yet for ASN.1 sequences");
1577 // no break
1578 case T_SEQ_T: {
1579 const size_t num_cf = last->get_nof_comps();
1580 if (num_cf == 0) { // 33.2.1 ...must have a component...
1581 complaint = EMPTY_SEQUENCE;
1582 break; // stop checking to prevent accessing non-existing components
1583 }
1584 if (xerattrib->untagged_) { // 33.2.2
1585 complaint = UNTAGGED_USENIL;
1586 break;
1587 }
1588
1589 // Skip components supporting USE-ORDER or EMBED-VALUES
1590 size_t i = (xerattrib->useOrder_) + (xerattrib->embedValues_);
1591 // 33.2.1 All the others except the last must be (any)attributes
1592 for (; i < num_cf-1; ++i) {
1593 cf = last->get_comp_byIndex(i);
1594 Type *cft = cf->get_type();
1595 if (! (cft->xerattrib
1596 && ( cft->xerattrib->attribute_ || has_aa(cft->xerattrib))))
1597 {
1598 complaint = COMPONENT_NOT_ATTRIBUTE;
1599 break;
1600 }
1601 }
1602 // 33.2.1 The last component must be an OPTIONAL non-attribute
1603 cf_last = last->get_comp_byIndex(num_cf-1);
1604 Type *cft = cf_last->get_type();
1605 if (!cf_last->get_is_optional()) {
1606 complaint = LAST_NOT_OPTIONAL;
1607 }
1608
1609 if (cft->xerattrib) {
1610 if ( cft->xerattrib->attribute_
1611 || has_aa(cft->xerattrib)) {
1612 complaint = LAST_IS_ATTRIBUTE;
1613 break;
1614 }
1615
1616 if (has_ae(cft->xerattrib)
1617 ||has_aa(cft->xerattrib)
1618 ||cft->xerattrib->defaultForEmpty_ != 0
1619 ||cft->xerattrib->embedValues_ ||cft->xerattrib->untagged_
1620 ||cft->xerattrib->useNil_ ||cft->xerattrib->useOrder_
1621 ||cft->xerattrib->useType_) { // or PI-OR-COMMENT
1622 complaint = INCOMPATIBLE; // 33.2.3
1623 }
1624 }
1625
1626 if (cft->is_charenc() == Yes) {
1627 // In a sequence EMBED-VALUES and USE-NIL, the optional component
1628 // supporting USE-NIL shall not be a character-encodable type.
1629 // So says OSS, and rightly so (there's no way to separate
1630 // the last field from the surrounding "embed" strings).
1631 if (xerattrib->embedValues_) complaint = EMBED_CHARENC;
1632 }
1633 else switch (cft->get_type_refd_last()->typetype) {
1634 case T_SEQ_T:
1635 // more checking
1636 case T_SEQ_A:
1637 case T_SET_T:
1638 case T_SET_A:
1639 case T_CHOICE_T:
1640 case T_CHOICE_A:
1641 case T_SEQOF:
1642 case T_SETOF:
1643 case T_OPENTYPE:
1644 // or an octetstring or bitstring with a contained "Type" and without ENCODED BY
1645 break; // acceptable
1646
1647 default:
1648 complaint = WRONG_OPTIONAL_TYPE;
1649 break;
1650 }
1651
1652 break;}
1653 } // else switch(last->typetype)
1654
1655 if (complaint == ALL_GOOD) use_nil_possible = true;
1656 else if (xerattrib->useNil_) {
1657 switch (complaint) {
1658 case ALL_GOOD: // Not possible because of the if.
1659 // Present so GCC checks that all enum values are handled (no default!)
1660 break;
1661 case NO_CONTROLNS:
1662 error("Type has USE-NIL, but the module has no control namespace set");
1663 break;
1664 case NOT_SEQUENCE:
1665 error("The target of an USE-NIL encoding instruction must be a record (SEQUENCE) or set type");
1666 break;
1667 case EMPTY_SEQUENCE:
1668 error("The target of an USE-NIL must have at least one component");
1669 break;
1670 case UNTAGGED_USENIL:
1671 error("The target of an USE-NIL encoding instruction shall not have"
1672 " a final UNTAGGED encoding instruction");
1673 break;
1674 case COMPONENT_NOT_ATTRIBUTE:
1675 cf->error("Component '%s' of USE-NIL not ATTRIBUTE", cf->get_name().get_name().c_str());
1676 break;
1677 case LAST_IS_ATTRIBUTE:
1678 cf_last->error("Last component of USE-NIL must not have ATTRIBUTE");
1679 break;
1680 case LAST_NOT_OPTIONAL:
1681 cf_last->error("Last component of USE-NIL must be OPTIONAL");
1682 break;
1683 case INCOMPATIBLE:
1684 cf_last->error("The OPTIONAL component of USE-NIL cannot have any of the "
1685 "following encoding instructions: ANY-ATTRIBUTES, ANY-ELEMENT, "
1686 "DEFAULT-FOR-EMPTY, EMBED-VALUES, PI-OR-COMMENT, UNTAGGED, "
1687 "USE-NIL, USE-ORDER, USE-TYPE.");
1688 break;
1689 case WRONG_OPTIONAL_TYPE:
1690 cf_last->error("The OPTIONAL component of USE-NIL must be "
1691 "a character-encodable type, or a sequence, set, choice, "
1692 "sequence-of, set-of or open type.");
1693 break;
1694 case EMBED_CHARENC:
1695 cf_last->error("In a sequence type with EMBED-VALUES and USE-NIL, "
1696 "the optional component supporting USE-NIL shall not be "
1697 "a character-encodable type.");
1698 break;
1699 } // switch
1700 } // if USE-NIL
1701 }
1702
1703 void Type::chk_xer_use_order(int num_attributes)
1704 {
1705 Type * const last = get_type_refd_last();
1706
1707 enum complaint_type { ALL_GOOD, NOT_SEQUENCE, NOT_ENOUGH_MEMBERS,
1708 FIRST_NOT_RECORD_OF, FIRST_NOT_RECORD_OF_ENUM, FIRST_OPTIONAL,
1709 LAST_NOT_RECORD, BAD_ENUM, ENUM_GAP, NOTHING_TO_ORDER };
1710 complaint_type complaint = ALL_GOOD;
1711 Type *the_enum = 0; // Well, it's supposed to be an enum.
1712 switch (last->typetype) {
1713 case T_SEQ_A: case T_SEQ_T: { // record/SEQUENCE acceptable
1714 size_t useorder_index = xerattrib->embedValues_;
1715 // The first (or second, if the first is taken by EMBED_VALUES)
1716 // member must be a record of enumerated
1717 if (useorder_index >= last->get_nof_comps()) {
1718 complaint = NOT_ENOUGH_MEMBERS;
1719 break;
1720 }
1721 CompField *uo_field = last->get_comp_byIndex(useorder_index);
1722 Type *uot = uo_field->get_type();
1723 if (uot->get_type_refd_last()->typetype == T_SEQOF) {
1724 the_enum = uot->get_ofType()->get_type_refd_last();
1725 switch (the_enum->typetype) {
1726 case T_ENUM_A: case T_ENUM_T: // acceptable
1727 if (uo_field->get_is_optional() || uo_field->get_defval() != 0) {
1728 complaint = FIRST_OPTIONAL;
1729 }
1730 break;
1731 default:
1732 complaint = FIRST_NOT_RECORD_OF_ENUM;
1733 goto complain2;
1734 } // switch enum type
1735 size_t ncomps = last->get_nof_comps();
1736 // the components of this sequence will have to match the enum
1737 Type *sequence_type = 0;
1738 size_t expected_enum_items, first_non_attr;
1739
1740 if (xerattrib->useNil_) { // useNil in addition to useOrder
1741 // This is an additional complication because USE-ORDER
1742 // will affect the optional component, rather than the type itself
1743 CompField *cf = get_comp_byIndex(ncomps-1);
1744 sequence_type = cf->get_type()->get_type_refd_last();
1745 if (sequence_type->typetype == T_SEQ_T
1746 ||sequence_type->typetype == T_SEQ_A) {
1747
1748 // No need to check that it has at least one component (35.2.1)
1749 // it can't match up with the enum which always has one
1750 ncomps = sequence_type->get_nof_comps();
1751 expected_enum_items = ncomps;
1752 first_non_attr = 0;
1753 }
1754 else { // Whoops, not a sequence type!
1755 complaint = LAST_NOT_RECORD;
1756 break; // the switch(typetype)
1757 }
1758 }
1759 else {
1760 sequence_type = last;
1761 first_non_attr = useorder_index+1+num_attributes;
1762 expected_enum_items = ncomps - first_non_attr;
1763 } // if (use-nil)
1764
1765 size_t enum_index = 0;
1766 if (expected_enum_items == 0)
1767 complaint = NOTHING_TO_ORDER;
1768 else if (the_enum->u.enums.eis->get_nof_eis() != expected_enum_items)
1769 complaint = BAD_ENUM;
1770 else for (size_t i = first_non_attr; i < ncomps; ++i) {
1771 CompField *cf = sequence_type->get_comp_byIndex(i);
1772 Type *cft = cf->get_type();
1773 if (cft->xerattrib && cft->xerattrib->attribute_) continue;
1774 // Found a non-attribute component. Its name must match an enumval
1775 const Identifier& field_name = cf->get_name();
1776 // don't use get_eis_index_byName(); fatal error if not found :(
1777 const EnumItem *ei = the_enum->get_ei_byIndex(enum_index);
1778 const Identifier& enum_name = ei->get_name();
1779 if (field_name != enum_name) {// X.693amd1 35.2.2.1 and 35.2.2.2
1780 complaint = BAD_ENUM;
1781 break;
1782 }
1783 Value *v = ei->get_value();
1784 const int_val_t *ival = v->get_val_Int();
1785 const Int enumval = ival->get_val();
1786 if ((size_t)enumval != enum_index) {
1787 complaint = ENUM_GAP; // 35.2.2.3
1788 break;
1789 }
1790 ++enum_index;
1791 } // next enum component
1792 }
1793 else {
1794 complaint = FIRST_NOT_RECORD_OF;
1795 complain2:;
1796 }
1797 break; }
1798 default:
1799 complaint = NOT_SEQUENCE;
1800 break;
1801 } // switch typetype
1802
1803 if (complaint == ALL_GOOD) use_order_possible = true;
1804 else if (xerattrib->useOrder_) {
1805 switch (complaint) {
1806 case ALL_GOOD: // Not possible; present in the switch so GCC checks
1807 // that all enum values are handled (make sure there's no default).
1808 break;
1809 case NOT_SEQUENCE:
1810 error("USE-ORDER can only be assigned to a SEQUENCE/record type.");
1811 break;
1812 case NOT_ENOUGH_MEMBERS:
1813 case FIRST_NOT_RECORD_OF:
1814 case FIRST_NOT_RECORD_OF_ENUM:
1815 error("The type with USE-ORDER should have a component "
1816 "which is a record-of enumerated");
1817 break;
1818 case FIRST_OPTIONAL:
1819 error("The record-of for USE-ORDER shall not be marked"
1820 " OPTIONAL or DEFAULT"); // X.693amd1 35.2.3
1821 break;
1822 case NOTHING_TO_ORDER:
1823 error("The type with USE-ORDER should have at least one "
1824 "non-attribute component");
1825 break;
1826 case LAST_NOT_RECORD:
1827 error("The OPTIONAL component supporting the USE-NIL "
1828 "encoding instruction should be a SEQUENCE/record");
1829 break;
1830 case BAD_ENUM:
1831 if (!the_enum) FATAL_ERROR("Type::chk_xer_use_order()");
1832 the_enum->error("Enumeration items should match the"
1833 " non-attribute components of the sequence");
1834 break;
1835 case ENUM_GAP:
1836 if (!the_enum) FATAL_ERROR("Type::chk_xer_use_order()");
1837 the_enum->error("Enumeration values must start at 0 and have no gaps");
1838 break;
1839 } //switch
1840 } // if USE-ORDER
1841 }
1842
1843 void Type::chk_xer_use_type()
1844 {
1845 Type * const last = get_type_refd_last();
1846
1847 const char *ns, *prefix;
1848 my_scope->get_scope_mod()->get_controlns(ns, prefix);
1849 if (!prefix) error("Type has USE-TYPE, but the module has no control namespace set");
1850
1851 switch (last->typetype) {
1852 // USE-TYPE applied to anytype ? Just say no.
1853 case T_CHOICE_A: case T_CHOICE_T: { // must be CHOICE; 37.2.1
1854 if (xerattrib->untagged_ || xerattrib->useUnion_) { // 37.2.5
1855 error("A type with USE-TYPE encoding instruction shall not also have"
1856 " any of the final encoding instructions UNTAGGED or USE-UNION");
1857 }
1858 // Now check the alternatives.
1859 // iterating backwards calls get_nof_comps only once
1860 for (int i = last->get_nof_comps() - 1; i >= 0; --i) {
1861 CompField *cf = last->get_comp_byIndex(i);
1862 Type *cft = cf->get_type();
1863 if (cft->xerattrib && cft->xerattrib->untagged_) {
1864 cf->error("Alternative of a union with USE-TYPE should not have UNTAGGED"); // 37.2.2
1865 break;
1866 }
1867 switch (cft->typetype) {
1868 case T_CHOICE_A: case T_CHOICE_T:
1869 if (cft->xerattrib && cft->xerattrib->useType_) {
1870 cf->error("Alternative of a CHOICE type with USE-TYPE shall not be"
1871 " a CHOICE type with a USE-TYPE encoding instruction"); // 37.2.3
1872 }
1873 break;
1874 default:
1875 break;
1876 }
1877 }
1878 break; }
1879 default:
1880 error("USE-TYPE can only applied to a CHOICE/union type");
1881 break;
1882 } // switch
1883 }
1884
1885 void Type::chk_xer_use_union()
1886 {
1887 Type * const last = get_type_refd_last();
1888 switch (last->typetype) {
1889 case T_CHOICE_A: case T_CHOICE_T: {
1890 // Now check the alternatives.
1891 // iterating backwards calls get_nof_comps only once
1892 for (int i = last->get_nof_comps() - 1; i >= 0; --i) {
1893 CompField *cf = last->get_comp_byIndex(i);
1894 Type *cft = cf->get_type();
1895 if (cft->is_charenc() && !(cft->xerattrib && cft->xerattrib->useType_) &&
1896 !(cft->xerattrib && cft->xerattrib->useQName_)) { // currently not supported
1897 if (cft->xerattrib && cft->xerattrib->useUnion_) // it must be a union
1898 cf->error("Alternative of a CHOICE/union with USE-UNION"
1899 " can not itself be a CHOICE/union with USE-UNION");
1900 }
1901 else cf->error("Alternative of a CHOICE/union with USE-UNION must be character-encodable");
1902 }
1903 break; }
1904 default:
1905 error("USE-UNION can only applied to a CHOICE/union type"); // 38.2.1
1906 break;
1907 }
1908
1909 }
1910
1911 static const char *xml98 = "http://www.w3.org/XML/1998/namespace";
1912
1913 void Type::chk_xer() { // XERSTUFF semantic check
1914 // the type (and everything it contains) is fully checked now
1915
1916 if (xer_checked) return;
1917 xer_checked = true;
1918
1919 Type *last = get_type_refd_last();
1920
1921 // Check XER attributes if the type belongs to a type definition,
1922 // a field of a record/set/union, or is the embedded type of a record-of.
1923 if (ownertype==OT_TYPE_DEF
1924 ||ownertype==OT_COMP_FIELD
1925 ||ownertype==OT_RECORD_OF) {
1926 XerAttributes *newx = 0;
1927 if (is_ref()) {
1928 // Merge XER attributes from the referenced type.
1929 // This implements X.693amd1 clause 15.1.2
1930 newx = new XerAttributes;
1931 Type *t1 = get_type_refd();
1932 // chk_refd() (called by chk() for T_REFD) does not check
1933 // the referenced type; do it now. This makes it fully recursive.
1934 t1->chk();
1935
1936 size_t old_text = 0;
1937 if (t1->xerattrib && !t1->xerattrib->empty()) {
1938 old_text = t1->xerattrib->num_text_;
1939 *newx |= *t1->xerattrib; // get the ancestor's attributes, except...
1940 newx->attribute_ = false; // attribute is not inherited
1941 newx->element_ = false; // element is not inherited
1942
1943 if (ownertype == OT_TYPE_DEF
1944 ||ownertype == OT_COMP_FIELD) {
1945 // Name,Namespace is not inherited, X.693 amd1, 13.6
1946 // are you sure about the namespace?
1947 XerAttributes::FreeNameChange(newx->name_);
1948 //XerAttributes::FreeNamespace(newx->namespace_); // HR39678 bugfix beta
1949 }
1950 }
1951 // Now merge/override with our own attributes
1952 if (xerattrib && !xerattrib->empty()) {
1953 if (xerattrib->num_text_ > 0 && old_text > 0
1954 && (last->typetype == T_ENUM_T || last->typetype == T_ENUM_A)) {
1955 // Adding more TEXT attributes does not work right.
1956 error("Adding more TEXT attributes is not supported "
1957 "by the implementation.");
1958 }
1959 *newx |= *xerattrib;
1960 }
1961
1962 if (newx->empty()) delete newx;
1963 else { // something interesting was found
1964 delete xerattrib;
1965 xerattrib = newx;
1966
1967 if (xerattrib->attribute_
1968 && t1->xerattrib && t1->xerattrib->attribute_
1969 && t1->ownertype == OT_TYPE_DEF
1970 && !(xerattrib->form_ & XerAttributes::LOCALLY_SET) ) {
1971 // The referenced type came from a global XSD attribute.
1972 // This type's form will be qualified, unless it has an explicit
1973 // "form as ..." (which overrides everything).
1974 xerattrib->form_ |= XerAttributes::QUALIFIED;
1975 }
1976
1977 if (t1->xerattrib && t1->xerattrib->element_
1978 // The referenced type came from a global XSD element.
1979 && !(xerattrib->form_ & XerAttributes::LOCALLY_SET))
1980 { // and it doesn't have an explicit "form as ..."
1981 xerattrib->form_ |= XerAttributes::QUALIFIED;
1982 }
1983 }
1984 } // if is_ref
1985 } // if ownertype
1986
1987 if (!xerattrib) return;
1988
1989 //const char *fn = get_fullname().c_str();
1990 //printf("chk_xer(%s)\n", fn);
1991
1992 // In general, "last" should be used instead of "this" in the checks below
1993 // when accessing information about the type's characteristics, except
1994 // this->xerattrib MUST be used (and not last->xerattrib!).
1995
1996 switch (ownertype) {
1997 case OT_COMP_FIELD:
1998 case OT_TYPE_DEF:
1999 case OT_RECORD_OF:
2000 // acceptable
2001 break;
2002
2003 default:
2004 FATAL_ERROR("Unexpected ownertype %d", ownertype);
2005 }
2006
2007 int num_attributes = 0;
2008 switch (last->typetype) {
2009 case T_SEQ_A: case T_SEQ_T:
2010 case T_SET_A: case T_SET_T: {
2011 // Count attributes (ANY-ATTRIBUTES counts as one)
2012 const size_t num_cf = last->get_nof_comps();
2013 int specials = xerattrib->embedValues_ + xerattrib->useOrder_;
2014 int num_any_attributes = 0;
2015 for (int x = num_cf - 1; x >= specials; --x) {
2016 CompField *cf = last->get_comp_byIndex(x);
2017 Type *cft = cf->get_type() /* NOT get_type_refd_last() */;
2018 if (cft->xerattrib
2019 && (cft->xerattrib->attribute_ || has_aa(cft->xerattrib)))
2020 {
2021 if (cft->xerattrib->attribute_) ++num_attributes;
2022 else if (++num_any_attributes > 1) {
2023 cf->error("There can be at most one field with ANY-ATTRIBUTES");
2024 }
2025 }
2026 else if (num_attributes + num_any_attributes > 0) {
2027 // Found a non-attribute when there was an attribute after it
2028 cf->error("Non-attribute field before attribute not supported");
2029 }
2030 } // next
2031
2032 num_attributes += num_any_attributes;
2033 break; }
2034
2035 default:
2036 break;
2037 }
2038
2039 /* * * Check restrictions set out in X.693 amd1, clauses 18-39 * * */
2040
2041 if (has_aa(xerattrib)) {
2042 chk_xer_any_attributes();
2043 } // if ANY-ATTRIBUTES
2044
2045 if (has_ae(xerattrib)) {
2046 chk_xer_any_element();
2047 } // if ANY-ELEMENT
2048
2049 if (xerattrib->attribute_) {
2050 chk_xer_attribute();
2051 // It's an attribute, check for the attributeFormQualified bit
2052 // and transform it into unconditionally qualified.
2053 if (!(xerattrib->form_ & XerAttributes::LOCALLY_SET)
2054 && (xerattrib->form_ & XerAttributes::ATTRIBUTE_DEFAULT_QUALIFIED)) {
2055 xerattrib->form_ |= XerAttributes::QUALIFIED;
2056 }
2057 }
2058 else {
2059 // Element, check the elementFormQualified bit.
2060 if (!(xerattrib->form_ & XerAttributes::LOCALLY_SET)
2061 && (xerattrib->form_ & XerAttributes::ELEMENT_DEFAULT_QUALIFIED)) {
2062 xerattrib->form_ |= XerAttributes::QUALIFIED;
2063 }
2064 } // if ATTRIBUTE
2065
2066 if (xerattrib->base64_) {
2067 switch (last->typetype) {
2068 case T_OSTR: // OCTET STRING
2069 case T_HSTR: // hexstring
2070 case T_OPENTYPE:
2071 case T_BMPSTRING:
2072 case T_GENERALSTRING:
2073 case T_GRAPHICSTRING:
2074 case T_IA5STRING:
2075 // ISO646String ?
2076 case T_NUMERICSTRING:
2077 case T_PRINTABLESTRING:
2078 case T_TELETEXSTRING:
2079 // T61
2080 case T_UNIVERSALSTRING:
2081 case T_UTF8STRING:
2082 case T_VIDEOTEXSTRING:
2083 case T_VISIBLESTRING:
2084 // TTCN types
2085 case T_CSTR:
2086 case T_USTR:
2087 break; // acceptable
2088 default:
2089 error("BASE64 can only be applied to OCTET STRING, open type or "
2090 "restricted character string type");
2091 break;
2092 } // switch
2093
2094 if (has_ae(xerattrib) || xerattrib->whitespace_ != XerAttributes::PRESERVE) {
2095 error("A type with BASE64 shall not have any of the final "
2096 "encoding instructions ANY-ELEMENT or WHITESPACE");
2097 }
2098 } // if BASE64
2099
2100 if (xerattrib->decimal_) {
2101 if (last->typetype != T_REAL) {
2102 error("DECIMAL shall only be assigned to a real type");
2103 }
2104 } // if DECIMAL
2105
2106 if (xerattrib->defaultForEmpty_ != 0) {
2107 chk_xer_dfe();
2108 } // if defaultForEmpty
2109
2110 chk_xer_embed_values(num_attributes); // always
2111
2112 if (xerattrib->list_) {
2113 switch (last->typetype) {
2114 case T_SEQOF: case T_SETOF:
2115 break; // acceptable
2116 default:
2117 error("LIST can only be assigned to SEQUENCE-OF or SET-OF");// 27.2.1
2118 break;
2119 }
2120
2121 if (has_aa(xerattrib)) {
2122 error("A type with LIST shall not have ANY-ATTRIBUTES");// 27.2.3
2123 }
2124 } // if LIST
2125
2126 // NAME is handled later when generate_code_xerdescriptor call change_name
2127
2128 if ((unsigned long)xerattrib->namespace_.keyword
2129 > (unsigned long)NamespaceSpecification::LOWERCASED) {
2130 // Now both are proper non-NULL strings
2131 if (*xerattrib->namespace_.prefix != 0) { // there is a prefix, check it
2132 char first[4] = {0,0,0,0};
2133 strncpy(first, xerattrib->namespace_.prefix, 3);
2134 first[0] = toupper(first[0]);
2135 first[1] = toupper(first[1]);
2136 first[2] = toupper(first[2]);
2137 if (!memcmp(first, "XML", 3) // It _is_ "xml"
2138 // but the W3C XML namespace gets an exemption
2139 && strcmp(xerattrib->namespace_.uri, xml98)) error(
2140 "Prefix shall not commence with characters that"
2141 " when uppercased are 'XML'");
2142 // X.693 (11/2008), clause 29.1.7
2143 }
2144
2145 Common::Module::add_namespace(
2146 xerattrib->namespace_.uri, xerattrib->namespace_.prefix);
2147 }
2148 else xerattrib->namespace_.uri = NULL; // really no namespace
2149
2150 // PI-OR-COMMENT not supported
2151
2152 if (xerattrib->num_text_ > 0) {
2153 chk_xer_text();
2154 }
2155
2156 if (xerattrib->untagged_) {
2157 chk_xer_untagged();
2158 } // if UNTAGGED
2159
2160 chk_xer_use_nil(); // always
2161
2162 if (xerattrib->useNumber_) {
2163 switch (last->typetype) {
2164 case T_ENUM_A:
2165 error("No XER yet for ASN.1 enumerations");
2166 // no break
2167 case T_ENUM_T:
2168 break; // acceptable
2169 default:
2170 warning("USE-NUMBER ignored unless assigned to an enumerated type");
2171 xerattrib->useNumber_ = false;
2172 break;
2173 }
2174
2175 if (xerattrib->num_text_) {
2176 error("A type with USE-NUMBER shall not have TEXT");
2177 }
2178 } // if USE-NUMBER
2179
2180 chk_xer_use_order(num_attributes); //always
2181
2182 if (xerattrib->useQName_) {
2183 switch (last->typetype) {
2184 case T_SEQ_A: case T_SEQ_T: {
2185 if (last->get_nof_comps() != 2) goto complain;
2186 const CompField * cf = last->get_comp_byIndex(0);
2187 const Type * cft = cf->get_type()->get_type_refd_last();
2188 if (cft->typetype != T_USTR && cft->typetype != T_UTF8STRING)
2189 cft->error ("Both components must be UTF8String or universal charstring");
2190 if (!cf->get_is_optional()) cft->error(
2191 "The first component of a type with USE-QNAME must be optional");
2192
2193 cf = last->get_comp_byIndex(1);
2194 cft = cf->get_type()->get_type_refd_last();
2195 if (cft->typetype != T_USTR && cft->typetype != T_UTF8STRING)
2196 cft->error ("Both components must be UTF8String or universal charstring");
2197 if (cf->get_is_optional()) cft->error(
2198 "The second component of a type with USE-QNAME must NOT be optional");
2199 break; }
2200
2201 default:
2202 complain:
2203 error("A type with USE-QNAME must be a sequence type with exactly two components.");
2204 break;
2205 }
2206 if (xerattrib->useNil_) error("A type with USE-QNAME shall not have USE-NIL"); // 36.2.4
2207 }
2208
2209 if (xerattrib->useType_) {
2210 chk_xer_use_type();
2211 } // if USE-TYPE
2212
2213 if (xerattrib->useUnion_) {
2214 chk_xer_use_union();
2215 }
2216
2217 if (is_secho()) {
2218 CompFieldMap& cfm = *u.secho.cfm;
2219 const size_t ncomps = cfm.get_nof_comps();
2220 CompField *the_one = 0; // ...and only untagged character-encodable field
2221 map<int, CompField> empties; // potentially empties
2222
2223 for (size_t i=0; i < ncomps; ++i) {
2224 CompField * cf = cfm.get_comp_byIndex(i);
2225 Type *cft = cf->get_type();
2226
2227 if (cft->xerattrib && cft->xerattrib->untagged_) {
2228 /* This check could be in chk_xer_untagged(), but then we couldn't
2229 * access the CompField in the parent type. */
2230 if (cft->is_charenc() == Yes) {
2231 if (the_one) { // already has one
2232 cf->error("More than one UNTAGGED character-encodable field");
2233 // break? to report only once
2234 }
2235 else {
2236 the_one = cf; // this is used for further checks below
2237 u.secho.has_single_charenc = true; // used while generating code
2238 switch (typetype) {
2239 case T_SEQ_A: case T_SEQ_T:
2240 if (xerattrib->untagged_) {
2241 error("Enclosing type of an UNTAGGED character-encodable type "
2242 "must not be UNTAGGED");
2243 }
2244 break; // the small switch
2245 default:
2246 error("Enclosing type of an UNTAGGED character-encodable type "
2247 "is not record.");
2248 break;
2249 } // switch
2250 } // if (the_one)
2251 }
2252 else { // untagged, not charenc
2253 switch (cft->get_type_refd_last()->typetype) {
2254 case T_SEQ_A: case T_SEQ_T:
2255 case T_SET_A: case T_SET_T:
2256 case T_CHOICE_A: case T_CHOICE_T:
2257 case T_SEQOF:
2258 case T_SETOF:
2259 //case T_OSTR: with a contained type
2260 //case T_BSTR_A: with a contained type
2261 //case T_OPENTYPE:
2262 break; //ok
2263
2264 default: // 32.2.3 "If the type is not character-encodable..."
2265 cft->error("UNTAGGED type should be sequence, set, choice, sequence-of, or set-of type");
2266 break;
2267 }
2268 } // if(is_charenc)
2269 } // if untagged
2270
2271 if (cft->has_empty_xml()) {
2272 empties.add(i, cf);
2273 }
2274 } // next component
2275
2276 if (the_one) {
2277 if (the_one->get_is_optional() || the_one->has_default()) {
2278 the_one->error("UNTAGGED field should not be marked OPTIONAL or DEFAULT");
2279 }
2280 // Check the other compfields. They must all be (ANY)?ATTRIBUTE
2281 for (size_t i=0; i < ncomps; ++i) {
2282 CompField *cf = cfm.get_comp_byIndex(i);
2283 if (cf == the_one) continue;
2284
2285 Type *cft = cf->get_type();
2286 if ( !cft->xerattrib // cannot be attribute, error
2287 || (!cft->xerattrib->attribute_ && !has_aa(cft->xerattrib))) {
2288 the_one->note("Due to this UNTAGGED component");
2289 cf->error("All the other components should be ATTRIBUTE or ANY-ATTRIBUTE");
2290 // X.693 (2008) 32.2.2
2291 break;
2292 }
2293 } // next i
2294 } // if the_one
2295
2296 if (empties.size() > 1
2297 && (typetype==T_CHOICE_A || typetype==T_CHOICE_T)) {
2298 warning("More than one field can have empty XML. Decoding of empty"
2299 " XML is ambiguous, %s chosen arbitrarily.",
2300 empties.get_nth_elem(empties.size()-1)->get_name().get_name().c_str());
2301 }
2302 empties.clear();
2303 } // if secho
2304
2305 }
2306
2307
2308 void Type::chk_Int_A()
2309 {
2310 if(checked) return;
2311 checked=true;
2312 if(!u.namednums.block) return;
2313 parse_block_Int();
2314 if(typetype==T_ERROR) return;
2315 /* check named numbers */
2316 if(!u.namednums.nvs) return;
2317 map<Int, NamedValue> value_map;
2318 Error_Context cntxt(this, "In named numbers");
2319 u.namednums.nvs->chk_dupl_id();
2320 for (size_t i = 0; i < u.namednums.nvs->get_nof_nvs(); i++) {
2321 NamedValue *nv = u.namednums.nvs->get_nv_byIndex(i);
2322 Value *value = nv->get_value();
2323 Value *v = value->get_value_refd_last();
2324 switch (v->get_valuetype()) {
2325 case Value::V_INT: {
2326 const int_val_t *int_val_int = v->get_val_Int();
2327 if (*int_val_int > INT_MAX) {
2328 value->error("Integer value `%s' is too big to be used as a named "
2329 "number", (int_val_int->t_str()).c_str());
2330 } else {
2331 Int int_val = int_val_int->get_val();
2332 if (value_map.has_key(int_val)) {
2333 value->error("Duplicate number %s for name `%s'",
2334 Int2string(int_val).c_str(),
2335 nv->get_name().get_dispname().c_str());
2336 NamedValue *nv2 = value_map[int_val];
2337 nv2->note("Number %s is already assigned to name `%s'",
2338 Int2string(int_val).c_str(),
2339 nv2->get_name().get_dispname().c_str());
2340 } else {
2341 value_map.add(int_val, nv);
2342 }
2343 }
2344 break; }
2345 case Value::V_ERROR:
2346 break;
2347 default:
2348 nv->error("INTEGER value was expected for named number `%s'",
2349 nv->get_name().get_dispname().c_str());
2350 break;
2351 }
2352 }
2353 value_map.clear();
2354 }
2355
2356 void Type::chk_Enum_A()
2357 {
2358 if(checked) return;
2359 if(!u.enums.block) return;
2360 parse_block_Enum();
2361 if(typetype==T_ERROR) return;
2362 /* checking enumerations */
2363 map<Int, EnumItem> value_map;
2364 /* checking values before the ellipsis */
2365 for (size_t i = 0; i < u.enums.eis1->get_nof_eis(); i++)
2366 chk_Enum_item(u.enums.eis1->get_ei_byIndex(i), false, value_map);
2367 /* assigning default values */
2368 Int& first_unused = u.enums.first_unused;
2369 for (first_unused = 0; value_map.has_key(first_unused); first_unused++) ;
2370 for (size_t i = 0; i < u.enums.eis1->get_nof_eis(); i++) {
2371 EnumItem *ei = u.enums.eis1->get_ei_byIndex(i);
2372 if (!ei->get_value()) {
2373 ei->set_value(new Value(Value::V_INT, first_unused));
2374 value_map.add(first_unused, ei);
2375 while (value_map.has_key(++first_unused)) ;
2376 }
2377 }
2378 /* checking values after the ellipsis */
2379 if(u.enums.eis2) {
2380 for(size_t i=0; i < u.enums.eis2->get_nof_eis(); i++)
2381 chk_Enum_item(u.enums.eis2->get_ei_byIndex(i), true, value_map);
2382 }
2383 /* determining the first two unused non-negative integer values
2384 * for code generation */
2385 for (first_unused = 0; value_map.has_key(first_unused); first_unused++) ;
2386 Int& second_unused = u.enums.second_unused;
2387 for (second_unused = first_unused + 1; value_map.has_key(second_unused);
2388 second_unused++) ;
2389 value_map.clear();
2390 u.enums.eis1->release_eis();
2391 delete u.enums.eis1;
2392 u.enums.eis1 = 0;
2393 if(u.enums.eis2) {
2394 u.enums.eis2->release_eis();
2395 delete u.enums.eis2;
2396 u.enums.eis2 = 0;
2397 }
2398 }
2399
2400 void Type::chk_Enum_item(EnumItem *ei, bool after_ellipsis,
2401 map<Int, EnumItem>& value_map)
2402 {
2403 const Identifier& name = ei->get_name();
2404 const char *dispname_str = name.get_dispname().c_str();
2405 if (u.enums.eis->has_ei_withName(name)) {
2406 ei->error("Duplicate ENUMERATED identifier: `%s'", dispname_str);
2407 u.enums.eis->get_ei_byName(name)->note("Previous definition of `%s' "
2408 "is here", dispname_str);
2409 } else if (!name.get_has_valid(Identifier::ID_TTCN)) {
2410 ei->warning("The identifier `%s' is not reachable from TTCN-3",
2411 dispname_str);
2412 }
2413 u.enums.eis->add_ei(ei);
2414 Int& first_unused=u.enums.first_unused;
2415 Value *value = ei->get_value();
2416 if (value) {
2417 Value *v;
2418 {
2419 Error_Context cntxt(ei, "In enumeration `%s'", dispname_str);
2420 v = value->get_value_refd_last();
2421 }
2422 switch (v->get_valuetype()) {
2423 case Value::V_INT:
2424 break;
2425 case Value::V_ERROR:
2426 return;
2427 default:
2428 value->error("INTEGER value was expected for enumeration `%s'",
2429 dispname_str);
2430 return;
2431 }
2432 Int enum_value = v->get_val_Int()->get_val();
2433 if (static_cast<Int>(static_cast<int>(enum_value)) != enum_value) {
2434 value->error("The numeric value of enumeration `%s' (%s) is too "
2435 "large for being represented in memory", dispname_str,
2436 Int2string(enum_value).c_str());
2437 }
2438 if (after_ellipsis) {
2439 if (enum_value >= first_unused) {
2440 value_map.add(enum_value, ei);
2441 for (first_unused = enum_value + 1; value_map.has_key(first_unused);
2442 first_unused++) ;
2443 } else {
2444 value->error("ENUMERATED values shall be monotonically growing after "
2445 "the ellipsis: the value of `%s' must be at least %s instead of %s",
2446 dispname_str, Int2string(first_unused).c_str(),
2447 Int2string(enum_value).c_str());
2448 }
2449 } else {
2450 if (value_map.has_key(enum_value)) {
2451 value->error("Duplicate numeric value %s for enumeration `%s'",
2452 Int2string(enum_value).c_str(), dispname_str);
2453 EnumItem *ei2 = value_map[enum_value];
2454 ei2->note("Value %s is already assigned to `%s'",
2455 Int2string(enum_value).c_str(),
2456 ei2->get_name().get_dispname().c_str());
2457 } else value_map.add(enum_value, ei);
2458 }
2459 } else { // the item has no value
2460 if (after_ellipsis) {
2461 ei->set_value(new Value(Value::V_INT, first_unused));
2462 value_map.add(first_unused, ei);
2463 while (value_map.has_key(++first_unused)) ;
2464 }
2465 }
2466 }
2467
2468 void Type::chk_Enum_T()
2469 {
2470 if(checked) return;
2471 map<Int, EnumItem> value_map;
2472 map<string, EnumItem> name_map;
2473 bool error_flag = false;
2474 /* checking the uniqueness of identifiers and values */
2475 size_t nof_eis = u.enums.eis->get_nof_eis();
2476 for(size_t i = 0; i < nof_eis; i++) {
2477 EnumItem *ei = u.enums.eis->get_ei_byIndex(i);
2478 const Identifier& id = ei->get_name();
2479 const string& name = id.get_name();
2480 if (name_map.has_key(name)) {
2481 const char *dispname_str = id.get_dispname().c_str();
2482 ei->error("Duplicate enumeration identifier `%s'", dispname_str);
2483 name_map[name]->note("Previous definition of `%s' is here",
2484 dispname_str);
2485 error_flag = true;
2486 } else {
2487 name_map.add(name, ei);
2488 }
2489 Value *value = ei->get_value();
2490 if (value) {
2491 /* Handle the error node created by the parser. */
2492 if (value->get_valuetype() == Value::V_ERROR) {
2493 value->error("INTEGER value was expected for enumeration `%s'",
2494 id.get_dispname().c_str());
2495 error_flag = true;
2496 } else {
2497 const int_val_t *enum_value_int = value->get_val_Int();
2498 // It used to be the same check.
2499 if (*enum_value_int > INT_MAX ||
2500 static_cast<Int>(static_cast<int>(enum_value_int->get_val()))
2501 != enum_value_int->get_val()) {
2502 value->error("The numeric value of enumeration `%s' (%s) is "
2503 "too large for being represented in memory",
2504 id.get_dispname().c_str(), (enum_value_int->t_str()).c_str());
2505 error_flag = true;
2506 } else {
2507 Int enum_value = enum_value_int->get_val();
2508 if (value_map.has_key(enum_value)) {
2509 const char *dispname_str = id.get_dispname().c_str();
2510 value->error("Duplicate numeric value %s for enumeration `%s'",
2511 Int2string(enum_value).c_str(), dispname_str);
2512 EnumItem *ei2 = value_map[enum_value];
2513 ei2->note("Value %s is already assigned to `%s'",
2514 Int2string(enum_value).c_str(),
2515 ei2->get_name().get_dispname().c_str());
2516 error_flag = true;
2517 } else {
2518 value_map.add(enum_value, ei);
2519 }
2520 }
2521 }
2522 }
2523 }
2524 if (!error_flag) {
2525 /* assigning default values */
2526 Int& first_unused=u.enums.first_unused;
2527 for(first_unused=0; value_map.has_key(first_unused); first_unused++) ;
2528 for(size_t i = 0; i < nof_eis; i++) {
2529 EnumItem *ei = u.enums.eis->get_ei_byIndex(i);
2530 if(!ei->get_value()) {
2531 ei->set_value(new Value(Value::V_INT, first_unused));
2532 value_map.add(first_unused, ei);
2533 while (value_map.has_key(++first_unused)) ;
2534 }
2535 }
2536 Int& second_unused = u.enums.second_unused;
2537 for (second_unused = first_unused + 1; value_map.has_key(second_unused);
2538 second_unused++) ;
2539 }
2540 value_map.clear();
2541 name_map.clear();
2542 }
2543
2544 void Type::chk_BStr_A()
2545 {
2546 if(!u.namednums.block) return;
2547 parse_block_BStr();
2548 if(typetype==T_ERROR) return;
2549 if(u.namednums.nvs) {
2550 /* check named bits */
2551 map<Int, NamedValue> value_map;
2552 {
2553 Error_Context cntxt(this, "In named bits");
2554 u.namednums.nvs->chk_dupl_id();
2555 }
2556 for(size_t i = 0; i < u.namednums.nvs->get_nof_nvs(); i++) {
2557 NamedValue *nv = u.namednums.nvs->get_nv_byIndex(i);
2558 const char *dispname_str = nv->get_name().get_dispname().c_str();
2559 Value *value = nv->get_value();
2560 Value *v;
2561 {
2562 Error_Context cntxt(this, "In named bit `%s'", dispname_str);
2563 v = value->get_value_refd_last();
2564 }
2565 switch (v->get_valuetype()) {
2566 case Value::V_INT:
2567 break;
2568 case Value::V_ERROR:
2569 continue;
2570 default:
2571 v->error("INTEGER value was expected for named bit `%s'",
2572 dispname_str);
2573 continue;
2574 }
2575 const int_val_t *int_val_int = v->get_val_Int();
2576 if (*int_val_int > INT_MAX) {
2577 value->error("An INTEGER value less than `%d' was expected for "
2578 "named bit `%s' instead of %s", INT_MAX, dispname_str,
2579 (int_val_int->t_str()).c_str());
2580 continue;
2581 }
2582 Int int_val = int_val_int->get_val();
2583 if(int_val < 0) {
2584 value->error("A non-negative INTEGER value was expected for named "
2585 "bit `%s' instead of %s", dispname_str,
2586 Int2string(int_val).c_str());
2587 continue;
2588 }
2589 if (value_map.has_key(int_val)) {
2590 value->error("Duplicate value %s for named bit `%s'",
2591 Int2string(int_val).c_str(), dispname_str);
2592 NamedValue *nv2 = value_map[int_val];
2593 nv2->note("Bit %s is already assigned to name `%s'",
2594 Int2string(int_val).c_str(),
2595 nv2->get_name().get_dispname().c_str());
2596 } else value_map.add(int_val, nv);
2597 }
2598 value_map.clear();
2599 }
2600 }
2601
2602 void Type::chk_SeCho_T()
2603 {
2604 u.secho.cfm->set_my_type(this);
2605 checked = true;
2606 u.secho.cfm->chk();
2607 u.secho.component_internal = false;
2608 size_t nof_comps = u.secho.cfm->get_nof_comps();
2609 for (size_t i=0; i<nof_comps; i++) {
2610 Type* cft = u.secho.cfm->get_comp_byIndex(i)->get_type();
2611 if (cft && cft->is_component_internal()) {
2612 u.secho.component_internal = true;
2613 break;
2614 }
2615 }
2616 }
2617
2618 void Type::chk_Choice_A()
2619 {
2620 if(u.secho.block) parse_block_Choice();
2621 if(typetype==T_ERROR) return;
2622 checked=true;
2623 if(u.secho.ctss->needs_auto_tags())
2624 u.secho.ctss->add_auto_tags();
2625 u.secho.ctss->chk();
2626 if (u.secho.ctss->get_nof_comps() <= 0)
2627 FATAL_ERROR("CHOICE type must have at least one alternative");
2628 u.secho.ctss->chk_tags();
2629 }
2630
2631 void Type::chk_Se_A()
2632 {
2633 if(u.secho.block) parse_block_Se();
2634 if(typetype==T_ERROR) return;
2635 checked=true;
2636 tr_compsof();
2637 u.secho.ctss->chk();
2638 u.secho.ctss->chk_tags();
2639 }
2640
2641 void Type::chk_SeOf()
2642 {
2643 u.seof.ofType->set_genname(get_genname_own(), string('0'));
2644 u.seof.ofType->set_parent_type(this);
2645 checked=true;
2646 const char *type_name;
2647 bool asn1 = is_asn1();
2648 switch (typetype) {
2649 case T_SEQOF:
2650 type_name = asn1 ? "SEQUENCE OF" : "record of";
2651 break;
2652 case T_SETOF:
2653 type_name = asn1 ? "SET OF" : "set of";
2654 break;
2655 default:
2656 type_name = "<unknown>";
2657 break;
2658 }
2659 Error_Context cntxt(this, "In embedded type of %s", type_name);
2660 u.seof.ofType->chk();
2661 if (!asn1) u.seof.ofType->chk_embedded(true, "embedded into another type");
2662 u.seof.component_internal = u.seof.ofType->is_component_internal();
2663 }
2664
2665 void Type::chk_refd()
2666 {
2667 checked=true;
2668 ReferenceChain refch(this, "While checking referenced type");
2669 Type* t_last = get_type_refd_last(&refch);
2670 u.ref.component_internal = t_last->is_component_internal();
2671 }
2672
2673 void Type::chk_seltype()
2674 {
2675 checked=true;
2676 u.seltype.type->set_genname(get_genname_own(), string('0'));
2677 ReferenceChain refch(this, "In selection type");
2678 get_type_refd_last(&refch);
2679 if(typetype==T_ERROR) return;
2680 u.seltype.type->chk();
2681 }
2682
2683 void Type::chk_Array()
2684 {
2685 u.array.element_type->set_genname(get_genname_own(), string('0'));
2686 u.array.element_type->set_parent_type(this);
2687 checked = true;
2688 {
2689 Error_Context cntxt(this, "In element type of array");
2690 u.array.element_type->chk();
2691 u.array.element_type->chk_embedded(true, "embedded into an array type");
2692 }
2693 u.array.dimension->chk();
2694 u.array.component_internal = u.array.element_type->is_component_internal();
2695 }
2696
2697 void Type::chk_Signature()
2698 {
2699 checked = true;
2700 u.signature.component_internal = false;
2701 if (u.signature.parameters) {
2702 u.signature.parameters->chk(this);
2703 size_t nof_params = u.signature.parameters->get_nof_params();
2704 for (size_t i=0; i<nof_params; i++) {
2705 Type* spt = u.signature.parameters->get_param_byIndex(i)->get_type();
2706 if (spt && spt->is_component_internal()) {
2707 u.signature.component_internal = true;
2708 break;
2709 }
2710 }
2711 }
2712 if (u.signature.return_type) {
2713 Error_Context cntxt(u.signature.return_type, "In return type");
2714 u.signature.return_type->set_genname(get_genname_own(), string('0'));
2715 u.signature.return_type->set_parent_type(this);
2716 u.signature.return_type->chk();
2717 u.signature.return_type->chk_embedded(false,
2718 "the return type of a signature");
2719 if (!u.signature.component_internal &&
2720 u.signature.return_type->is_component_internal())
2721 u.signature.component_internal = true;
2722 }
2723 if (u.signature.exceptions) {
2724 u.signature.exceptions->chk(this);
2725 if (!u.signature.component_internal) {
2726 size_t nof_types = u.signature.exceptions->get_nof_types();
2727 for (size_t i=0; i<nof_types; i++) {
2728 if (u.signature.exceptions->get_type_byIndex(i)->
2729 is_component_internal()) {
2730 u.signature.component_internal = true;
2731 break;
2732 }
2733 }
2734 }
2735 }
2736 }
2737
2738 void Type::chk_Fat()
2739 {
2740 if(checked) return;
2741 checked = true;
2742 Scope *parlist_scope = my_scope;
2743 // the runs on clause must be checked before the formal parameter list
2744 // in order to determine the right scope
2745 if (u.fatref.runs_on.ref) {
2746 if (typetype == T_FUNCTION) u.fatref.is_startable = true;
2747 Error_Context cntxt2(u.fatref.runs_on.ref, "In `runs on' clause");
2748 u.fatref.runs_on.type = u.fatref.runs_on.ref->chk_comptype_ref();
2749 if(u.fatref.runs_on.type) {
2750 Ttcn::Module *my_module =
2751 dynamic_cast<Ttcn::Module*>(my_scope->get_scope_mod());
2752 if (!my_module) FATAL_ERROR("Type::chk_Fat()");
2753 parlist_scope = my_module->get_runs_on_scope(u.fatref.runs_on.type);
2754 }
2755 }
2756 u.fatref.fp_list->set_my_scope(parlist_scope);
2757 switch (typetype) {
2758 case T_FUNCTION:
2759 u.fatref.fp_list->chk(Ttcn::Definition::A_FUNCTION);
2760 u.fatref.fp_list->chk_noLazyParams();
2761 if (u.fatref.is_startable && !u.fatref.fp_list->get_startability())
2762 u.fatref.is_startable = false;
2763 if (u.fatref.return_type) {
2764 Error_Context cntxt2(u.fatref.return_type, "In return type");
2765 u.fatref.return_type->chk();
2766 u.fatref.return_type->chk_as_return_type(!u.fatref.returns_template,
2767 "function type");
2768 if (u.fatref.is_startable && u.fatref.return_type->get_type_refd_last()
2769 ->get_typetype() == T_DEFAULT) u.fatref.is_startable = false;
2770
2771 }
2772 break;
2773 case T_ALTSTEP:
2774 u.fatref.fp_list->chk(Ttcn::Definition::A_ALTSTEP);
2775 u.fatref.fp_list->chk_noLazyParams();
2776 break;
2777 case T_TESTCASE:
2778 u.fatref.fp_list->chk(Ttcn::Definition::A_TESTCASE);
2779 u.fatref.fp_list->chk_noLazyParams();
2780 if (u.fatref.system.ref) {
2781 Error_Context cntxt2(u.fatref.runs_on.ref, "In `system' clause");
2782 u.fatref.system.type = u.fatref.system.ref->chk_comptype_ref();
2783 }
2784 break;
2785 default:
2786 FATAL_ERROR("Type::chk_Fat()");
2787 }
2788 if (!semantic_check_only)
2789 u.fatref.fp_list->set_genname(get_genname_own());
2790 }
2791
2792 void Type::chk_address()
2793 {
2794 Type *t = get_type_refd_last();
2795 switch (t->typetype) {
2796 case T_PORT:
2797 error("Port type `%s' cannot be the address type",
2798 t->get_typename().c_str());
2799 break;
2800 case T_COMPONENT:
2801 error("Component type `%s' cannot be the address type",
2802 t->get_typename().c_str());
2803 break;
2804 case T_SIGNATURE:
2805 error("Signature `%s' cannot be the address type",
2806 t->get_typename().c_str());
2807 break;
2808 case T_DEFAULT:
2809 error("Default type cannot be the address type");
2810 break;
2811 case T_ANYTYPE:
2812 error("TTCN-3 anytype cannot be the address type");
2813 break;
2814 default:
2815 return;
2816 }
2817 clean_up();
2818 }
2819
2820 void Type::chk_embedded(bool default_allowed, const char *error_msg)
2821 {
2822 Type *t=get_type_refd_last();
2823 switch (t->typetype) {
2824 case T_PORT:
2825 error("Port type `%s' cannot be %s", t->get_typename().c_str(),
2826 error_msg);
2827 break;
2828 case T_SIGNATURE:
2829 error("Signature `%s' cannot be %s", t->get_typename().c_str(),
2830 error_msg);
2831 break;
2832 case T_DEFAULT:
2833 if (!default_allowed) error("Default type cannot be %s", error_msg);
2834 break;
2835 default:
2836 break;
2837 }
2838 }
2839
2840 void Type::chk_recursions(ReferenceChain& refch)
2841 {
2842 if (recurs_checked) return;
2843 Type *t = this;
2844 for ( ; ; ) {
2845 if (!refch.add(t->get_fullname())) {
2846 // an error has been found (and reported by refch.add)
2847 recurs_checked = true;
2848 return;
2849 }
2850 if (!t->is_ref()) break;
2851 t = t->get_type_refd();
2852 }
2853 switch (t->typetype) {
2854 case T_SEQ_A:
2855 case T_SEQ_T:
2856 case T_SET_A:
2857 case T_SET_T:
2858 for(size_t i = 0; i < t->get_nof_comps(); i++) {
2859 CompField *cf = t->get_comp_byIndex(i);
2860 if(!cf->get_is_optional()) {
2861 refch.mark_state();
2862 cf->get_type()->chk_recursions(refch);
2863 refch.prev_state();
2864 }
2865 // an optional field can "stop" the recursion
2866 } // for i
2867 break;
2868 case T_CHOICE_A:
2869 case T_CHOICE_T: {
2870 refch.set_error_reporting(false);
2871 refch.mark_error_state();
2872 for (size_t i = 0; i < t->get_nof_comps(); ++i) {
2873 refch.mark_state();
2874 CompField* cf = t->get_comp_byIndex(i);
2875 cf->get_type()->chk_recursions(refch);
2876 refch.prev_state();
2877 }
2878
2879 if (refch.nof_errors() == t->get_nof_comps()) {
2880 refch.report_errors();
2881 }
2882
2883 refch.prev_error_state();
2884 refch.set_error_reporting(true);
2885 break;
2886 }
2887 case T_ANYTYPE:
2888 case T_OPENTYPE:
2889 if(t->get_nof_comps()==1)
2890 t->get_comp_byIndex(0)->get_type()->chk_recursions(refch);
2891 break;
2892 case T_ARRAY:
2893 t->get_ofType()->chk_recursions(refch);
2894 break;
2895 default:
2896 break;
2897 }
2898 recurs_checked = true;
2899 }
2900
2901 void Type::chk_constructor_name(const Identifier& p_id)
2902 {
2903 switch (typetype) {
2904 case T_SEQ_T:
2905 case T_SEQ_A:
2906 case T_SET_T:
2907 case T_SET_A:
2908 case T_CHOICE_T:
2909 case T_CHOICE_A:
2910 case T_OPENTYPE:
2911 // T_ANYTYPE can not have a field of type anytype, no need to check.
2912 if (has_comp_withName(p_id)) {
2913 // HL26011: a field has the same name as the typedef.
2914 // Titan can't generate valid C++ code; better report an error.
2915 get_comp_byName(p_id)->error("Field name clashes with type name");
2916 }
2917 break;
2918 default: // can't have fields
2919 break;
2920 }
2921 }
2922
2923 bool Type::chk_startability()
2924 {
2925 if(typetype != T_FUNCTION) FATAL_ERROR("Type::chk_startable()");
2926 if(!checked) chk_Fat();
2927 if(u.fatref.is_startable) return true;
2928 if (!u.fatref.runs_on.ref) error("Functions of type `%s' cannot be started "
2929 "on a parallel test component because the type does not have `runs on' "
2930 "clause", get_typename().c_str());
2931 u.fatref.fp_list->chk_startability("Functions of type",
2932 get_typename().c_str());
2933 if (u.fatref.return_type && u.fatref.return_type->is_component_internal()) {
2934 map<Type*,void> type_chain;
2935 char* err_str = mprintf("the return type or embedded in the return type "
2936 "of function type `%s' if it is started on a parallel test component",
2937 get_typename().c_str());
2938 u.fatref.return_type->chk_component_internal(type_chain, err_str);
2939 Free(err_str);
2940 }
2941 return false;
2942 }
2943
2944 void Type::chk_as_return_type(bool as_value, const char* what)
2945 {
2946 Type *t = get_type_refd_last();
2947 switch(t->get_typetype()) {
2948 case Type::T_PORT:
2949 error("Port type `%s' cannot be the return type of a %s"
2950 , t->get_fullname().c_str(), what);
2951 break;
2952 case Type::T_SIGNATURE:
2953 if(as_value) error("A value of signature `%s' cannot be the "
2954 "return type of a %s", t->get_fullname().c_str(), what);
2955 break;
2956 default:
2957 break;
2958 }
2959 }
2960
2961 void Type::chk_this_value_ref(Value *value)
2962 {
2963 switch (value->get_valuetype()) {
2964 case Value::V_UNDEF_LOWERID:
2965 switch(typetype) {
2966 case T_INT_A:
2967 if(value->is_asn1()) {
2968 chk_Int_A();
2969 if(u.namednums.nvs
2970 && u.namednums.nvs->has_nv_withName(*value->get_val_id())) {
2971 value->set_valuetype(Value::V_NAMEDINT);
2972 value->set_my_governor(this);
2973 return;
2974 }
2975 }
2976 break;
2977 case T_ENUM_A:
2978 case T_ENUM_T:
2979 if (has_ei_withName(*value->get_val_id())) {
2980 value->set_valuetype(Value::V_ENUM);
2981 value->set_my_governor(this);
2982 return;
2983 }
2984 break;
2985 case T_REFD:
2986 case T_SELTYPE:
2987 case T_REFDSPEC:
2988 case T_OCFT:
2989 get_type_refd()->chk_this_value_ref(value);
2990 return;
2991 default:
2992 break;
2993 } // switch
2994 /* default behavior: interpret as reference */
2995 value->set_valuetype(Value::V_REFD);
2996 break;
2997 default:
2998 break;
2999 }
3000 }
3001
3002 bool Type::chk_this_value(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
3003 namedbool incomplete_allowed, namedbool omit_allowed,
3004 namedbool sub_chk, namedbool implicit_omit, namedbool is_str_elem)
3005 {
3006 bool self_ref = false;
3007 chk();
3008 Value *v_last = value->get_value_refd_last(0, expected_value);
3009 if (v_last->get_valuetype() == Value::V_OMIT) {
3010 if (!omit_allowed) {
3011 value->error("`omit' value is not allowed in this context");
3012 value->set_valuetype(Value::V_ERROR);
3013 }
3014 return false;
3015 }
3016
3017 switch (value->get_valuetype()) {
3018 case Value::V_ERROR:
3019 return false;
3020 case Value::V_REFD:
3021 return chk_this_refd_value(value, lhs, expected_value, 0, is_str_elem);
3022 case Value::V_INVOKE:
3023 chk_this_invoked_value(value, lhs, expected_value);
3024 return false; // assumes no self-ref in invoke
3025 case Value::V_EXPR:
3026 if (lhs) self_ref = value->chk_expr_self_ref(lhs);
3027 // no break
3028 case Value::V_MACRO:
3029 if (value->is_unfoldable(0, expected_value)) {
3030 typetype_t tt = value->get_expr_returntype(expected_value);
3031 if (!is_compatible_tt(tt, value->is_asn1())) {
3032 value->error("Incompatible value: `%s' value was expected",
3033 get_typename().c_str());
3034 value->set_valuetype(Value::V_ERROR);
3035 }
3036 return self_ref;
3037 }
3038 break;
3039 default:
3040 break;
3041 }
3042
3043 switch(typetype) {
3044 case T_ERROR:
3045 break;
3046 case T_NULL:
3047 chk_this_value_Null(value);
3048 break;
3049 case T_BOOL:
3050 chk_this_value_Bool(value);
3051 break;
3052 case T_INT:
3053 chk_this_value_Int(value);
3054 break;
3055 case T_INT_A:
3056 chk_this_value_Int_A(value);
3057 break;
3058 case T_REAL:
3059 chk_this_value_Real(value);
3060 break;
3061 case T_ENUM_A:
3062 case T_ENUM_T:
3063 chk_this_value_Enum(value);
3064 break;
3065 case T_BSTR:
3066 chk_this_value_BStr(value);
3067 break;
3068 case T_BSTR_A:
3069 chk_this_value_BStr_A(value);
3070 break;
3071 case T_HSTR:
3072 chk_this_value_HStr(value);
3073 break;
3074 case T_OSTR:
3075 chk_this_value_OStr(value);
3076 break;
3077 case T_CSTR:
3078 case T_USTR:
3079 case T_UTF8STRING:
3080 case T_NUMERICSTRING:
3081 case T_PRINTABLESTRING:
3082 case T_TELETEXSTRING:
3083 case T_VIDEOTEXSTRING:
3084 case T_IA5STRING:
3085 case T_GRAPHICSTRING:
3086 case T_VISIBLESTRING:
3087 case T_GENERALSTRING:
3088 case T_UNIVERSALSTRING:
3089 case T_BMPSTRING:
3090 case T_UTCTIME:
3091 case T_GENERALIZEDTIME:
3092 case T_OBJECTDESCRIPTOR:
3093 chk_this_value_CStr(value);
3094 break;
3095 case T_OID:
3096 chk_this_value_OID(value);
3097 break;
3098 case T_ROID:
3099 chk_this_value_ROID(value);
3100 break;
3101 case T_ANY:
3102 chk_this_value_Any(value);
3103 break;
3104 case T_CHOICE_A:
3105 case T_CHOICE_T:
3106 case T_OPENTYPE:
3107 case T_ANYTYPE:
3108 self_ref = chk_this_value_Choice(value, lhs, expected_value, incomplete_allowed,
3109 implicit_omit);
3110 break;
3111 case T_SEQ_T:
3112 case T_SET_T:
3113 case T_SEQ_A:
3114 case T_SET_A:
3115 self_ref = chk_this_value_Se(value, lhs, expected_value, incomplete_allowed,
3116 implicit_omit);
3117 break;
3118 case T_SEQOF:
3119 case T_SETOF:
3120 self_ref = chk_this_value_SeOf(value, lhs, expected_value, incomplete_allowed,
3121 implicit_omit);
3122 break;
3123 case T_REFD:
3124 self_ref = get_type_refd()->chk_this_value(value, lhs, expected_value,
3125 incomplete_allowed, omit_allowed, NO_SUB_CHK, implicit_omit, is_str_elem);
3126 break;
3127 case T_UNRESTRICTEDSTRING:
3128 case T_OCFT:
3129 case T_EXTERNAL:
3130 case T_EMBEDDED_PDV:
3131 case T_REFDSPEC:
3132 case T_SELTYPE:
3133 case T_ADDRESS:
3134 self_ref = get_type_refd()->chk_this_value(value, lhs, expected_value,
3135 incomplete_allowed, omit_allowed, NO_SUB_CHK, NOT_IMPLICIT_OMIT, is_str_elem);
3136 break;
3137 case T_VERDICT:
3138 chk_this_value_Verdict(value);
3139 break;
3140 case T_DEFAULT:
3141 chk_this_value_Default(value);
3142 break;
3143 case T_ARRAY:
3144 self_ref = chk_this_value_Array(value, lhs, expected_value, incomplete_allowed, implicit_omit);
3145 break;
3146 case T_PORT:
3147 // Remain silent. The error has already been reported in the definition
3148 // that the value belongs to.
3149 break;
3150 case T_SIGNATURE:
3151 self_ref = chk_this_value_Signature(value, lhs, expected_value, incomplete_allowed);
3152 break;
3153 case T_COMPONENT:
3154 chk_this_value_Component(value);
3155 break;
3156 case T_FUNCTION:
3157 case T_ALTSTEP:
3158 case T_TESTCASE:
3159 chk_this_value_FAT(value);
3160 break;
3161 default:
3162 FATAL_ERROR("Type::chk_this_value()");
3163 } // switch
3164
3165 // check value against subtype
3166 if(sub_chk && (sub_type!=NULL)) sub_type->chk_this_value(value);
3167
3168 return self_ref;
3169 }
3170
3171 bool Type::chk_this_refd_value(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
3172 ReferenceChain* refch, namedbool str_elem)
3173 {
3174 Reference *ref = value->get_reference();
3175 Assignment *ass = ref->get_refd_assignment();
3176 if (!ass) {
3177 value->set_valuetype(Value::V_ERROR);
3178 return false;
3179 }
3180
3181 ass->chk();
3182 bool self_ref = (ass == lhs);
3183
3184 // Exit immediately in case of infinite recursion.
3185 if (value->get_valuetype() != Value::V_REFD) return self_ref;
3186 bool is_const = false, error_flag = false, chk_runs_on = false;
3187 Type *governor = NULL;
3188 switch (ass->get_asstype()) {
3189 case Assignment::A_ERROR:
3190 value->set_valuetype(Value::V_ERROR);
3191 return self_ref;
3192 case Assignment::A_CONST:
3193 is_const = true;
3194 break;
3195 case Assignment::A_OBJECT:
3196 case Assignment::A_OS: {
3197 Setting *setting = ref->get_refd_setting();
3198 if (!setting || setting->get_st() == Setting::S_ERROR) {
3199 value->set_valuetype(Value::V_ERROR);
3200 return self_ref;
3201 }
3202 if (setting->get_st() != Setting::S_V) {
3203 ref->error("This InformationFromObjects construct does not refer to "
3204 "a value: `%s'", value->get_fullname().c_str());
3205 value->set_valuetype(Value::V_ERROR);
3206 return self_ref;
3207 }
3208 governor = dynamic_cast<Value*>(setting)->get_my_governor();
3209 if (!governor) FATAL_ERROR("Type::chk_this_refd_value()");
3210 is_const = true;
3211 break; }
3212 case Assignment::A_MODULEPAR:
3213 #ifdef MINGW
3214 break;
3215 #endif
3216 case Assignment::A_EXT_CONST:
3217 if (expected_value == EXPECTED_CONSTANT) {
3218 value->error("Reference to an (evaluatable) constant value was "
3219 "expected instead of %s",
3220 ass->get_description().c_str());
3221 error_flag = true;
3222 }
3223 break;
3224 case Assignment::A_VAR:
3225 case Assignment::A_PAR_VAL:
3226 case Assignment::A_PAR_VAL_IN:
3227 case Assignment::A_PAR_VAL_OUT:
3228 case Assignment::A_PAR_VAL_INOUT:
3229 switch (expected_value) {
3230 case EXPECTED_CONSTANT:
3231 value->error("Reference to a constant value was expected instead of "
3232 "%s", ass->get_description().c_str());
3233 error_flag = true;
3234 break;
3235 case EXPECTED_STATIC_VALUE:
3236 value->error("Reference to a static value was expected instead of %s",
3237 ass->get_description().c_str());
3238 error_flag = true;
3239 break;
3240 default:
3241 break;
3242 }
3243 break;
3244 case Assignment::A_MODULEPAR_TEMP:
3245 case Assignment::A_TEMPLATE:
3246 case Assignment::A_VAR_TEMPLATE:
3247 case Assignment::A_PAR_TEMPL_IN:
3248 case Assignment::A_PAR_TEMPL_OUT:
3249 case Assignment::A_PAR_TEMPL_INOUT:
3250 if (expected_value != EXPECTED_TEMPLATE) {
3251 value->error("Reference to a value was expected instead of %s",
3252 ass->get_description().c_str());
3253 error_flag = true;
3254 }
3255 break;
3256 case Assignment::A_FUNCTION_RVAL:
3257 chk_runs_on = true;
3258 // No break
3259 case Assignment::A_EXT_FUNCTION_RVAL:
3260 switch (expected_value) {
3261 case EXPECTED_CONSTANT:
3262 value->error("Reference to a constant value was expected instead of "
3263 "the return value of %s",
3264 ass->get_description().c_str());
3265 error_flag = true;
3266 break;
3267 case EXPECTED_STATIC_VALUE:
3268 value->error("Reference to a static value was expected instead of "
3269 "the return value of %s",
3270 ass->get_description().c_str());
3271 error_flag = true;
3272 break;
3273 default:
3274 break;
3275 }
3276 break;
3277 case Assignment::A_FUNCTION_RTEMP:
3278 chk_runs_on = true;
3279 // No break
3280 case Assignment::A_EXT_FUNCTION_RTEMP:
3281 if (expected_value != EXPECTED_TEMPLATE) {
3282 value->error("Reference to a value was expected instead of a call of "
3283 "%s, which returns a template",
3284 ass->get_description().c_str());
3285 error_flag = true;
3286 }
3287 break;
3288 case Assignment::A_FUNCTION:
3289 case Assignment::A_EXT_FUNCTION:
3290 value->error("Reference to a %s was expected instead of a call of %s, "
3291 "which does not have return type",
3292 expected_value == EXPECTED_TEMPLATE
3293 ? "value or template" : "value",
3294 ass->get_description().c_str());
3295 value->set_valuetype(Value::V_ERROR);
3296 return self_ref;
3297 default:
3298 value->error("Reference to a %s was expected instead of %s",
3299 expected_value == EXPECTED_TEMPLATE
3300 ? "value or template" : "value",
3301 ass->get_description().c_str());
3302 value->set_valuetype(Value::V_ERROR);
3303 return self_ref;
3304 } // switch ass->get_asstype()
3305 if (chk_runs_on)
3306 ref->get_my_scope()->chk_runs_on_clause(ass, *ref, "call");
3307 if (!governor)
3308 governor = ass->get_Type()->get_field_type(ref->get_subrefs(),
3309 expected_value);
3310 if (!governor) {
3311 value->set_valuetype(Value::V_ERROR);
3312 return self_ref;
3313 }
3314 TypeCompatInfo info(value->get_my_scope()->get_scope_mod(), this,
3315 governor, true, false);
3316 info.set_str1_elem(str_elem);
3317 if (ref->get_subrefs()) info.set_str2_elem(ref->get_subrefs()->refers_to_string_element());
3318 TypeChain l_chain;
3319 TypeChain r_chain;
3320 if (!is_compatible(governor, &info, &l_chain, &r_chain)) {
3321 // Port or signature values do not exist at all. These errors are
3322 // already reported at those definitions. Extra errors should not be
3323 // reported here.
3324 Type *t = get_type_refd_last();
3325 switch (t->typetype) {
3326 case T_PORT:
3327 // Neither port values nor templates exist.
3328 break;
3329 case T_SIGNATURE:
3330 // Only signature templates may exist.
3331 if (expected_value == EXPECTED_TEMPLATE)
3332 value->error("Type mismatch: a signature template of type `%s' was "
3333 "expected instead of `%s'", get_typename().c_str(),
3334 governor->get_typename().c_str());
3335 break;
3336 default:
3337 if (info.is_subtype_error()) {
3338 value->error("%s", info.get_subtype_error().c_str());
3339 } else if (!info.is_erroneous()) {
3340 value->error("Type mismatch: a %s of type `%s' was expected "
3341 "instead of `%s'", expected_value == EXPECTED_TEMPLATE
3342 ? "value or template" : "value",
3343 get_typename().c_str(),
3344 governor->get_typename().c_str());
3345 } else {
3346 // The semantic error was found by the new code. It was better to
3347 // do the assembly inside TypeCompatInfo.
3348 value->error("%s", info.get_error_str_str().c_str());
3349 }
3350 break;
3351 }
3352 error_flag = true;
3353 } else {
3354 if (info.needs_conversion()) value->set_needs_conversion();
3355 }
3356
3357 if (error_flag) {
3358 value->set_valuetype(Value::V_ERROR);
3359 return self_ref;
3360 }
3361 // Checking for circular references.
3362 Value *v_last = value->get_value_refd_last(refch, expected_value);
3363 if (is_const && v_last->get_valuetype() != Value::V_ERROR) {
3364 // If a referenced universal charstring value points to a literal
3365 // charstring then drop the reference and create a literal ustring to
3366 // avoid run-time conversion.
3367 if (v_last->get_valuetype() == Value::V_CSTR
3368 && get_typetype_ttcn3(get_type_refd_last()->typetype) == T_USTR)
3369 value->set_valuetype(Value::V_USTR);
3370 // Check v_last against the subtype constraints.
3371 if (sub_type!=NULL) sub_type->chk_this_value(value);
3372 }
3373
3374 return self_ref;
3375 }
3376
3377 void Type::chk_this_invoked_value(Value *value, Common::Assignment *,
3378 expected_value_t expected_value)
3379 {
3380 value->get_value_refd_last(NULL, expected_value);
3381 if (value->get_valuetype() == Value::V_ERROR) return;
3382 Type *invoked_t = value->get_invoked_type(expected_value);
3383 if (invoked_t->get_typetype() == T_ERROR) return;
3384 invoked_t = invoked_t->get_type_refd_last();
3385 Type *t = 0;
3386 switch (invoked_t->get_typetype()) {
3387 case Type::T_FUNCTION:
3388 t = invoked_t->get_function_return_type();
3389 break;
3390 default:
3391 FATAL_ERROR("Type::chk_this_invoked_value()");
3392 break;
3393 }
3394 if (!t)
3395 value->error("The type `%s' has no return type, `%s' expected",
3396 invoked_t->get_typename().c_str(), get_typename().c_str());
3397 else if (!is_compatible(t, NULL)) {
3398 value->error("Incompatible value: `%s' value was expected",
3399 get_typename().c_str());
3400 }
3401 }
3402
3403 void Type::chk_this_value_Null(Value *value)
3404 {
3405 Value *v=value->get_value_refd_last();
3406 switch(v->get_valuetype()) {
3407 case Value::V_NULL:
3408 break;
3409 default:
3410 value->error("NULL value was expected");
3411 value->set_valuetype(Value::V_ERROR);
3412 break;
3413 }
3414 }
3415
3416 void Type::chk_this_value_Bool(Value *value)
3417 {
3418 Value *v=value->get_value_refd_last();
3419 switch(v->get_valuetype()) {
3420 case Value::V_BOOL:
3421 break;
3422 default:
3423 value->error("%s value was expected",
3424 value->is_asn1() ? "BOOLEAN" : "boolean");
3425 value->set_valuetype(Value::V_ERROR);
3426 break;
3427 }
3428 }
3429
3430 void Type::chk_this_value_Int(Value *value)
3431 {
3432 Value *v=value->get_value_refd_last();
3433 switch(v->get_valuetype()) {
3434 case Value::V_INT:
3435 break;
3436 default:
3437 value->error("integer value was expected");
3438 value->set_valuetype(Value::V_ERROR);
3439 break;
3440 }
3441 return;
3442 }
3443
3444 void Type::chk_this_value_Int_A(Value *value)
3445 {
3446 Value *v=value->get_value_refd_last();
3447 switch(v->get_valuetype()) {
3448 case Value::V_INT:
3449 break;
3450 case Value::V_NAMEDINT:
3451 if(!u.namednums.nvs)
3452 FATAL_ERROR("Type::chk_this_value_Int_A()");
3453 v->set_valuetype
3454 (Value::V_INT, u.namednums.nvs->
3455 get_nv_byName(*v->get_val_id())->get_value()->get_val_Int()->get_val());
3456 break;
3457 default:
3458 value->error("INTEGER value was expected");
3459 value->set_valuetype(Value::V_ERROR);
3460 break;
3461 }
3462 }
3463
3464 void Type::chk_this_value_Real(Value *value)
3465 {
3466 Value *v = value->get_value_refd_last();
3467 if (value->is_asn1()) {
3468 if (value->is_ref()) {
3469 Type *t = v->get_my_governor()->get_type_refd_last();
3470 if (t->get_typetype() != T_REAL) {
3471 value->error("REAL value was expected");
3472 value->set_valuetype(Value::V_ERROR);
3473 return;
3474 }
3475 }
3476 switch (v->get_valuetype()) {
3477 case Value::V_REAL:
3478 break;
3479 case Value::V_UNDEF_BLOCK:{
3480 v->set_valuetype(Value::V_SEQ);
3481 Identifier t_id(Identifier::ID_ASN, string("REAL"));
3482 bool self_ref = get_my_scope()->get_scope_asss()->get_local_ass_byId(t_id)
3483 ->get_Type()->chk_this_value(v, 0, EXPECTED_CONSTANT, INCOMPLETE_NOT_ALLOWED,
3484 OMIT_NOT_ALLOWED, SUB_CHK);
3485 (void)self_ref;
3486 v->set_valuetype(Value::V_REAL);
3487 break;}
3488 case Value::V_INT:
3489 v->set_valuetype(Value::V_REAL);
3490 break;
3491 default:
3492 value->error("REAL value was expected");
3493 value->set_valuetype(Value::V_ERROR);
3494 break;
3495 }
3496 } else {
3497 switch(v->get_valuetype()) {
3498 case Value::V_REAL:
3499 break;
3500 default:
3501 value->error("float value was expected");
3502 value->set_valuetype(Value::V_ERROR);
3503 break;
3504 }
3505 }
3506 }
3507
3508 void Type::chk_this_value_Enum(Value *value)
3509 {
3510 switch(value->get_valuetype()) {
3511 case Value::V_ENUM:
3512 break;
3513 default:
3514 value->error("%s value was expected",
3515 value->is_asn1() ? "ENUMERATED" : "enumerated");
3516 value->set_valuetype(Value::V_ERROR);
3517 break;
3518 }
3519 }
3520
3521 void Type::chk_this_value_BStr(Value *value)
3522 {
3523 Value *v = value->get_value_refd_last();
3524 switch(v->get_valuetype()) {
3525 case Value::V_BSTR:
3526 break;
3527 default:
3528 value->error("bitstring value was expected");
3529 value->set_valuetype(Value::V_ERROR);
3530 break;
3531 }
3532 }
3533
3534 void Type::chk_this_value_namedbits(Value *value)
3535 {
3536 if (!value) FATAL_ERROR("Type::chk_this_value_namedbits()");
3537 value->set_valuetype(Value::V_NAMEDBITS);
3538 if(!u.namednums.nvs) {
3539 value->error("No named bits are defined in type `%s'",
3540 get_typename().c_str());
3541 value->set_valuetype(Value::V_ERROR);
3542 return;
3543 }
3544 string *bstring = new string("");
3545 for(size_t i=0; i < value->get_nof_ids(); i++) {
3546 Identifier *id = value->get_id_byIndex(i);
3547 if(!u.namednums.nvs->has_nv_withName(*id)) {
3548 delete bstring;
3549 error("No named bit with name `%s' is defined in type `%s'",
3550 id->get_dispname().c_str(), get_typename().c_str());
3551 value->set_valuetype(Value::V_ERROR);
3552 return;
3553 }
3554 size_t bitnum = static_cast<size_t>
3555 (u.namednums.nvs->get_nv_byName(*id)->get_value()->get_val_Int()
3556 ->get_val());
3557 if(bstring->size() < bitnum + 1) bstring->resize(bitnum + 1, '0');
3558 (*bstring)[bitnum] = '1';
3559 }
3560 value->set_valuetype(Value::V_BSTR, bstring);
3561 }
3562
3563 void Type::chk_this_value_BStr_A(Value *value)
3564 {
3565 Value *v = value->get_value_refd_last();
3566 if (value->is_asn1()) {
3567 if(value->is_ref()) {
3568 Type *t = v->get_my_governor()->get_type_refd_last();
3569 if(t->get_typetype()!=T_BSTR_A && t->get_typetype()!=T_BSTR) {
3570 value->error("(reference to) BIT STRING value was expected");
3571 value->set_valuetype(Value::V_ERROR);
3572 return;
3573 }
3574 }
3575 switch(v->get_valuetype()) {
3576 case Value::V_BSTR:
3577 break;
3578 case Value::V_HSTR:
3579 if (v != value) FATAL_ERROR("Common::Type::chk_this_value_BStr_A()");
3580 v->set_valuetype(Value::V_BSTR);
3581 break;
3582 case Value::V_UNDEF_BLOCK:
3583 if (v != value) FATAL_ERROR("Type::chk_this_value_BStr_A()");
3584 chk_this_value_namedbits(v);
3585 break;
3586 default:
3587 value->error("BIT STRING value was expected");
3588 value->set_valuetype(Value::V_ERROR);
3589 return;
3590 }
3591 } else {
3592 switch(v->get_valuetype()) {
3593 case Value::V_BSTR:
3594 break;
3595 default:
3596 value->error("bitstring value was expected");
3597 value->set_valuetype(Value::V_ERROR);
3598 break;
3599 }
3600 }
3601 }
3602
3603 void Type::chk_this_value_HStr(Value *value)
3604 {
3605 Value *v = value->get_value_refd_last();
3606 switch (v->get_valuetype()) {
3607 case Value::V_HSTR:
3608 break;
3609 default:
3610 value->error("hexstring value was expected");
3611 value->set_valuetype(Value::V_ERROR);
3612 break;
3613 }
3614 }
3615
3616 void Type::chk_this_value_OStr(Value *value)
3617 {
3618 Value *v = value->get_value_refd_last();
3619 if (value->is_asn1()) {
3620 if (value->is_ref()) {
3621 Type *t = v->get_my_governor()->get_type_refd_last();
3622 if(t->get_typetype() != T_OSTR) {
3623 value->error("(reference to) OCTET STRING value was expected");
3624 value->set_valuetype(Value::V_ERROR);
3625 return;
3626 }
3627 }
3628 switch(v->get_valuetype()) {
3629 case Value::V_OSTR:
3630 break;
3631 case Value::V_BSTR:
3632 case Value::V_HSTR:
3633 if (v != value) FATAL_ERROR("Type::chk_this_value_OStr()");
3634 v->set_valuetype(Value::V_OSTR);
3635 break;
3636 default:
3637 value->error("OCTET STRING value was expected");
3638 value->set_valuetype(Value::V_ERROR);
3639 break;
3640 }
3641 } else {
3642 switch(v->get_valuetype()) {
3643 case Value::V_OSTR:
3644 break;
3645 default:
3646 value->error("octetstring value was expected");
3647 value->set_valuetype(Value::V_ERROR);
3648 break;
3649 }
3650 }
3651 }
3652
3653 /** \todo enhance */
3654 void Type::chk_this_value_CStr(Value *value)
3655 {
3656
3657 switch(value->get_valuetype()) {
3658 case Value::V_UNDEF_BLOCK:
3659 value->set_valuetype(Value::V_CHARSYMS);
3660 if (value->get_valuetype() == Value::V_ERROR) return;
3661 // no break
3662 case Value::V_CHARSYMS:
3663 switch (typetype) {
3664 case T_USTR:
3665 case T_UTF8STRING:
3666 case T_BMPSTRING:
3667 case T_UNIVERSALSTRING:
3668 value->set_valuetype(Value::V_USTR);
3669 break;
3670 case T_TELETEXSTRING:
3671 case T_VIDEOTEXSTRING:
3672 case T_GRAPHICSTRING:
3673 case T_OBJECTDESCRIPTOR:
3674 case T_GENERALSTRING:
3675 value->set_valuetype(Value::V_ISO2022STR);
3676 break;
3677 case T_CSTR:
3678 case T_NUMERICSTRING:
3679 case T_PRINTABLESTRING:
3680 case T_IA5STRING:
3681 case T_VISIBLESTRING:
3682 case T_UTCTIME:
3683 case T_GENERALIZEDTIME:
3684 value->set_valuetype(Value::V_CSTR);
3685 break;
3686 default:
3687 FATAL_ERROR("chk_this_value_CStr()");
3688 } // switch
3689 break;
3690 case Value::V_USTR:
3691 switch (typetype) {
3692 case T_USTR:
3693 case T_UTF8STRING:
3694 case T_BMPSTRING:
3695 case T_UNIVERSALSTRING:
3696 break;
3697 case T_TELETEXSTRING:
3698 case T_VIDEOTEXSTRING:
3699 case T_GRAPHICSTRING:
3700 case T_OBJECTDESCRIPTOR:
3701 case T_GENERALSTRING:
3702 // accept it
3703 /*
3704 if(value->get_val_ustr().is_cstr()) {
3705 value->warning("ISO-2022 string value was expected (converting"
3706 " simple ISO-10646 string).");
3707 value->set_valuetype(Value::V_CSTR);
3708 }
3709 else {
3710 value->error("ISO-2022 string value was expected (instead of"
3711 " ISO-10646 string).");
3712 value->set_valuetype(Value::V_ERROR);
3713 }
3714 */
3715 break;
3716 case T_CSTR:
3717 case T_NUMERICSTRING:
3718 case T_PRINTABLESTRING:
3719 case T_IA5STRING:
3720 case T_VISIBLESTRING:
3721 case T_UTCTIME:
3722 case T_GENERALIZEDTIME:
3723 value->set_valuetype(Value::V_CSTR);
3724 break;
3725 default:
3726 FATAL_ERROR("Type::chk_this_value_CStr()");
3727 } // switch
3728 break;
3729 case Value::V_CSTR:
3730 switch (typetype) {
3731 case T_USTR:
3732 case T_UTF8STRING:
3733 case T_BMPSTRING:
3734 case T_UNIVERSALSTRING:
3735 value->set_valuetype(Value::V_USTR);
3736 break;
3737 case T_TELETEXSTRING:
3738 case T_VIDEOTEXSTRING:
3739 case T_GRAPHICSTRING:
3740 case T_OBJECTDESCRIPTOR:
3741 case T_GENERALSTRING:
3742 value->set_valuetype(Value::V_ISO2022STR);
3743 break;
3744 case T_CSTR:
3745 case T_NUMERICSTRING:
3746 case T_PRINTABLESTRING:
3747 case T_IA5STRING:
3748 case T_VISIBLESTRING:
3749 case T_UTCTIME:
3750 case T_GENERALIZEDTIME:
3751 break;
3752 default:
3753 FATAL_ERROR("chk_this_value_CStr()");
3754 } // switch
3755 break;
3756 case Value::V_ISO2022STR:
3757 switch (typetype) {
3758 case T_USTR:
3759 case T_UTF8STRING:
3760 case T_BMPSTRING:
3761 case T_UNIVERSALSTRING:
3762 value->error("ISO-10646 string value was expected (instead of"
3763 " ISO-2022 string).");
3764 value->set_valuetype(Value::V_ERROR);
3765 break;
3766 case T_TELETEXSTRING:
3767 case T_VIDEOTEXSTRING:
3768 case T_GRAPHICSTRING:
3769 case T_OBJECTDESCRIPTOR:
3770 case T_GENERALSTRING:
3771 break;
3772 case T_CSTR:
3773 case T_NUMERICSTRING:
3774 case T_PRINTABLESTRING:
3775 case T_IA5STRING:
3776 case T_VISIBLESTRING:
3777 case T_UTCTIME:
3778 case T_GENERALIZEDTIME:
3779 value->set_valuetype(Value::V_ISO2022STR);
3780 break;
3781 default:
3782 FATAL_ERROR("chk_this_value_CStr()");
3783 } // switch
3784 break;
3785 default:
3786 value->error("character string value was expected");
3787 value->set_valuetype(Value::V_ERROR);
3788 break;
3789 }
3790 }
3791
3792 void Type::chk_this_value_OID(Value *value)
3793 {
3794 Value *v = value->get_value_refd_last();
3795 if (value->is_asn1()) {
3796 if (value->is_ref()) {
3797 Type *t = v->get_my_governor()->get_type_refd_last();
3798 if (t->get_typetype() != T_OID) {
3799 value->error("(reference to) OBJECT IDENTIFIER value was "
3800 "expected");
3801 value->set_valuetype(Value::V_ERROR);
3802 return;
3803 }
3804 }
3805 switch (v->get_valuetype()) {
3806 case Value::V_OID:
3807 break;
3808 case Value::V_UNDEF_BLOCK:
3809 if (v != value) FATAL_ERROR("Type::chk_this_value_OID()");
3810 v->set_valuetype(Value::V_OID);
3811 v->chk();
3812 break;
3813 default:
3814 value->error("OBJECT IDENTIFIER value was expected");
3815 value->set_valuetype(Value::V_ERROR);
3816 break;
3817 }
3818 } else {
3819 switch (v->get_valuetype()) {
3820 case Value::V_OID:
3821 v->chk();
3822 break;
3823 default:
3824 value->error("objid value was expected");
3825 value->set_valuetype(Value::V_ERROR);
3826 break;
3827 }
3828 }
3829 }
3830
3831 void Type::chk_this_value_ROID(Value *value)
3832 {
3833 Value *v = value->get_value_refd_last();
3834 if(value->is_ref()) {
3835 Type *t = v->get_my_governor()->get_type_refd_last();
3836 if (t->get_typetype() != T_ROID) {
3837 value->error("(reference to) RELATIVE-OID value was expected");
3838 value->set_valuetype(Value::V_ERROR);
3839 return;
3840 }
3841 }
3842 switch(v->get_valuetype()) {
3843 case Value::V_ROID:
3844 break;
3845 case Value::V_UNDEF_BLOCK:
3846 if (v != value) FATAL_ERROR("Type::chk_this_value_ROID()");
3847 v->set_valuetype(Value::V_ROID);
3848 v->chk();
3849 break;
3850 default:
3851 value->error("RELATIVE-OID value was expected");
3852 value->set_valuetype(Value::V_ERROR);
3853 break;
3854 }
3855 }
3856
3857 void Type::chk_this_value_Any(Value *value)
3858 {
3859 Value *v = value->get_value_refd_last();
3860 if (value->is_asn1()) {
3861 if (value->is_ref()) {
3862 Type *t = v->get_my_governor()->get_type_refd_last();
3863 if(t->get_typetype()!=T_ANY && t->get_typetype()!=T_OSTR) {
3864 value->error("(reference to) OCTET STRING or ANY type value"
3865 " was expected");
3866 value->set_valuetype(Value::V_ERROR);
3867 return;
3868 }
3869 }
3870 switch(v->get_valuetype()) {
3871 case Value::V_OSTR:
3872 break;
3873 case Value::V_HSTR:
3874 if (v!=value) FATAL_ERROR("Type::chk_this_value_Any()");
3875 v->set_valuetype(Value::V_OSTR);
3876 break;
3877 default:
3878 value->error("ANY (OCTET STRING) value was expected");
3879 value->set_valuetype(Value::V_ERROR);
3880 break;
3881 }
3882 }
3883 else { // is ttcn
3884 switch(v->get_valuetype()) {
3885 case Value::V_OSTR:
3886 break;
3887 default:
3888 value->error("octetstring value was expected for ASN ANY type");
3889 value->set_valuetype(Value::V_ERROR);
3890 break;
3891 }
3892 }
3893 }
3894
3895 /** Return a string containing the names of existing fields (components).
3896 *
3897 * @param t a Type object
3898 * @return a string (l-value, temporary)
3899 * @pre t must be a sequence, choice, set, anytype, open type
3900 */
3901 static string actual_fields(Type& t) // alas, not even get_nof_comps() is const
3902 {
3903 static const string has_no(" has no ");
3904 size_t ncomps = t.get_nof_comps();
3905 const string fields_or_comps(t.is_asn1() ? "components" : "fields");
3906 if (ncomps) {
3907 string msg("Valid ");
3908 msg += fields_or_comps;
3909 msg += ": ";
3910 msg += t.get_comp_byIndex(0)->get_name().get_dispname();
3911 for (size_t ci=1; ci < ncomps; ++ci) {
3912 msg += ',';
3913 msg += t.get_comp_byIndex(ci)->get_name().get_dispname();
3914 }
3915 return msg;
3916 }
3917 else return t.get_fullname() + has_no + fields_or_comps;
3918 }
3919
3920
3921 bool Type::chk_this_value_Choice(Value *value, Common::Assignment *lhs,
3922 expected_value_t expected_value, namedbool incomplete_allowed, namedbool implicit_omit)
3923 {
3924 bool self_ref = false;
3925 switch(value->get_valuetype()) {
3926 case Value::V_SEQ:
3927 if (value->is_asn1()) {
3928 value->error("CHOICE value was expected for type `%s'",
3929 get_fullname().c_str());
3930 value->set_valuetype(Value::V_ERROR);
3931 break;
3932 } else {
3933 // the valuetype can be ERROR if the value has no fields at all
3934 if (value->get_valuetype() == Value::V_ERROR) return false;
3935 // The value notation for TTCN record/union types
3936 // cannot be distinguished during parsing. Now we know it's a union.
3937 value->set_valuetype(Value::V_CHOICE);
3938 }
3939 // no break
3940 case Value::V_CHOICE: {
3941 const Identifier& alt_name = value->get_alt_name();
3942 if(!has_comp_withName(alt_name)) {
3943 if (value->is_asn1()) {
3944 value->error("Reference to non-existent alternative `%s' in CHOICE"
3945 " value for type `%s'",
3946 alt_name.get_dispname().c_str(),
3947 get_fullname().c_str());
3948 } else {
3949 value->error("Reference to non-existent field `%s' in union "
3950 "value for type `%s'",
3951 alt_name.get_dispname().c_str(),
3952 get_fullname().c_str());
3953 }
3954 value->set_valuetype(Value::V_ERROR);
3955 value->note("%s", actual_fields(*this).c_str());
3956 return self_ref;
3957 }
3958 Type *alt_type = get_comp_byName(alt_name)->get_type();
3959 Value *alt_value = value->get_alt_value();
3960 Error_Context cntxt(value, "In value for %s `%s'",
3961 value->is_asn1() ? "alternative" : "union field",
3962 alt_name.get_dispname().c_str());
3963 alt_value->set_my_governor(alt_type);
3964 alt_type->chk_this_value_ref(alt_value);
3965 self_ref |= alt_type->chk_this_value(alt_value, lhs, expected_value,
3966 incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
3967 break;}
3968 default:
3969 value->error("%s value was expected for type `%s'",
3970 value->is_asn1() ? "CHOICE" : "union",
3971 get_fullname().c_str());
3972 value->set_valuetype(Value::V_ERROR);
3973 break;
3974 }
3975 return self_ref;
3976 }
3977
3978 bool Type::chk_this_value_Se(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
3979 namedbool incomplete_allowed, namedbool implicit_omit)
3980 {
3981 if (value->is_asn1())
3982 return chk_this_value_Se_A(value, lhs, expected_value, implicit_omit);
3983 else
3984 return chk_this_value_Se_T(value, lhs, expected_value, incomplete_allowed,
3985 implicit_omit);
3986 }
3987
3988 bool Type::chk_this_value_Se_T(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
3989 namedbool incomplete_allowed, namedbool implicit_omit)
3990 {
3991 switch (value->get_valuetype()) {
3992 case Value::V_SEQ:
3993 if (typetype == T_SET_A || typetype == T_SET_T) {
3994 value->set_valuetype(Value::V_SET);
3995 return chk_this_value_Set_T(value, lhs, expected_value, incomplete_allowed,
3996 implicit_omit);
3997 } else {
3998 return chk_this_value_Seq_T(value, lhs, expected_value, incomplete_allowed,
3999 implicit_omit);
4000 }
4001 break;
4002 case Value::V_SEQOF:
4003 if (typetype == T_SET_A || typetype == T_SET_T) {
4004 if (value->get_nof_comps() == 0) {
4005 if (get_nof_comps() == 0) {
4006 value->set_valuetype(Value::V_SET);
4007 } else {
4008 value->error("A non-empty set value was expected for type `%s'",
4009 get_fullname().c_str());
4010 value->set_valuetype(Value::V_ERROR);
4011 }
4012 } else {
4013 // This will catch the indexed assignment notation as well.
4014 value->error("Value list notation cannot be used for "
4015 "%s type `%s'", typetype == T_SET_A ? "SET" : "set",
4016 get_fullname().c_str());
4017 value->set_valuetype(Value::V_ERROR);
4018 }
4019 } else {
4020 if (value->is_indexed()) {
4021 value->error("Indexed assignment notation cannot be used for %s "
4022 "type `%s'", typetype == T_SEQ_A
4023 ? "SEQUENCE" : "record",
4024 get_fullname().c_str());
4025 value->set_valuetype(Value::V_ERROR);
4026 } else {
4027 value->set_valuetype(Value::V_SEQ);
4028 return chk_this_value_Seq_T(value, lhs, expected_value, incomplete_allowed,
4029 implicit_omit);
4030 }
4031 }
4032 break;
4033 default:
4034 value->error("%s value was expected for type `%s'",
4035 typetype == T_SEQ_T ? "Record" : "Set",
4036 get_fullname().c_str());
4037 value->set_valuetype(Value::V_ERROR);
4038 break;
4039 }
4040 return false;
4041 }
4042
4043 bool Type::chk_this_value_Seq_T(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
4044 namedbool incomplete_allowed, namedbool implicit_omit)
4045 {
4046 bool self_ref = false;
4047 map<string, NamedValue> comp_map;
4048 // it is set to false if we have lost the ordering
4049 bool in_synch = true;
4050 const size_t n_type_comps = get_nof_comps();
4051 size_t n_value_comps = value->get_nof_comps();
4052 // for incomplete values
4053 CompField *last_cf = 0;
4054 size_t next_index = 0;
4055 size_t seq_index = 0;
4056 for (size_t v_i = 0; v_i < n_value_comps; v_i++, seq_index++) {
4057 NamedValue *nv = value->get_se_comp_byIndex(v_i);
4058 const Identifier& value_id = nv->get_name();
4059 const string& value_name = value_id.get_name();
4060 const char *value_dispname_str = value_id.get_dispname().c_str();
4061 if (!has_comp_withName(value_id)) {
4062 nv->error("Reference to non-existent field `%s' in record value for "
4063 "type `%s'", value_dispname_str, get_typename().c_str());
4064 nv->note("%s", actual_fields(*this).c_str());
4065 in_synch = false;
4066 continue;
4067 } else if (comp_map.has_key(value_name)) {
4068 nv->error("Duplicate record field `%s'", value_dispname_str);
4069 comp_map[value_name]->note("Field `%s' is already given here",
4070 value_dispname_str);
4071 in_synch = false;
4072 } else comp_map.add(value_name, nv);
4073 CompField *cf = get_comp_byName(value_id);
4074 // check the ordering of fields
4075 if (in_synch) {
4076 if (incomplete_allowed) {
4077 bool found = false;
4078 for (size_t i = next_index; i < n_type_comps; i++) {
4079 CompField *cf2 = get_comp_byIndex(i);
4080 if (value_name == cf2->get_name().get_name()) {
4081 last_cf = cf2;
4082 next_index = i + 1;
4083 found = true;
4084 break;
4085 }
4086 }
4087 if (!found) {
4088 nv->error("Field `%s' cannot appear after field `%s' in record "
4089 "value", value_dispname_str,
4090 last_cf->get_name().get_dispname().c_str());
4091 in_synch = false;
4092 }
4093 } else {
4094 // the value must be complete unless implicit omit is set
4095 CompField *cf2 = get_comp_byIndex(seq_index);
4096 CompField *cf2_orig = cf2;
4097 while (implicit_omit && seq_index < n_type_comps && cf2 != cf &&
4098 cf2->get_is_optional())
4099 cf2 = get_comp_byIndex(++seq_index);
4100 if (seq_index >= n_type_comps || cf2 != cf) {
4101 nv->error("Unexpected field `%s' in record value, "
4102 "expecting `%s'", value_dispname_str,
4103 cf2_orig->get_name().get_dispname().c_str());
4104 in_synch = false;
4105 }
4106 }
4107 }
4108 Type *type = cf->get_type();
4109 Value *comp_value = nv->get_value();
4110 comp_value->set_my_governor(type);
4111 if (comp_value->get_valuetype() == Value::V_NOTUSED) {
4112 if (implicit_omit) {
4113 comp_value->set_valuetype(Value::V_OMIT);
4114 } else {
4115 continue;
4116 }
4117 }
4118 Error_Context cntxt(nv, "In value for record field `%s'",
4119 value_dispname_str);
4120 type->chk_this_value_ref(comp_value);
4121 self_ref |= type->chk_this_value(comp_value, lhs, expected_value, incomplete_allowed,
4122 cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
4123 }
4124 if (!incomplete_allowed || implicit_omit) {
4125 for (size_t i = 0; i < n_type_comps; i++) {
4126 const Identifier& id = get_comp_byIndex(i)->get_name();
4127 if (!comp_map.has_key(id.get_name())) {
4128 if (get_comp_byIndex(i)->get_is_optional() && implicit_omit)
4129 value->add_se_comp(new NamedValue(new Identifier(id),
4130 new Value(Value::V_OMIT)));
4131 else if (!incomplete_allowed)
4132 value->error("Field `%s' is missing from record value",
4133 id.get_dispname().c_str());
4134 }
4135 }
4136 }
4137 comp_map.clear();
4138 return self_ref;
4139 }
4140
4141 bool Type::chk_this_value_Set_T(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
4142 namedbool incomplete_allowed, namedbool implicit_omit)
4143 {
4144 bool self_ref = false;
4145 map<string, NamedValue> comp_map;
4146 size_t n_type_comps = get_nof_comps();
4147 size_t n_value_comps = value->get_nof_comps();
4148 for(size_t v_i = 0; v_i < n_value_comps; v_i++) {
4149 NamedValue *nv = value->get_se_comp_byIndex(v_i);
4150 const Identifier& value_id = nv->get_name();
4151 const string& value_name = value_id.get_name();
4152 const char *value_dispname_str = value_id.get_dispname().c_str();
4153 if (!has_comp_withName(value_id)) {
4154 nv->error("Reference to non-existent field `%s' in set value for "
4155 "type `%s'", value_dispname_str, get_typename().c_str());
4156 nv->note("%s", actual_fields(*this).c_str());
4157 continue;
4158 } else if (comp_map.has_key(value_name)) {
4159 nv->error("Duplicate set field `%s'", value_dispname_str);
4160 comp_map[value_name]->note("Field `%s' is already given here",
4161 value_dispname_str);
4162 } else comp_map.add(value_name, nv);
4163 CompField *cf = get_comp_byName(value_id);
4164 Type *type = cf->get_type();
4165 Value *comp_value = nv->get_value();
4166 comp_value->set_my_governor(type);
4167 if (comp_value->get_valuetype() == Value::V_NOTUSED) {
4168 if (implicit_omit) {
4169 comp_value->set_valuetype(Value::V_OMIT);
4170 } else {
4171 continue;
4172 }
4173 }
4174 Error_Context cntxt(nv, "In value for set field `%s'",
4175 value_dispname_str);
4176 type->chk_this_value_ref(comp_value);
4177 self_ref |= type->chk_this_value(comp_value, lhs, expected_value, incomplete_allowed,
4178 cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
4179 }
4180 if (!incomplete_allowed || implicit_omit) {
4181 for (size_t i = 0; i < n_type_comps; i++) {
4182 const Identifier& id = get_comp_byIndex(i)->get_name();
4183 if(!comp_map.has_key(id.get_name())) {
4184 if (get_comp_byIndex(i)->get_is_optional() && implicit_omit)
4185 value->add_se_comp(new NamedValue(new Identifier(id),
4186 new Value(Value::V_OMIT)));
4187 else if (!incomplete_allowed)
4188 value->error("Field `%s' is missing from set value %s",
4189 id.get_dispname().c_str(), implicit_omit ? "yes" : "no");
4190 }
4191 }
4192 }
4193 comp_map.clear();
4194 return self_ref;
4195 }
4196
4197 bool Type::chk_this_value_Se_A(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
4198 namedbool implicit_omit)
4199 {
4200 if(value->get_valuetype()==Value::V_UNDEF_BLOCK) {
4201 if(typetype == T_SEQ_A) value->set_valuetype(Value::V_SEQ);
4202 else value->set_valuetype(Value::V_SET);
4203 } // if V_UNDEF
4204 switch(value->get_valuetype()) {
4205 case Value::V_SEQ:
4206 return chk_this_value_Seq_A(value, lhs, expected_value, implicit_omit);
4207 case Value::V_SET:
4208 return chk_this_value_Set_A(value, lhs, expected_value, implicit_omit);
4209 default:
4210 value->error("%s value was expected",
4211 typetype == T_SEQ_A ? "SEQUENCE" : "SET");
4212 value->set_valuetype(Value::V_ERROR);
4213 break;
4214 }
4215 return false;
4216 }
4217
4218 bool Type::chk_this_value_Seq_A(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
4219 namedbool implicit_omit)
4220 {
4221 bool self_ref = false;
4222 map<string, NamedValue> comp_map;
4223 // it is set to false if we have lost the ordering
4224 bool in_synch = true;
4225 size_t n_type_comps = u.secho.ctss->get_nof_comps();
4226 size_t n_value_comps = value->get_nof_comps();
4227 size_t t_i = 0;
4228 for (size_t v_i = 0; v_i < n_value_comps; v_i++) {
4229 NamedValue *nv = value->get_se_comp_byIndex(v_i);
4230 const Identifier& value_id = nv->get_name();
4231 const string& value_name = value_id.get_name();
4232 const char *value_dispname_str = value_id.get_dispname().c_str();
4233 if (!u.secho.ctss->has_comp_withName(value_id)) {
4234 nv->error("Reference to non-existent component `%s' of SEQUENCE "
4235 "type `%s'", value_dispname_str, get_typename().c_str());
4236 nv->note("%s", actual_fields(*this).c_str());
4237 in_synch = false;
4238 continue;
4239 } else if (comp_map.has_key(value_name)) {
4240 nv->error("Duplicate SEQUENCE component `%s'", value_dispname_str);
4241 comp_map[value_name]->note("Component `%s' is already given here",
4242 value_dispname_str);
4243 in_synch = false;
4244 } else comp_map.add(value_name, nv);
4245 CompField *cf = u.secho.ctss->get_comp_byName(value_id);
4246 if (in_synch) {
4247 CompField *cf2 = 0;
4248 for ( ; t_i < n_type_comps; t_i++) {
4249 cf2 = u.secho.ctss->get_comp_byIndex(t_i);
4250 if (cf2 == cf || (!cf2->get_is_optional() && !cf2->has_default() &&
4251 !implicit_omit))
4252 break;
4253 }
4254 if (cf2 != cf) {
4255 if (t_i < n_type_comps) {
4256 nv->error("Unexpected component `%s' in SEQUENCE value, "
4257 "expecting `%s'", value_dispname_str,
4258 cf2->get_name().get_dispname().c_str());
4259 } else {
4260 nv->error("Unexpected component `%s' in SEQUENCE value",
4261 value_dispname_str);
4262 }
4263 in_synch = false;
4264 } else t_i++;
4265 }
4266 Type *type = cf->get_type();
4267 Error_Context cntxt(nv, "In value for SEQUENCE component `%s'",
4268 value_dispname_str);
4269 Value *comp_value = nv->get_value();
4270 comp_value->set_my_governor(type);
4271 type->chk_this_value_ref(comp_value);
4272 self_ref |= type->chk_this_value(comp_value, lhs, expected_value,
4273 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
4274 }
4275 for (size_t i = 0; i < n_type_comps; i++) {
4276 CompField *cf = u.secho.ctss->get_comp_byIndex(i);
4277 const Identifier& id = cf->get_name();
4278 if (!comp_map.has_key(id.get_name())) {
4279 if (!cf->get_is_optional() && !cf->has_default())
4280 value->error("Mandatory component `%s' is missing from SEQUENCE value",
4281 id.get_dispname().c_str());
4282 else if (cf->get_is_optional() && implicit_omit)
4283 value->add_se_comp(new NamedValue(new Identifier(id),
4284 new Value(Value::V_OMIT)));
4285 }
4286 }
4287 comp_map.clear();
4288 return self_ref;
4289 }
4290
4291 bool Type::chk_this_value_Set_A(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
4292 namedbool implicit_omit)
4293 {
4294 bool self_ref = false;
4295 map<string, NamedValue> comp_map;
4296 size_t n_type_comps = u.secho.ctss->get_nof_comps();
4297 size_t n_value_comps = value->get_nof_comps();
4298 for(size_t v_i = 0; v_i < n_value_comps; v_i++) {
4299 NamedValue *nv = value->get_se_comp_byIndex(v_i);
4300 const Identifier& value_id = nv->get_name();
4301 const string& value_name = value_id.get_name();
4302 const char *value_dispname_str = value_id.get_dispname().c_str();
4303 if (!u.secho.ctss->has_comp_withName(value_id)) {
4304 value->error("Reference to non-existent component `%s' of SET type "
4305 "`%s'", value_dispname_str, get_typename().c_str());
4306 nv->note("%s", actual_fields(*this).c_str());
4307 continue;
4308 } else if (comp_map.has_key(value_name)) {
4309 nv->error("Duplicate SET component `%s'", value_dispname_str);
4310 comp_map[value_name]->note("Component `%s' is already given here",
4311 value_dispname_str);
4312 } else comp_map.add(value_name, nv);
4313 Type *type =
4314 u.secho.ctss->get_comp_byName(value_id)->get_type();
4315 Value *comp_value = nv->get_value();
4316 Error_Context cntxt(nv, "In value for SET component `%s'",
4317 value_dispname_str);
4318 comp_value->set_my_governor(type);
4319 type->chk_this_value_ref(comp_value);
4320 self_ref |= type->chk_this_value(comp_value, lhs, expected_value,
4321 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
4322 }
4323 for (size_t i = 0; i < n_type_comps; i++) {
4324 CompField *cf = u.secho.ctss->get_comp_byIndex(i);
4325 const Identifier& id = cf->get_name();
4326 if (!comp_map.has_key(id.get_name())) {
4327 if (!cf->get_is_optional() && !cf->has_default())
4328 value->error("Mandatory component `%s' is missing from SET value",
4329 id.get_dispname().c_str());
4330 else if (cf->get_is_optional() && implicit_omit)
4331 value->add_se_comp(new NamedValue(new Identifier(id),
4332 new Value(Value::V_OMIT)));
4333 }
4334 }
4335 comp_map.clear();
4336 return self_ref;
4337 }
4338
4339 bool Type::chk_this_value_SeOf(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
4340 namedbool incomplete_allowed, namedbool implicit_omit)
4341 {
4342 bool self_ref = false;
4343 const char *valuetypename;
4344 if (value->is_asn1()) {
4345 if (typetype == T_SEQOF) valuetypename = "SEQUENCE OF";
4346 else valuetypename = "SET OF";
4347 } else {
4348 if (typetype == T_SEQOF) valuetypename = "record of";
4349 else valuetypename = "set of";
4350 }
4351 if (value->get_valuetype() == Value::V_UNDEF_BLOCK) {
4352 if (typetype == T_SEQOF) value->set_valuetype(Value::V_SEQOF);
4353 else value->set_valuetype(Value::V_SETOF);
4354 } // if V_UNDEF
4355 switch (value->get_valuetype()) {
4356 case Value::V_SEQOF:
4357 if (typetype == T_SETOF) value->set_valuetype(Value::V_SETOF);
4358 // no break
4359 case Value::V_SETOF: {
4360 if (!value->is_indexed()) {
4361 for (size_t i = 0; i < value->get_nof_comps(); i++) {
4362 Value *v_comp = value->get_comp_byIndex(i);
4363 Error_Context cntxt(v_comp, "In component #%lu",
4364 (unsigned long)(i + 1));
4365 v_comp->set_my_governor(u.seof.ofType);
4366 if (v_comp->get_valuetype() == Value::V_NOTUSED) {
4367 if (!incomplete_allowed)
4368 v_comp->error("Not used symbol `-' is not allowed in this "
4369 "context");
4370 } else {
4371 u.seof.ofType->chk_this_value_ref(v_comp);
4372 self_ref |= u.seof.ofType->chk_this_value(v_comp, lhs, expected_value,
4373 incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
4374 }
4375 }
4376 } else {
4377 // Only constant values with constant indicies can be checked at
4378 // compile time. Constant expressions evaluated.
4379 bool check_holes = expected_value == EXPECTED_CONSTANT;
4380 Int max_index = -1;
4381 map<Int, Int> index_map;
4382 for (size_t i = 0; i < value->get_nof_comps(); i++) {
4383 Error_Context cntxt(this, "In component #%lu",
4384 (unsigned long)(i + 1));
4385 Value *val = value->get_comp_byIndex(i);
4386 Value *index = value->get_index_byIndex(i);
4387 index->chk_expr_int(expected_value);
4388 if (index->get_valuetype() != Value::V_ERROR &&
4389 index->get_value_refd_last()->get_valuetype() == Value::V_INT) {
4390 const int_val_t *index_int = index->get_value_refd_last()
4391 ->get_val_Int();
4392 if (*index_int > INT_MAX) {
4393 index->error("An integer value less than `%d' was expected for "
4394 "indexing type `%s' instead of `%s'", INT_MAX,
4395 get_typename().c_str(),
4396 (index_int->t_str()).c_str());
4397 index->set_valuetype(Value::V_ERROR);
4398 check_holes = false;
4399 } else {
4400 Int index_val = index_int->get_val();
4401 if (index_val < 0) {
4402 index->error("A non-negative integer value was expected for "
4403 "indexing type `%s' instead of `%s'",
4404 get_typename().c_str(),
4405 Int2string(index_val).c_str());
4406 index->set_valuetype(Value::V_ERROR);
4407 check_holes = false;
4408 } else if (index_map.has_key(index_val)) {
4409 index->error("Duplicate index value `%s' for components `%s' "
4410 "and `%s'", Int2string(index_val).c_str(),
4411 Int2string((Int)i + 1).c_str(),
4412 Int2string(*index_map[index_val]).c_str());
4413 index->set_valuetype(Value::V_ERROR);
4414 check_holes = false;
4415 } else {
4416 index_map.add(index_val, new Int((Int)i + 1));
4417 if (max_index < index_val)
4418 max_index = index_val;
4419 }
4420 }
4421 } else {
4422 // The index cannot be determined.
4423 check_holes = false;
4424 }
4425 val->set_my_governor(u.seof.ofType);
4426 u.seof.ofType->chk_this_value_ref(val);
4427 self_ref |= u.seof.ofType->chk_this_value(val, lhs, expected_value,
4428 incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK);
4429 }
4430 if (check_holes) {
4431 if ((size_t)max_index != index_map.size() - 1) {
4432 value->error("It's not allowed to create hole(s) in constant "
4433 "values");
4434 value->set_valuetype(Value::V_ERROR);
4435 }
4436 }
4437 for (size_t i = 0; i < index_map.size(); i++)
4438 delete index_map.get_nth_elem(i);
4439 index_map.clear();
4440 }
4441 break; }
4442 default:
4443 value->error("%s value was expected", valuetypename);
4444 value->set_valuetype(Value::V_ERROR);
4445 break;
4446 }
4447 return self_ref;
4448 }
4449
4450 void Type::chk_this_value_Verdict(Value *value)
4451 {
4452 Value *v = value->get_value_refd_last();
4453 switch (v->get_valuetype()) {
4454 case Value::V_VERDICT:
4455 break;
4456 default:
4457 value->error("verdict value was expected");
4458 value->set_valuetype(Value::V_ERROR);
4459 break;
4460 }
4461 }
4462
4463 /** \todo enhance to handle activate */
4464 void Type::chk_this_value_Default(Value *value)
4465 {
4466 switch (value->get_valuetype()) {
4467 case Value::V_TTCN3_NULL:
4468 value->set_valuetype(Value::V_DEFAULT_NULL);
4469 break;
4470 default:
4471 value->error("default value was expected");
4472 value->set_valuetype(Value::V_ERROR);
4473 break;
4474 }
4475 }
4476
4477 bool Type::chk_this_value_Array(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
4478 namedbool incomplete_allowed, namedbool implicit_omit)
4479 {
4480 bool self_ref = false;
4481 switch (value->get_valuetype()) {
4482 case Value::V_SEQOF:
4483 value->set_valuetype(Value::V_ARRAY);
4484 // no break
4485 case Value::V_ARRAY: {
4486 size_t n_value_comps = value->get_nof_comps();
4487 Ttcn::ArrayDimension *dim = u.array.dimension;
4488 if (!value->is_indexed()) {
4489 // Value-list notation.
4490 if (!dim->get_has_error()) {
4491 size_t array_size = dim->get_size();
4492 if (array_size != n_value_comps)
4493 value->error("Too %s elements in the array value: %lu was "
4494 "expected instead of %lu",
4495 array_size > n_value_comps ? "few" : "many",
4496 (unsigned long)array_size,
4497 (unsigned long)n_value_comps);
4498 }
4499 for (size_t i = 0; i < n_value_comps; i++) {
4500 Error_Context cntxt(this, "In array element %lu",
4501 (unsigned long)(i + 1));
4502 Value *v_comp = value->get_comp_byIndex(i);
4503 v_comp->set_my_governor(u.array.element_type);
4504 if (v_comp->get_valuetype() == Value::V_NOTUSED) {
4505 if (!incomplete_allowed)
4506 v_comp->error("Not used symbol `-' is not allowed in this "
4507 "context");
4508 } else {
4509 u.array.element_type->chk_this_value_ref(v_comp);
4510 self_ref |= u.array.element_type->chk_this_value(v_comp, lhs,
4511 expected_value, incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK,
4512 implicit_omit);
4513 }
4514 }
4515 } else {
4516 // Indexed-list notation.
4517 bool array_size_known = !dim->get_has_error();
4518 bool check_holes = array_size_known
4519 && expected_value == EXPECTED_CONSTANT;
4520 size_t array_size = 0;
4521 if (array_size_known) array_size = dim->get_size();
4522 map<Int, Int> index_map;
4523 for (size_t i = 0; i < n_value_comps; i++) {
4524 Error_Context cntxt(this, "In array element #%lu",
4525 (unsigned long)(i + 1));
4526 Value *val = value->get_comp_byIndex(i);
4527 Value *index = value->get_index_byIndex(i);
4528 dim->chk_index(index, expected_value);
4529 if (index->get_value_refd_last()->get_valuetype() == Value::V_INT) {
4530 const int_val_t *index_int = index->get_value_refd_last()
4531 ->get_val_Int();
4532 if (*index_int > INT_MAX) {
4533 index->error("An integer value less than `%d' was expected for "
4534 "indexing type `%s' instead of `%s'", INT_MAX,
4535 get_typename().c_str(),
4536 (index_int->t_str()).c_str());
4537 index->set_valuetype(Value::V_ERROR);
4538 check_holes = false;
4539 } else {
4540 // Index overflows/underflows are already checked by
4541 // ArrayDimensions::chk_index() at this point. The only thing
4542 // we need to check is the uniqueness of constant index values.
4543 Int index_val = index_int->get_val();
4544 if (index_map.has_key(index_val)) {
4545 index->error("Duplicate index value `%s' for components `%s' "
4546 "and `%s'", Int2string(index_val).c_str(),
4547 Int2string((Int)i + 1).c_str(),
4548 Int2string(*index_map[index_val]).c_str());
4549 index->set_valuetype(Value::V_ERROR);
4550 check_holes = false;
4551 } else {
4552 index_map.add(index_val, new Int((Int)i + 1));
4553 }
4554 }
4555 } else {
4556 check_holes = false;
4557 }
4558 val->set_my_governor(u.array.element_type);
4559 u.array.element_type->chk_this_value_ref(val);
4560 self_ref |= u.array.element_type->chk_this_value(val, lhs, expected_value,
4561 incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
4562 }
4563 if (check_holes) {
4564 if (index_map.size() < array_size) {
4565 // It's a constant array assigned with constant index values. The
4566 // # of constant index values doesn't reach the size of the array.
4567 value->error("It's not allowed to create hole(s) in constant "
4568 "values");
4569 value->set_valuetype(Value::V_ERROR);
4570 }
4571 }
4572 for (size_t i = 0; i < index_map.size(); i++)
4573 delete index_map.get_nth_elem(i);
4574 index_map.clear();
4575 }
4576 break; }
4577 default:
4578 value->error("array value was expected");
4579 value->set_valuetype(Value::V_ERROR);
4580 break;
4581 }
4582
4583 return self_ref;
4584 }
4585
4586 bool Type::chk_this_value_Signature(Value *value, Common::Assignment *lhs,
4587 expected_value_t expected_value,
4588 namedbool incomplete_allowed)
4589 {
4590 bool self_ref = false;
4591 switch(value->get_valuetype()) {
4592 case Value::V_SEQOF:
4593 value->set_valuetype(Value::V_SEQ);
4594 // no break
4595 case Value::V_SEQ:{
4596 map<string, NamedValue> comp_map;
4597 // it is set to false if we have lost the ordering
4598 bool in_synch = true;
4599 size_t n_type_comps = get_nof_comps();
4600 size_t n_value_comps = value->get_nof_comps();
4601 // for incomplete values
4602 CompField *last_cf = 0;
4603 size_t next_index = 0;
4604 for (size_t v_i = 0; v_i < n_value_comps; v_i++) {
4605 NamedValue *nv = value->get_se_comp_byIndex(v_i);
4606 const Identifier& value_id = nv->get_name();
4607 const string& value_name = value_id.get_name();
4608 const char *value_dispname_str = value_id.get_dispname().c_str();
4609 if (!has_comp_withName(value_id)) {
4610 nv->error("Reference to non-existent parameter `%s' in signature value for "
4611 "type `%s'", value_dispname_str, get_typename().c_str());
4612 in_synch = false;
4613 continue;
4614 } else if (comp_map.has_key(value_name)) {
4615 nv->error("Duplicate signature parameter `%s'", value_dispname_str);
4616 comp_map[value_name]->note("Parameter `%s' is already given here",
4617 value_dispname_str);
4618 in_synch = false;
4619 } else comp_map.add(value_name, nv);
4620 CompField *cf = get_comp_byName(value_id);
4621 // check the ordering of fields
4622 if (in_synch) {
4623 if (incomplete_allowed) {
4624 bool found = false;
4625 for (size_t i = next_index; i < n_type_comps; i++) {
4626 CompField *cf2 = get_comp_byIndex(i);
4627 if (value_name == cf2->get_name().get_name()) {
4628 last_cf = cf2;
4629 next_index = i + 1;
4630 found = true;
4631 break;
4632 }
4633 }
4634 if (!found) {
4635 nv->error("Field `%s' cannot appear after parameter `%s' in signature "
4636 "value", value_dispname_str,
4637 last_cf->get_name().get_dispname().c_str());
4638 in_synch = false;
4639 }
4640 } else {
4641 // the value must be complete
4642 CompField *cf2 = get_comp_byIndex(v_i);
4643 if (cf2 != cf) {
4644 nv->error("Unexpected field `%s' in record value, "
4645 "expecting `%s'", value_dispname_str,
4646 cf2->get_name().get_dispname().c_str());
4647 in_synch = false;
4648 }
4649 }
4650 }
4651 Type *type = cf->get_type();
4652 Value *comp_value = nv->get_value();
4653 comp_value->set_my_governor(type);
4654 Error_Context cntxt(nv, "In value for signature parameter `%s'",
4655 value_dispname_str);
4656 type->chk_this_value_ref(comp_value);
4657 self_ref |= type->chk_this_value(comp_value, lhs, expected_value,
4658 INCOMPLETE_NOT_ALLOWED,
4659 cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK);
4660 }
4661 if (!incomplete_allowed) {
4662 for (size_t i = 0; i < u.signature.parameters->get_nof_in_params(); i++) {
4663 const Identifier& id = get_comp_byIndex(i)->get_name(); //u.signature.parameters->get_param_byIndex(n)
4664 if (!comp_map.has_key(id.get_name()) && SignatureParam::PARAM_OUT != u.signature.parameters->get_in_param_byIndex(i)->get_direction()) {
4665 value->error("Field `%s' is missing from signature value",
4666 id.get_dispname().c_str());
4667 }
4668 }
4669 }
4670 comp_map.clear();
4671 break;}
4672 default:
4673 value->error("Signature value was expected for type `%s'",
4674 get_fullname().c_str());
4675 value->set_valuetype(Value::V_ERROR);
4676 break;
4677 }
4678
4679 return self_ref;
4680 }
4681
4682 /** \todo enhance to handle mtc, system, etc. */
4683 void Type::chk_this_value_Component(Value *value)
4684 {
4685 switch (value->get_valuetype()) {
4686 case Value::V_TTCN3_NULL:
4687 value->set_valuetype_COMP_NULL();
4688 break;
4689 case Value::V_EXPR:
4690 if (value->get_optype() == Value::OPTYPE_COMP_NULL)
4691 break; // set_valuetype_COMP_NULL was called already
4692 // no break
4693 default:
4694 value->error("component reference value was expected");
4695 value->set_valuetype(Value::V_ERROR);
4696 break;
4697 }
4698 }
4699
4700 void Type::chk_this_value_FAT(Value *value)
4701 {
4702 switch (value->get_valuetype()) {
4703 case Value::V_TTCN3_NULL:
4704 value->set_valuetype(Value::V_FAT_NULL);
4705 return;
4706 case Value::V_REFER:
4707 // see later
4708 break;
4709 case Value::V_FUNCTION:
4710 case Value::V_ALTSTEP:
4711 case Value::V_TESTCASE:
4712 case Value::V_FAT_NULL:
4713 // This function (chk_this_value_FAT) might have transformed the value
4714 // from V_REFER or V_TTCN3_NULL to one of these. Return now,
4715 // otherwise spurious errors are generated.
4716 return;
4717 default:
4718 switch (typetype) {
4719 case T_FUNCTION:
4720 value->error("Reference to a function or external function was "
4721 "expected");
4722 break;
4723 case T_ALTSTEP:
4724 value->error("Reference to an altstep was expected");
4725 break;
4726 case T_TESTCASE:
4727 value->error("Reference to a testcase was expected");
4728 break;
4729 default:
4730 FATAL_ERROR("Type::chk_this_value_FAT()");
4731 }
4732 value->set_valuetype(Value::V_ERROR);
4733 return;
4734 } // switch valuetype
4735
4736 // Here value->valuetype is V_REFER
4737 Assignment *t_ass = value->get_refered()->get_refd_assignment(false);
4738 if (!t_ass) {
4739 value->set_valuetype(Value::V_ERROR);
4740 return;
4741 }
4742 t_ass->chk();
4743 // check whether refers() points to the right definition
4744 Assignment::asstype_t t_asstype = t_ass->get_asstype();
4745 switch (typetype) {
4746 case T_FUNCTION:
4747 switch (t_asstype) {
4748 case Assignment::A_FUNCTION:
4749 case Assignment::A_FUNCTION_RVAL:
4750 case Assignment::A_FUNCTION_RTEMP:
4751 case Assignment::A_EXT_FUNCTION:
4752 case Assignment::A_EXT_FUNCTION_RVAL:
4753 case Assignment::A_EXT_FUNCTION_RTEMP:
4754 value->set_valuetype(Value::V_FUNCTION, t_ass);
4755 break;
4756 default:
4757 value->error("Reference to a function or external function was "
4758 "expected instead of %s", t_ass->get_description().c_str());
4759 value->set_valuetype(Value::V_ERROR);
4760 return;
4761 }
4762 break;
4763 case T_ALTSTEP:
4764 if (t_ass->get_asstype() == Assignment::A_ALTSTEP) {
4765 value->set_valuetype(Value::V_ALTSTEP, t_ass);
4766 break;
4767 } else {
4768 value->error("Reference to an altstep was expected instead of %s",
4769 t_ass->get_description().c_str());
4770 value->set_valuetype(Value::V_ERROR);
4771 return;
4772 }
4773 case T_TESTCASE:
4774 if (t_ass->get_asstype() == Assignment::A_TESTCASE) {
4775 value->set_valuetype(Value::V_TESTCASE, t_ass);
4776 break;
4777 } else {
4778 value->error("Reference to a testcase was expected instead of %s",
4779 t_ass->get_description().c_str());
4780 value->set_valuetype(Value::V_ERROR);
4781 return;
4782 }
4783 default:
4784 FATAL_ERROR("Type::chk_this_value_FAT()");
4785 }
4786 // comparison of formal parameter lists
4787 {
4788 Error_Context cntxt(value, "In comparing formal parameter lists of "
4789 "type `%s' and %s", get_typename().c_str(),
4790 t_ass->get_description().c_str());
4791 u.fatref.fp_list->chk_compatibility(t_ass->get_FormalParList(),
4792 get_typename().c_str());
4793 }
4794 // comparison of 'runs on' clauses
4795 Type *t_runs_on_type = t_ass->get_RunsOnType();
4796 if (t_runs_on_type) {
4797 if (u.fatref.runs_on.self) {
4798 if (u.fatref.runs_on.ref) {
4799 FATAL_ERROR("Type::chk_this_value_FAT()");
4800 } else { // "runs on self" case
4801 // check against the runs on component type of the scope of the value
4802 Scope* value_scope = value->get_my_scope();
4803 if (!value_scope) FATAL_ERROR("Type::chk_this_value_FAT()");
4804 Ttcn::RunsOnScope *t_ros = value_scope->get_scope_runs_on();
4805 if (t_ros) {
4806 Type *scope_comptype = t_ros->get_component_type();
4807 if (!t_runs_on_type->is_compatible(scope_comptype, NULL)) {
4808 value->error("Runs on clause mismatch: type `%s' has a "
4809 "'runs on self' clause and the current scope expects component "
4810 "type `%s', but %s runs on `%s'", get_typename().c_str(),
4811 scope_comptype->get_typename().c_str(),
4812 t_ass->get_description().c_str(),
4813 t_runs_on_type->get_typename().c_str());
4814 }
4815 } else { // does not have 'runs on' clause
4816 // if the value's scope is a component body then check the runs on
4817 // compatibility using this component type as the scope
4818 ComponentTypeBody* ct_body =
4819 dynamic_cast<ComponentTypeBody*>(value_scope);
4820 if (ct_body) {
4821 if (!t_runs_on_type->is_compatible(ct_body->get_my_type(), NULL)) {
4822 value->error("Runs on clause mismatch: type `%s' has a "
4823 "'runs on self' clause and the current component definition "
4824 "is of type `%s', but %s runs on `%s'",
4825 get_typename().c_str(),
4826 ct_body->get_my_type()->get_typename().c_str(),
4827 t_ass->get_description().c_str(),
4828 t_runs_on_type->get_typename().c_str());
4829 }
4830 } else {
4831 value->error("Type `%s' has a 'runs on self' clause and the "
4832 "current scope does not have a 'runs on' clause, "
4833 "but %s runs on `%s'", get_typename().c_str(),
4834 t_ass->get_description().c_str(),
4835 t_runs_on_type->get_typename().c_str());
4836 }
4837 }
4838 }
4839 } else {
4840 if (u.fatref.runs_on.ref) {
4841 if (u.fatref.runs_on.type &&
4842 !t_runs_on_type->is_compatible(u.fatref.runs_on.type, NULL)) {
4843 value->error("Runs on clause mismatch: type `%s' expects component "
4844 "type `%s', but %s runs on `%s'", get_typename().c_str(),
4845 u.fatref.runs_on.type->get_typename().c_str(),
4846 t_ass->get_description().c_str(),
4847 t_runs_on_type->get_typename().c_str());
4848 }
4849 } else {
4850 value->error("Type `%s' does not have 'runs on' clause, but %s runs "
4851 "on `%s'", get_typename().c_str(), t_ass->get_description().c_str(),
4852 t_runs_on_type->get_typename().c_str());
4853 }
4854 }
4855 }
4856 if (typetype == T_TESTCASE) {
4857 // comparison of system clauses
4858 Ttcn::Def_Testcase *t_testcase = dynamic_cast<Ttcn::Def_Testcase*>(t_ass);
4859 if (!t_testcase) FATAL_ERROR("Type::chk_this_value_FAT()");
4860 Type *t_system_type = t_testcase->get_SystemType();
4861 // if the system clause is missing we shall examine the component type
4862 // that is given in the 'runs on' clause
4863 if (!t_system_type) t_system_type = t_runs_on_type;
4864 Type *my_system_type =
4865 u.fatref.system.ref ? u.fatref.system.type : u.fatref.runs_on.type;
4866 if (t_system_type && my_system_type &&
4867 !t_system_type->is_compatible(my_system_type, NULL)) {
4868 value->error("System clause mismatch: testcase type `%s' expects "
4869 "component type `%s', but %s has `%s'", get_typename().c_str(),
4870 my_system_type->get_typename().c_str(),
4871 t_ass->get_description().c_str(),
4872 t_system_type->get_typename().c_str());
4873 }
4874 } else if (typetype == T_FUNCTION) {
4875 // comparison of return types
4876 bool t_returns_template = false;
4877 switch (t_asstype) {
4878 case Assignment::A_FUNCTION:
4879 case Assignment::A_EXT_FUNCTION:
4880 if (u.fatref.return_type) {
4881 value->error("Type `%s' expects a function or external function "
4882 "that returns a %s of type `%s', but %s does not have return type",
4883 get_typename().c_str(),
4884 u.fatref.returns_template ? "template" : "value",
4885 u.fatref.return_type->get_typename().c_str(),
4886 t_ass->get_description().c_str());
4887 }
4888 break;
4889 case Assignment::A_FUNCTION_RTEMP:
4890 case Assignment::A_EXT_FUNCTION_RTEMP: {
4891 // comparison of template restrictions
4892 Ttcn::Def_Function_Base* dfb =
4893 dynamic_cast<Ttcn::Def_Function_Base*>(t_ass);
4894 if (!dfb) FATAL_ERROR("Type::chk_this_value_FAT()");
4895 template_restriction_t refd_tr = dfb->get_template_restriction();
4896 if (refd_tr!=u.fatref.template_restriction) {
4897 value->error("Type `%s' expects a function or external function "
4898 "that returns a template with %s restriction, "
4899 "but %s returns a template with %s restriction",
4900 get_typename().c_str(),
4901 u.fatref.template_restriction==TR_NONE ? "no" :
4902 Template::get_restriction_name(u.fatref.template_restriction),
4903 t_ass->get_description().c_str(),
4904 refd_tr==TR_NONE ? "no" : Template::get_restriction_name(refd_tr));
4905 }
4906 }
4907 t_returns_template = true;
4908 // no break
4909 case Assignment::A_FUNCTION_RVAL:
4910 case Assignment::A_EXT_FUNCTION_RVAL:
4911 if (u.fatref.return_type) {
4912 Type *t_return_type = t_ass->get_Type();
4913 if (!u.fatref.return_type->is_identical(t_return_type)) {
4914 value->error("Return type mismatch: type `%s' expects a function "
4915 "or external function that returns a %s of type `%s', but %s "
4916 "returns a %s of type `%s'", get_typename().c_str(),
4917 u.fatref.returns_template ? "template" : "value",
4918 u.fatref.return_type->get_typename().c_str(),
4919 t_ass->get_description().c_str(),
4920 t_returns_template ? "template" : "value",
4921 t_return_type->get_typename().c_str());
4922 } else if (u.fatref.return_type->get_sub_type() && t_return_type->get_sub_type() &&
4923 (u.fatref.return_type->get_sub_type()->get_subtypetype()==t_return_type->get_sub_type()->get_subtypetype()) &&
4924 (!u.fatref.return_type->get_sub_type()->is_compatible(t_return_type->get_sub_type()))) {
4925 // TODO: maybe equivalence should be checked, or maybe that is too strict
4926 value->error("Return type subtype mismatch: subtype %s has no common value with subtype %s",
4927 u.fatref.return_type->get_sub_type()->to_string().c_str(),
4928 t_return_type->get_sub_type()->to_string().c_str());
4929 } else if (u.fatref.returns_template != t_returns_template) {
4930 value->error("Type `%s' expects a function or external function "
4931 "that returns a %s of type `%s', but %s returns a %s",
4932 get_typename().c_str(),
4933 u.fatref.returns_template ? "template" : "value",
4934 u.fatref.return_type->get_typename().c_str(),
4935 t_ass->get_description().c_str(),
4936 t_returns_template ? "template" : "value");
4937 }
4938 } else {
4939 value->error("Type `%s' expects a function or external function "
4940 "without return type, but %s returns a %s of type `%s'",
4941 get_typename().c_str(), t_ass->get_description().c_str(),
4942 t_returns_template ? "template" : "value",
4943 t_ass->get_Type()->get_typename().c_str());
4944 }
4945 break;
4946 default:
4947 FATAL_ERROR("Type::chk_this_value_FAT()");
4948 }
4949 }
4950 }
4951
4952 void Type::chk_this_template_length_restriction(Template *t)
4953 {
4954 Ttcn::LengthRestriction *lr = t->get_length_restriction();
4955 if (!lr) FATAL_ERROR("Type::chk_this_template_length_restriction()");
4956 // first check the length restriction itself
4957 lr->chk(EXPECTED_DYNAMIC_VALUE);
4958 if (is_ref()) {
4959 /** \todo check lr against the length subtype constraint of this */
4960 get_type_refd()->chk_this_template_length_restriction(t);
4961 return;
4962 }
4963 typetype_t tt = get_typetype_ttcn3(typetype);
4964 switch (tt) {
4965 case T_ERROR:
4966 case T_PORT:
4967 // return silently, the type of the template is erroneous anyway
4968 return;
4969 case T_ARRAY:
4970 lr->chk_array_size(u.array.dimension);
4971 /* no break */
4972 case T_BSTR:
4973 case T_HSTR:
4974 case T_OSTR:
4975 case T_CSTR:
4976 case T_USTR:
4977 case T_SETOF:
4978 case T_SEQOF:
4979 // length restriction is allowed for these types
4980 break;
4981 default:
4982 lr->error("Length restriction cannot be used in a template of type `%s'",
4983 get_typename().c_str());
4984 return;
4985 }
4986 // check whether the number of elements in t is in accordance with lr
4987 Template *t_last = t->get_template_refd_last();
4988 switch (t_last->get_templatetype()) {
4989 case Ttcn::Template::OMIT_VALUE:
4990 lr->error("Length restriction cannot be used with omit value");
4991 break;
4992 case Ttcn::Template::SPECIFIC_VALUE: {
4993 Value *v_last = t_last->get_specific_value()->get_value_refd_last();
4994 switch (v_last->get_valuetype()) {
4995 case Value::V_BSTR:
4996 if (tt == T_BSTR)
4997 lr->chk_nof_elements(v_last->get_val_strlen(), false, *t, "string");
4998 break;
4999 case Value::V_HSTR:
5000 if (tt == T_HSTR)
5001 lr->chk_nof_elements(v_last->get_val_strlen(), false, *t, "string");
5002 break;
5003 case Value::V_OSTR:
5004 if (tt == T_OSTR)
5005 lr->chk_nof_elements(v_last->get_val_strlen(), false, *t, "string");
5006 break;
5007 case Value::V_CSTR:
5008 if (tt == T_CSTR || tt == T_USTR)
5009 lr->chk_nof_elements(v_last->get_val_strlen(), false, *t, "string");
5010 break;
5011 case Value::V_USTR:
5012 if (tt == T_USTR)
5013 lr->chk_nof_elements(v_last->get_val_strlen(), false, *t, "string");
5014 break;
5015 case Value::V_SEQOF:
5016 if (tt == T_SEQOF)
5017 lr->chk_nof_elements(v_last->get_nof_comps(), false, *t, "value");
5018 break;
5019 case Value::V_SETOF:
5020 if (tt == T_SETOF)
5021 lr->chk_nof_elements(v_last->get_nof_comps(), false, *t, "value");
5022 break;
5023 // note: do not check array values
5024 // they are already verified against the array size
5025 case Value::V_OMIT:
5026 lr->error("Length restriction cannot be used with omit value");
5027 default:
5028 // we cannot verify anything on other value types
5029 // they are either correct or not applicable to the type
5030 break;
5031 }
5032 break; }
5033 case Ttcn::Template::TEMPLATE_LIST:
5034 if (tt == T_SEQOF || tt == T_SETOF)
5035 lr->chk_nof_elements(t_last->get_nof_comps_not_anyornone(),
5036 t_last->temps_contains_anyornone_symbol(), *t, "template");
5037 // note: do not check array templates
5038 // they are already verified against the array size
5039 break;
5040 case Ttcn::Template::SUPERSET_MATCH:
5041 if (tt == T_SETOF)
5042 lr->chk_nof_elements(t_last->get_nof_comps_not_anyornone(), true,
5043 *t, "template");
5044 break;
5045 case Ttcn::Template::BSTR_PATTERN:
5046 if (tt == T_BSTR)
5047 lr->chk_nof_elements(t_last->get_min_length_of_pattern(),
5048 t_last->pattern_contains_anyornone_symbol(), *t, "string");
5049 break;
5050 case Ttcn::Template::HSTR_PATTERN:
5051 if (tt == T_HSTR)
5052 lr->chk_nof_elements(t_last->get_min_length_of_pattern(),
5053 t_last->pattern_contains_anyornone_symbol(), *t, "string");
5054 break;
5055 case Ttcn::Template::OSTR_PATTERN:
5056 if (tt == T_OSTR)
5057 lr->chk_nof_elements(t_last->get_min_length_of_pattern(),
5058 t_last->pattern_contains_anyornone_symbol(), *t, "string");
5059 break;
5060 case Ttcn::Template::CSTR_PATTERN:
5061 if (tt == T_CSTR || tt == T_USTR)
5062 lr->chk_nof_elements(t_last->get_min_length_of_pattern(),
5063 t_last->pattern_contains_anyornone_symbol(), *t, "string");
5064 break;
5065 default:
5066 // We cannot verify anything on other matching mechanisms.
5067 // They are either correct or not applicable to the type.
5068 break;
5069 }
5070 }
5071
5072 void Type::chk_this_template_ref(Template *t)
5073 {
5074 switch (t->get_templatetype()) {
5075 case Ttcn::Template::SPECIFIC_VALUE: {
5076 // if (t->get_templatetype() != Ttcn::Template::SPECIFIC_VALUE) return;
5077 Value *v = t->get_specific_value();
5078 chk_this_value_ref(v);
5079 switch (v->get_valuetype()) {
5080 case Value::V_REFD: {
5081 // Do not check the actual parameter list of the reference yet to avoid
5082 // endless recursion in case of embedded circular references.
5083 // The parameter lists will be verified later.
5084 Assignment *ass = v->get_reference()->get_refd_assignment(false);
5085 if (ass) {
5086 switch (ass->get_asstype()) {
5087 case Assignment::A_VAR_TEMPLATE: {
5088 Type* type = ass->get_Type();
5089 switch (type->typetype) {
5090 case T_BSTR:
5091 case T_BSTR_A:
5092 case T_HSTR:
5093 case T_OSTR:
5094 case T_CSTR:
5095 case T_USTR:
5096 case T_UTF8STRING:
5097 case T_NUMERICSTRING:
5098 case T_PRINTABLESTRING:
5099 case T_TELETEXSTRING:
5100 case T_VIDEOTEXSTRING:
5101 case T_IA5STRING:
5102 case T_GRAPHICSTRING:
5103 case T_VISIBLESTRING:
5104 case T_GENERALSTRING:
5105 case T_UNIVERSALSTRING:
5106 case T_BMPSTRING:
5107 case T_UTCTIME:
5108 case T_GENERALIZEDTIME:
5109 case T_OBJECTDESCRIPTOR: {
5110 // TR 921 (indexing of template strings)
5111 Ttcn::FieldOrArrayRefs *subrefs = v->get_reference()
5112 ->get_subrefs();
5113 if (!subrefs) break;
5114 size_t nof_subrefs = subrefs->get_nof_refs();
5115 if (nof_subrefs > 0) {
5116 Ttcn::FieldOrArrayRef *last_ref = subrefs
5117 ->get_ref(nof_subrefs - 1);
5118 if (last_ref->get_type() == Ttcn::FieldOrArrayRef::ARRAY_REF) {
5119 t->error("Reference to %s can not be indexed",
5120 (ass->get_description()).c_str());
5121 t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
5122 return;
5123 }
5124 }
5125 break; }
5126 default:
5127 break;
5128 }
5129 }
5130 case Assignment::A_MODULEPAR_TEMP:
5131 case Assignment::A_TEMPLATE:
5132 case Assignment::A_PAR_TEMPL_IN:
5133 case Assignment::A_PAR_TEMPL_OUT:
5134 case Assignment::A_PAR_TEMPL_INOUT:
5135 case Assignment::A_FUNCTION_RTEMP:
5136 case Assignment::A_EXT_FUNCTION_RTEMP:
5137 t->set_templatetype(Ttcn::Template::TEMPLATE_REFD);
5138 default:
5139 break;
5140 }
5141 } else t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
5142 break; }
5143 case Value::V_INVOKE: {
5144 Type *t2 = v->get_invoked_type(Type::EXPECTED_TEMPLATE);
5145 if(t2 && t2->get_type_refd_last()->get_returns_template())
5146 t->set_templatetype(Ttcn::Template::TEMPLATE_INVOKE);
5147 break; }
5148 default:
5149 break;
5150 }
5151 break;
5152 }
5153 case Ttcn::Template::TEMPLATE_REFD: {
5154 // Do not check the actual parameter list of the reference yet to avoid
5155 // endless recursion in case of embedded circular references.
5156 // The parameter lists will be verified later.
5157 Assignment *ass = t->get_reference()->get_refd_assignment(false);
5158 if (ass) {
5159 switch (ass->get_asstype()) {
5160 case Assignment::A_VAR_TEMPLATE: {
5161 Type* type = ass->get_Type();
5162 switch (type->typetype) {
5163 case T_BSTR:
5164 case T_BSTR_A:
5165 case T_HSTR:
5166 case T_OSTR:
5167 case T_CSTR:
5168 case T_USTR:
5169 case T_UTF8STRING:
5170 case T_NUMERICSTRING:
5171 case T_PRINTABLESTRING:
5172 case T_TELETEXSTRING:
5173 case T_VIDEOTEXSTRING:
5174 case T_IA5STRING:
5175 case T_GRAPHICSTRING:
5176 case T_VISIBLESTRING:
5177 case T_GENERALSTRING:
5178 case T_UNIVERSALSTRING:
5179 case T_BMPSTRING:
5180 case T_UTCTIME:
5181 case T_GENERALIZEDTIME:
5182 case T_OBJECTDESCRIPTOR: {
5183 // TR 921 (indexing of template strings)
5184 Ttcn::FieldOrArrayRefs *subrefs = t->get_reference()
5185 ->get_subrefs();
5186 if (!subrefs) break;
5187 size_t nof_subrefs = subrefs->get_nof_refs();
5188 if (nof_subrefs > 0) {
5189 Ttcn::FieldOrArrayRef *last_ref = subrefs
5190 ->get_ref(nof_subrefs - 1);
5191 if (last_ref->get_type() == Ttcn::FieldOrArrayRef::ARRAY_REF) {
5192 t->error("Reference to %s can not be indexed",
5193 (ass->get_description()).c_str());
5194 t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
5195 return;
5196 }
5197 }
5198 break; }
5199 default:
5200 break;
5201 }
5202 }
5203 case Assignment::A_MODULEPAR_TEMP:
5204 case Assignment::A_TEMPLATE:
5205 case Assignment::A_PAR_TEMPL_IN:
5206 case Assignment::A_PAR_TEMPL_OUT:
5207 case Assignment::A_PAR_TEMPL_INOUT:
5208 case Assignment::A_FUNCTION_RTEMP:
5209 case Assignment::A_EXT_FUNCTION_RTEMP:
5210 t->set_templatetype(Ttcn::Template::TEMPLATE_REFD);
5211 default:
5212 break;
5213 }
5214 } else t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
5215 }
5216 break;
5217 default:
5218 return;
5219 }
5220 }
5221
5222 bool Type::chk_this_template_ref_pard(Ttcn::Ref_pard* ref_pard, Common::Assignment* lhs)
5223 {
5224 // Check if the reference on the left hand side of the assignment can be found
5225 // among the parameters
5226 Ttcn::ActualParList* par_list = ref_pard->get_parlist();
5227 if (par_list) {
5228 size_t nof_pars = par_list->get_nof_pars();
5229 for (size_t i = 0; i < nof_pars; ++i) {
5230 Ttcn::ActualPar* par = par_list->get_par(i);
5231 Ttcn::Ref_base* par_ref = 0;
5232 switch(par->get_selection()) {
5233 case Ttcn::ActualPar::AP_TEMPLATE: {
5234 Ttcn::TemplateInstance* temp_ins = par->get_TemplateInstance();
5235 Ttcn::Template* temp = temp_ins->get_Template();
5236 if (temp->get_templatetype() == Ttcn::Template::TEMPLATE_REFD) {
5237 par_ref = temp->get_reference();
5238 }
5239 break;
5240 }
5241 case Ttcn::ActualPar::AP_REF: {
5242 par_ref = par->get_Ref();
5243 break;
5244 }
5245 default:
5246 break;
5247 }
5248
5249 if (par_ref != 0) {
5250 Common::Assignment* ass = par_ref->get_refd_assignment(true); // also check parameters if there are any
5251 if (ass == lhs)
5252 return true;
5253
5254 // In case a parameter is another function call / parametrised template
5255 // check their parameters as well
5256 if (ass->get_asstype() == Assignment::A_FUNCTION_RTEMP ||
5257 ass->get_asstype() == Assignment::A_EXT_FUNCTION_RTEMP ||
5258 ass->get_asstype() == Assignment::A_TEMPLATE) {
5259 ref_pard = dynamic_cast<Ttcn::Ref_pard*>(par_ref);
5260 if (ref_pard && chk_this_template_ref_pard(ref_pard, lhs))
5261 return true;
5262 }
5263 }
5264 }
5265 }
5266 return false;
5267 }
5268
5269 bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed,
5270 namedbool allow_omit, namedbool allow_any_or_omit, namedbool sub_chk,
5271 namedbool implicit_omit, Common::Assignment *lhs)
5272 {
5273 bool self_ref = false;
5274 if (!allow_omit && t->get_template_refd_last()->get_templatetype() ==
5275 Ttcn::Template::OMIT_VALUE) {
5276 t->error("`omit' value is not allowed in this context");
5277 }
5278 if (!allow_any_or_omit && t->get_template_refd_last()->get_templatetype() ==
5279 Ttcn::Template::ANY_OR_OMIT) {
5280 t->warning("Using `*' for mandatory field");
5281 }
5282
5283 Ttcn::Template::templatetype_t temptype = t->get_templatetype();
5284 switch(temptype) {
5285 case Ttcn::Template::TEMPLATE_ERROR:
5286 break;
5287 case Ttcn::Template::TEMPLATE_NOTUSED:
5288 case Ttcn::Template::OMIT_VALUE:
5289 case Ttcn::Template::ANY_VALUE:
5290 case Ttcn::Template::ANY_OR_OMIT: {
5291 Type *type=get_type_refd_last();
5292 if (type->get_typetype() == T_SIGNATURE)
5293 t->error("Generic wildcard `%s' cannot be used for signature `%s'",
5294 t->get_templatetype_str(), type->get_fullname().c_str());
5295 break;}
5296 case Ttcn::Template::VALUE_LIST_ALL_FROM:
5297 case Ttcn::Template::ALL_FROM: {
5298 Ttcn::Template *af = t->get_all_from();
5299 switch (af->get_templatetype()) {
5300 case Ttcn::Template::SPECIFIC_VALUE: {
5301 Value *v = af->get_specific_value();
5302 v->set_lowerid_to_ref();
5303 Reference *ref = v->get_reference();
5304 Assignment *ass = ref->get_refd_assignment(true); // also check parameters if there are any
5305 if (!ass) break; // probably erroneous
5306 //warning("asstype %d", ass->get_asstype());
5307
5308 switch (ass->get_asstype()) {
5309 case Assignment::A_VAR:
5310 case Assignment::A_PAR_VAL_IN:
5311 case Assignment::A_PAR_VAL_INOUT:
5312 case Assignment::A_MODULEPAR:
5313 case Assignment::A_CONST:
5314 case Assignment::A_MODULEPAR_TEMP:
5315 break; // acceptable
5316 case Assignment::A_VAR_TEMPLATE:
5317 case Assignment::A_PAR_TEMPL_IN:
5318 case Assignment::A_PAR_TEMPL_INOUT:
5319 if (ass == lhs)
5320 self_ref = true;
5321 break; // acceptable
5322 case Assignment::A_FUNCTION_RVAL:
5323 case Assignment::A_EXT_FUNCTION_RVAL:
5324 case Assignment::A_FUNCTION_RTEMP:
5325 case Assignment::A_EXT_FUNCTION_RTEMP:
5326 case Assignment::A_TEMPLATE: {
5327 Ttcn::Ref_pard* ref_pard = dynamic_cast<Ttcn::Ref_pard*>(ref);
5328 if (ref_pard)
5329 self_ref |= chk_this_template_ref_pard(ref_pard, lhs);
5330 break; // acceptable
5331 }
5332 default:
5333 error("A %s cannot be used as the target of `all from'",
5334 ass->get_assname());
5335 break;
5336 }
5337 //self_ref |= chk_this_value(v, lhs, EXPECTED_TEMPLATE, incomplete_allowed,
5338 // allow_omit, sub_chk, implicit_omit, NOT_STR_ELEM /* ?? */);
5339 break; }
5340
5341 default:
5342 error("The target of an 'all from' must be a specific value template, not a %s",
5343 af->get_templatetype_str());
5344 break;
5345 }
5346
5347 break; }
5348 case Ttcn::Template::VALUE_LIST:
5349 case Ttcn::Template::COMPLEMENTED_LIST: {
5350 size_t nof_comps = t->get_nof_comps();
5351 for (size_t i = 0; i < nof_comps; i++) {
5352 Template* t_comp = t->get_temp_byIndex(i);
5353 Error_Context cntxt(t, "In list item %lu", (unsigned long) (i + 1));
5354 t_comp->set_my_governor(this);
5355 chk_this_template_ref(t_comp);
5356 self_ref |= chk_this_template_generic(t_comp, INCOMPLETE_NOT_ALLOWED,
5357 allow_omit, ANY_OR_OMIT_ALLOWED, sub_chk, implicit_omit, lhs);
5358 if(temptype==Ttcn::Template::COMPLEMENTED_LIST &&
5359 t_comp->get_template_refd_last()->get_templatetype() ==
5360 Ttcn::Template::ANY_OR_OMIT)
5361 t_comp->warning("`*' in complemented list."
5362 " This template will not match anything");
5363 }
5364 break;}
5365 case Ttcn::Template::SPECIFIC_VALUE: {
5366 Value *v = t->get_specific_value();
5367 v->set_my_governor(this);
5368 self_ref |= chk_this_value(v, lhs, EXPECTED_TEMPLATE, incomplete_allowed,
5369 allow_omit, SUB_CHK);
5370 break; }
5371 case Ttcn::Template::TEMPLATE_INVOKE: {
5372 t->chk_invoke();
5373 Type *governor = t->get_expr_governor(EXPECTED_DYNAMIC_VALUE);
5374 if(!governor)
5375 t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
5376 else if (!is_compatible(governor, NULL)) {
5377 t->error("Type mismatch: a value or template of type `%s' was "
5378 "expected instead of `%s'", get_typename().c_str(),
5379 governor->get_typename().c_str());
5380 t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
5381 }
5382 break; }
5383 case Ttcn::Template::TEMPLATE_REFD:
5384 self_ref = chk_this_refd_template(t, lhs);
5385 break;
5386 default:
5387 self_ref = chk_this_template(t, incomplete_allowed, sub_chk, implicit_omit, lhs);
5388 break;
5389 }
5390 if (t->get_length_restriction()) chk_this_template_length_restriction(t);
5391 if (!allow_omit && t->get_ifpresent())
5392 t->error("`ifpresent' is not allowed here");
5393 if(sub_chk && temptype != Ttcn::Template::PERMUTATION_MATCH) {
5394 /* Note: A "permuation" itself has no type - it is just a fragment. */
5395 if(sub_type!=NULL) sub_type->chk_this_template_generic(t);
5396 }
5397
5398 return self_ref;
5399 }
5400
5401 bool Type::chk_this_refd_template(Template *t, Common::Assignment *lhs)
5402 {
5403 if (t->get_templatetype() != Template::TEMPLATE_REFD) return false;
5404 Reference *ref = t->get_reference();
5405 Assignment *ass = ref->get_refd_assignment();
5406 if (!ass) FATAL_ERROR("Type::chk_this_refd_template()");
5407 ass->chk();
5408
5409 Type *governor = ass->get_Type()
5410 ->get_field_type(ref->get_subrefs(), EXPECTED_DYNAMIC_VALUE);
5411 if (!governor) {
5412 t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
5413 } else {
5414 TypeCompatInfo info(t->get_my_scope()->get_scope_mod(), this, governor,
5415 true, false, true);
5416 if (ref->get_subrefs()) info.set_str2_elem(ref->get_subrefs()->refers_to_string_element());
5417 TypeChain l_chain;
5418 TypeChain r_chain;
5419 if (!is_compatible(governor, &info, &l_chain, &r_chain)) {
5420 Type *type = get_type_refd_last();
5421 switch (type->typetype) {
5422 case T_PORT:
5423 // Port templates do not exist, remain silent.
5424 break;
5425 case T_SIGNATURE:
5426 t->error("Type mismatch: a signature template of type `%s' was "
5427 "expected instead of `%s'", get_typename().c_str(),
5428 governor->get_typename().c_str());
5429 break;
5430 default:
5431 if (info.is_subtype_error()) {
5432 t->error("%s", info.get_subtype_error().c_str());
5433 } else if (!info.is_erroneous()) {
5434 t->error("Type mismatch: a value or template of type `%s' was "
5435 "expected instead of `%s'", get_typename().c_str(),
5436 governor->get_typename().c_str());
5437 } else {
5438 t->error("%s", info.get_error_str_str().c_str());
5439 }
5440 break;
5441 }
5442 t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
5443 } else {
5444 // Detect circular references.
5445 t->get_template_refd_last();
5446
5447 if (info.needs_conversion()) t->set_needs_conversion();
5448 }
5449 }
5450 return (lhs == ass);
5451 }
5452
5453 bool Type::chk_this_template(Template *t, namedbool is_modified, namedbool,
5454 namedbool implicit_omit, Common::Assignment *lhs)
5455 {
5456 bool self_ref = false;
5457 Type *t_last = get_type_refd_last();
5458 t->set_my_governor(t_last);
5459
5460 switch(t_last->typetype) {
5461 case T_ERROR:
5462 break;
5463 case T_NULL:
5464 case T_BOOL:
5465 case T_OID:
5466 case T_ROID:
5467 case T_ANY:
5468 case T_VERDICT:
5469 case T_COMPONENT:
5470 case T_DEFAULT:
5471 t_last->chk_this_template_builtin(t);
5472 break;
5473 case T_BSTR_A:
5474 case T_BSTR:
5475 case T_HSTR:
5476 case T_OSTR:
5477 case T_CSTR:
5478 case T_USTR:
5479 case T_UTF8STRING:
5480 case T_NUMERICSTRING:
5481 case T_PRINTABLESTRING:
5482 case T_TELETEXSTRING:
5483 case T_VIDEOTEXSTRING:
5484 case T_IA5STRING:
5485 case T_GRAPHICSTRING:
5486 case T_VISIBLESTRING:
5487 case T_GENERALSTRING:
5488 case T_UNIVERSALSTRING:
5489 case T_BMPSTRING:
5490 case T_UTCTIME:
5491 case T_GENERALIZEDTIME:
5492 case T_OBJECTDESCRIPTOR:
5493 t_last->chk_this_template_Str(t);
5494 break;
5495 case T_INT:
5496 case T_INT_A:
5497 case T_REAL:
5498 t_last->chk_this_template_Int_Real(t);
5499 break;
5500 case T_ENUM_A:
5501 case T_ENUM_T:
5502 t_last->chk_this_template_Enum(t);
5503 break;
5504 case T_CHOICE_A:
5505 case T_CHOICE_T:
5506 case T_OPENTYPE:
5507 case T_ANYTYPE:
5508 self_ref = t_last->chk_this_template_Choice(t, is_modified, implicit_omit, lhs);
5509 break;
5510 case T_SEQ_A:
5511 case T_SEQ_T:
5512 self_ref = t_last->chk_this_template_Seq(t, is_modified, implicit_omit, lhs);
5513 break;
5514 case T_SET_A:
5515 case T_SET_T:
5516 self_ref = t_last->chk_this_template_Set(t, is_modified, implicit_omit, lhs);
5517 break;
5518 case T_SEQOF:
5519 self_ref = t_last->chk_this_template_SeqOf(t, is_modified, implicit_omit, lhs);
5520 break;
5521 case T_SETOF:
5522 self_ref = t_last->chk_this_template_SetOf(t, is_modified, implicit_omit, lhs);
5523 break;
5524 case T_ARRAY:
5525 self_ref = t_last->chk_this_template_array(t, is_modified, implicit_omit, lhs);
5526 break;
5527 case T_PORT:
5528 t->error("Template cannot be defined for port type `%s'",
5529 get_fullname().c_str());
5530 break;
5531 case T_SIGNATURE:
5532 t_last->chk_this_template_Signature(t, is_modified);
5533 break;
5534 case T_FUNCTION:
5535 case T_ALTSTEP:
5536 case T_TESTCASE:
5537 t_last->chk_this_template_Fat(t);
5538 break;
5539 default:
5540 FATAL_ERROR("Type::chk_this_template()");
5541 } // switch
5542 return self_ref;
5543 }
5544
5545 void Type::chk_this_template_Str(Template *t)
5546 {
5547 typetype_t tt = get_typetype_ttcn3(typetype);
5548 bool report_error = false;
5549 switch (t->get_templatetype()) {
5550 case Ttcn::Template::VALUE_RANGE:
5551 if (tt == T_CSTR || tt == T_USTR) {
5552 Error_Context cntxt(t, "In value range");
5553 Ttcn::ValueRange *vr = t->get_value_range();
5554 Value *v_lower = chk_range_boundary(vr->get_min_v(), "lower", *t);
5555 Value *v_upper = chk_range_boundary(vr->get_max_v(), "upper", *t);
5556 if (v_lower && v_upper) {
5557 // both boundaries are available and have correct type
5558 if (tt == T_CSTR) {
5559 if (v_lower->get_val_str() > v_upper->get_val_str())
5560 t->error("The lower boundary has higher character code than the "
5561 "upper boundary");
5562 } else {
5563 if (v_lower->get_val_ustr() > v_upper->get_val_ustr())
5564 t->error("The lower boundary has higher character code than the "
5565 "upper boundary");
5566 }
5567 }
5568 } else report_error = true;
5569 break;
5570 case Ttcn::Template::BSTR_PATTERN:
5571 if (tt != T_BSTR) report_error = true;
5572 break;
5573 case Ttcn::Template::HSTR_PATTERN:
5574 if (tt != T_HSTR) report_error = true;
5575 break;
5576 case Ttcn::Template::OSTR_PATTERN:
5577 if (tt != T_OSTR) report_error = true;
5578 break;
5579 case Ttcn::Template::CSTR_PATTERN:
5580 if (tt == T_CSTR) {
5581 Ttcn::PatternString *pstr = t->get_cstr_pattern();
5582 Error_Context cntxt(t, "In character string pattern");
5583 pstr->chk_refs();
5584 pstr->join_strings();
5585 if (!pstr->has_refs()) pstr->chk_pattern();
5586 break;
5587 } else if (tt == T_USTR) {
5588 t->set_templatetype(Template::USTR_PATTERN);
5589 t->get_ustr_pattern()
5590 ->set_pattern_type(Ttcn::PatternString::USTR_PATTERN);
5591 // fall through
5592 } else {
5593 report_error = true;
5594 break;
5595 }
5596 // no break
5597 case Ttcn::Template::USTR_PATTERN:
5598 if (tt == T_USTR) {
5599 Ttcn::PatternString *pstr = t->get_ustr_pattern();
5600 Error_Context cntxt(t, "In universal string pattern");
5601 pstr->chk_refs();
5602 pstr->join_strings();
5603 if (!pstr->has_refs()) pstr->chk_pattern();
5604 } else report_error = true;
5605 break;
5606 default:
5607 report_error = true;
5608 break;
5609 }
5610 if (report_error) {
5611 t->error("%s cannot be used for type `%s'", t->get_templatetype_str(),
5612 get_typename().c_str());
5613 }
5614 }
5615
5616 void Type::chk_range_boundary_infinity(Value *v, bool is_upper)
5617 {
5618 if (v) {
5619 v->set_my_governor(this);
5620 {
5621 Error_Context cntxt2(v, "In %s boundary", is_upper ? "upper" : "lower");
5622 chk_this_value_ref(v);
5623 Value *v_last = v->get_value_refd_last(0, EXPECTED_STATIC_VALUE);
5624 if (v_last->get_valuetype() == Value::V_OMIT) {
5625 v->error("`omit' value is not allowed in this context");
5626 v->set_valuetype(Value::V_ERROR);
5627 return;
5628 }
5629 if (sub_type != NULL) {
5630 if (is_upper) {
5631 if (!sub_type->get_root()->is_upper_limit_infinity()) {
5632 v->error("Infinity is not a valid value for type '%s' which has subtype %s",
5633 asString(), sub_type->to_string().c_str());
5634 }
5635 }
5636 else {
5637 if (!sub_type->get_root()->is_lower_limit_infinity()) {
5638 v->error("Infinity is not a valid value for type '%s' which has subtype %s",
5639 asString(), sub_type->to_string().c_str());
5640 }
5641 }
5642 }
5643 }
5644 }
5645 }
5646
5647 Value *Type::chk_range_boundary(Value *v, const char *which,
5648 const Location& loc)
5649 {
5650 typetype_t tt = get_typetype_ttcn3(typetype);
5651 Value *ret_val;
5652 if (v) {
5653 v->set_my_governor(this);
5654 {
5655 Error_Context cntxt2(v, "In %s boundary", which);
5656 chk_this_value_ref(v);
5657 chk_this_value(v, 0, EXPECTED_DYNAMIC_VALUE, INCOMPLETE_NOT_ALLOWED,
5658 OMIT_NOT_ALLOWED, SUB_CHK);
5659 }
5660 ret_val = v->get_value_refd_last();
5661 switch (ret_val->get_valuetype()) {
5662 case Value::V_INT:
5663 if (tt != T_INT) ret_val = 0;
5664 break;
5665 case Value::V_REAL:
5666 if (tt != T_REAL) ret_val = 0;
5667 break;
5668 case Value::V_CSTR:
5669 if (tt != T_CSTR) ret_val = 0;
5670 break;
5671 case Value::V_USTR:
5672 if (tt != T_USTR) ret_val = 0;
5673 break;
5674 default:
5675 // unfoldable or erroneous
5676 ret_val = 0;
5677 break;
5678 }
5679 if ((tt == T_CSTR || tt == T_USTR) && ret_val &&
5680 ret_val->get_val_strlen() != 1) {
5681 v->error("The %s boundary must be a %scharstring value containing a "
5682 "single character", which, tt == T_USTR ? "universal ": "");
5683 ret_val = 0;
5684 }
5685 } else {
5686 // the boundary is + or - infinity
5687 if (tt == T_CSTR || tt == T_USTR) {
5688 loc.error("The %s boundary must be a %scharstring value", which,
5689 tt == T_USTR ? "universal ": "");
5690 }
5691 ret_val = 0;
5692 }
5693 return ret_val;
5694 }
5695
5696 void Type::chk_this_template_builtin(Template *t)
5697 {
5698 t->error("%s cannot be used for type `%s'", t->get_templatetype_str(),
5699 get_typename().c_str());
5700 if (t->get_length_restriction()) t->error("Length restriction is not "
5701 "allowed for type `%s'", get_typename().c_str());
5702 }
5703
5704 void Type::chk_this_template_Int_Real(Template *t)
5705 {
5706 switch (t->get_templatetype()) {
5707 case Ttcn::Template::VALUE_RANGE: {
5708 Error_Context cntxt(t, "In value range");
5709 Ttcn::ValueRange *vr = t->get_value_range();
5710 Value *v_lower = chk_range_boundary(vr->get_min_v(), "lower", *t);
5711 Value *v_upper = chk_range_boundary(vr->get_max_v(), "upper", *t);
5712 if (v_lower && v_upper) {
5713 // both boundaries are available and have correct type
5714 switch (get_typetype_ttcn3(typetype)) {
5715 case T_INT: {
5716 if (*v_lower->get_val_Int() > *v_upper->get_val_Int())
5717 t->error("The lower boundary is higher than the upper boundary");
5718 break; }
5719 case T_REAL:
5720 if (v_lower->get_val_Real() > v_upper->get_val_Real())
5721 t->error("The lower boundary is higher than the upper boundary");
5722 break;
5723 default:
5724 FATAL_ERROR("Type::chk_this_template_Int_Real()");
5725 }
5726 }
5727 if (v_lower && !v_upper) {
5728 chk_range_boundary_infinity(v_lower, true);
5729 }
5730 if (!v_lower && v_upper) {
5731 chk_range_boundary_infinity(v_upper, false);
5732 }
5733 break;}
5734 default:
5735 t->error("%s cannot be used for type `%s'", t->get_templatetype_str(),
5736 get_typename().c_str());
5737 break;
5738 }
5739 if (t->get_length_restriction()) t->error("Length restriction is not "
5740 "allowed for type `%s'", get_typename().c_str());
5741 }
5742
5743 void Type::chk_this_template_Enum(Template *t)
5744 {
5745 t->error("%s cannot be used for enumerated type `%s'",
5746 t->get_templatetype_str(), get_typename().c_str());
5747 if (t->get_length_restriction()) t->error("Length restriction is not "
5748 "allowed for enumerated type `%s'", get_typename().c_str());
5749 }
5750
5751 bool Type::chk_this_template_Choice(Template *t, namedbool is_modified,
5752 namedbool implicit_omit, Common::Assignment *lhs)
5753 {
5754 bool self_ref = false;
5755 switch (t->get_templatetype()) {
5756 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
5757 size_t nof_nts = t->get_nof_comps();
5758 if (nof_nts != 1) t->error("A template for union type must contain "
5759 "exactly one selected field");
5760 // We check all named templates, even though it is an error
5761 // to have more than one here.
5762 for (size_t i = 0; i < nof_nts; i++) {
5763 Ttcn::NamedTemplate *nt = t->get_namedtemp_byIndex(i);
5764 const Identifier& nt_name = nt->get_name();
5765
5766 if (!has_comp_withName(nt_name)) {
5767 nt->error("Reference to non-existent field `%s' in union "
5768 "template for type `%s'", nt_name.get_dispname().c_str(),
5769 get_fullname().c_str());
5770 nt->note("%s", actual_fields(*this).c_str());
5771 continue;
5772 }
5773
5774 Type *field_type = get_comp_byName(nt_name)->get_type();
5775 Template *nt_templ = nt->get_template();
5776
5777 Error_Context cntxt(nt_templ, "In template for union field `%s'",
5778 nt_name.get_dispname().c_str());
5779
5780 nt_templ->set_my_governor(field_type);
5781 field_type->chk_this_template_ref(nt_templ);
5782 bool incompl_ok = t->get_completeness_condition_choice(is_modified, nt_name) ==
5783 Ttcn::Template::C_MAY_INCOMPLETE;
5784 self_ref |= field_type->chk_this_template_generic(nt_templ,
5785 (incompl_ok ? INCOMPLETE_ALLOWED : INCOMPLETE_NOT_ALLOWED),
5786 OMIT_NOT_ALLOWED, ANY_OR_OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit, lhs);
5787 }
5788 break;}
5789 default:
5790 t->error("%s cannot be used for union type `%s'",
5791 t->get_templatetype_str(), get_typename().c_str());
5792 break;
5793 }
5794 if (t->get_length_restriction()) t->error("Length restriction is not "
5795 "allowed for union type `%s'", get_typename().c_str());
5796
5797 return self_ref;
5798 }
5799
5800 bool Type::chk_this_template_Seq(Template *t, namedbool is_modified,
5801 namedbool implicit_omit, Common::Assignment *lhs)
5802 {
5803 bool self_ref = false;
5804 size_t n_type_comps = get_nof_comps();
5805 switch (t->get_templatetype()) {
5806 case Ttcn::Template::TEMPLATE_LIST:
5807 // conversion: value list -> assignment notation
5808 t->set_templatetype(Ttcn::Template::NAMED_TEMPLATE_LIST);
5809 // no break
5810 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
5811 map<string, Ttcn::NamedTemplate> comp_map;
5812 // it is set to false if we have lost the ordering
5813 bool in_synch = true;
5814 size_t n_template_comps = t->get_nof_comps();
5815 // the two variables below are used for modified templates only
5816 CompField *last_cf = 0;
5817 size_t next_index = 0;
5818 for (size_t i = 0; i < n_template_comps; i++) {
5819 Ttcn::NamedTemplate *namedtemp = t->get_namedtemp_byIndex(i);
5820 const Identifier& temp_id = namedtemp->get_name();
5821 const string& temp_name = temp_id.get_name();
5822 const char *temp_dispname_str = temp_id.get_dispname().c_str();
5823 if (!has_comp_withName(temp_id)) {
5824 namedtemp->error("Reference to non-existent field `%s' in record "
5825 "template for type `%s'", temp_dispname_str,
5826 get_typename().c_str());
5827 namedtemp->note("%s", actual_fields(*this).c_str());
5828 in_synch = false;
5829 continue;
5830 } else if (comp_map.has_key(temp_name)) {
5831 namedtemp->error("Duplicate record field `%s' in template",
5832 temp_dispname_str);
5833 comp_map[temp_name]->note("Field `%s' is already given here",
5834 temp_dispname_str);
5835 in_synch = false;
5836 } else comp_map.add(temp_name, namedtemp);
5837
5838 CompField *cf = get_comp_byName(temp_id);
5839 if (in_synch) {
5840 if (is_modified) {
5841 // missing fields are allowed, but take care of ordering
5842 bool found = false;
5843 for (size_t j = next_index; j < n_type_comps; j++) {
5844 CompField *cf2 = get_comp_byIndex(j);
5845 if (temp_name == cf2->get_name().get_name()) {
5846 last_cf = cf2;
5847 next_index = j + 1;
5848 found = true;
5849 break;
5850 }
5851 }
5852 if (!found) {
5853 namedtemp->error("Field `%s' cannot appear after field `%s' in "
5854 "a template for record type `%s'", temp_dispname_str,
5855 last_cf->get_name().get_dispname().c_str(),
5856 get_fullname().c_str());
5857 in_synch = false;
5858 }
5859 } else {
5860 // the template must be complete
5861 CompField *cf2 = get_comp_byIndex(i);
5862 if (cf2 != cf) {
5863 if (!cf2->get_is_optional() || !implicit_omit) {
5864 namedtemp->error("Unexpected field `%s' in record template, "
5865 "expecting `%s'", temp_dispname_str,
5866 cf2->get_name().get_dispname().c_str());
5867 in_synch = false;
5868 }
5869 }
5870 }
5871 }
5872 Type *type = cf->get_type();
5873 Template *comp_t = namedtemp->get_template();
5874 Error_Context cntxt(comp_t, "In template for record field `%s'",
5875 temp_dispname_str);
5876 comp_t->set_my_governor(type);
5877 type->chk_this_template_ref(comp_t);
5878 bool is_optional = cf->get_is_optional(); // || cf->has_default()
5879 self_ref |= type->chk_this_template_generic(comp_t, is_modified,
5880 (is_optional ? OMIT_ALLOWED : OMIT_NOT_ALLOWED),
5881 (is_optional ? ANY_OR_OMIT_ALLOWED : ANY_OR_OMIT_NOT_ALLOWED),
5882 SUB_CHK, implicit_omit, lhs);
5883 }
5884 if (!is_modified || implicit_omit) {
5885 // check missing fields
5886 for (size_t i = 0; i < n_type_comps; i++) {
5887 const Identifier& id = get_comp_byIndex(i)->get_name();
5888 if (!comp_map.has_key(id.get_name())) {
5889 if (implicit_omit && get_comp_byIndex(i)->get_is_optional()) {
5890 // do not overwrite base fields
5891 if (!t->get_base_template())
5892 t->add_named_temp(new Ttcn::NamedTemplate(new Identifier(id),
5893 new Template(Template::OMIT_VALUE)));
5894 } else if (!is_modified) {
5895 t->error("Field `%s' is missing from template for record type `%s'",
5896 id.get_dispname().c_str(), get_typename().c_str());
5897 }
5898 }
5899 }
5900 }
5901 comp_map.clear();
5902 break; }
5903 default:
5904 t->error("%s cannot be used for record type `%s'",
5905 t->get_templatetype_str(), get_typename().c_str());
5906 break;
5907 }
5908 if (t->get_length_restriction()) t->error("Length restriction is not "
5909 "allowed for record type `%s'", get_typename().c_str());
5910 return self_ref;
5911 }
5912
5913 bool Type::chk_this_template_Set(Template *t,
5914 namedbool is_modified, namedbool implicit_omit, Common::Assignment *lhs)
5915 {
5916 bool self_ref = false;
5917 size_t n_type_comps = get_nof_comps();
5918 switch (t->get_templatetype()) {
5919 case Ttcn::Template::TEMPLATE_LIST:
5920 if (t->get_nof_comps() > 0) {
5921 t->error("Value list notation is not allowed for set type `%s'",
5922 get_fullname().c_str());
5923 break;
5924 } else if (n_type_comps > 0) {
5925 t->error("A non-empty set template was expected for type `%s'",
5926 get_fullname().c_str());
5927 break;
5928 }
5929 t->set_templatetype(Ttcn::Template::NAMED_TEMPLATE_LIST);
5930 // no break
5931 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
5932 map<string, Ttcn::NamedTemplate> comp_map;
5933 size_t n_template_comps = t->get_nof_comps();
5934 for (size_t i = 0; i < n_template_comps; i++) {
5935 Ttcn::NamedTemplate *namedtemp = t->get_namedtemp_byIndex(i);
5936 const Identifier& temp_id=namedtemp->get_name();
5937 const string& temp_name = temp_id.get_name();
5938 const char *temp_dispname_str = temp_id.get_dispname().c_str();
5939 if (!has_comp_withName(temp_id)) {
5940 namedtemp->error("Reference to non-existent field `%s' in a "
5941 "template for set type `%s'", temp_dispname_str,
5942 get_typename().c_str());
5943 namedtemp->note("%s", actual_fields(*this).c_str());
5944 continue;
5945 } else if (comp_map.has_key(temp_name)) {
5946 namedtemp->error("Duplicate set field `%s' in template",
5947 temp_dispname_str);
5948 comp_map[temp_name]->note("Field `%s' is already given here",
5949 temp_dispname_str);
5950 } else comp_map.add(temp_name, namedtemp);
5951 CompField *cf = get_comp_byName(temp_id);
5952 Type *type = cf->get_type();
5953 Template *comp_t = namedtemp->get_template();
5954 Error_Context cntxt(comp_t, "In template for set field `%s'",
5955 temp_dispname_str);
5956 comp_t->set_my_governor(type);
5957 type->chk_this_template_ref(comp_t);
5958 bool is_optional = cf->get_is_optional();
5959 self_ref |= type->chk_this_template_generic(comp_t,
5960 (is_modified ? INCOMPLETE_ALLOWED : INCOMPLETE_NOT_ALLOWED),
5961 (is_optional ? OMIT_ALLOWED : OMIT_NOT_ALLOWED),
5962 (is_optional ? ANY_OR_OMIT_ALLOWED : ANY_OR_OMIT_NOT_ALLOWED),
5963 SUB_CHK, implicit_omit, lhs);
5964 }
5965 if (!is_modified || implicit_omit) {
5966 // check missing fields
5967 for (size_t i = 0; i < n_type_comps; i++) {
5968 const Identifier& id = get_comp_byIndex(i)->get_name();
5969 if (!comp_map.has_key(id.get_name())) {
5970 if (get_comp_byIndex(i)->get_is_optional() && implicit_omit) {
5971 // do not overwrite base fields
5972 if (!t->get_base_template())
5973 t->add_named_temp(new Ttcn::NamedTemplate(new Identifier(id),
5974 new Template(Template::OMIT_VALUE)));
5975 } else if (!is_modified) {
5976 t->error("Field `%s' is missing from template for set type `%s'",
5977 id.get_dispname().c_str(), get_typename().c_str());
5978 }
5979 }
5980 }
5981 }
5982 comp_map.clear();
5983 break; }
5984 default:
5985 t->error("%s cannot be used for set type `%s'",
5986 t->get_templatetype_str(), get_typename().c_str());
5987 break;
5988 }
5989 if (t->get_length_restriction()) t->error("Length restriction is not "
5990 "allowed for set type `%s'", get_typename().c_str());
5991 return self_ref;
5992 }
5993
5994 bool Type::chk_this_template_SeqOf(Template *t, namedbool is_modified,
5995 namedbool implicit_omit, Common::Assignment *lhs)
5996 {
5997 bool self_ref = false;
5998 switch(t->get_templatetype()) {
5999 case Ttcn::Template::OMIT_VALUE:
6000 if(t->get_length_restriction())
6001 t->warning("Redundant usage of length restriction with `omit'");
6002 break;
6003 case Ttcn::Template::PERMUTATION_MATCH: {
6004 size_t nof_comps = t->get_nof_comps();
6005 for (size_t i = 0; i < nof_comps; i++) {
6006 Template *t_comp = t->get_temp_byIndex(i);
6007 Error_Context cntxt(t_comp, "In element %lu of permutation",
6008 (unsigned long) (i + 1));
6009 t_comp->set_my_governor(u.seof.ofType);
6010 u.seof.ofType->chk_this_template_ref(t_comp);
6011 // the elements of permutation must be always complete
6012 self_ref |= u.seof.ofType->chk_this_template_generic(t_comp,
6013 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
6014 NOT_IMPLICIT_OMIT, lhs);
6015 }
6016 break; }
6017 case Ttcn::Template::TEMPLATE_LIST: {
6018 Ttcn::Template::completeness_t c =
6019 t->get_completeness_condition_seof(is_modified);
6020 Template *t_base;
6021 size_t nof_base_comps;
6022 if (c == Ttcn::Template::C_PARTIAL) {
6023 t_base = t->get_base_template()->get_template_refd_last();
6024 // it is sure that t_base is a TEMPLATE_LIST
6025 nof_base_comps = t_base->get_nof_comps();
6026 } else {
6027 t_base = 0;
6028 nof_base_comps = 0;
6029 }
6030 size_t nof_comps = t->get_nof_comps();
6031 for(size_t i = 0; i < nof_comps; i++) {
6032 Template *t_comp = t->get_temp_byIndex(i);
6033 Error_Context cntxt(t_comp, "In component %lu", (unsigned long)(i+1));
6034 t_comp->set_my_governor(u.seof.ofType);
6035 if (t_base && i < nof_base_comps)
6036 t_comp->set_base_template(t_base->get_temp_byIndex(i));
6037 u.seof.ofType->chk_this_template_ref(t_comp);
6038 switch (t_comp->get_templatetype()) {
6039 case Ttcn::Template::PERMUTATION_MATCH:
6040 // the elements of permutation has to be checked by u.seof.ofType
6041 // the templates within the permutation always have to be complete
6042 self_ref |= chk_this_template_generic(t_comp, INCOMPLETE_NOT_ALLOWED,
6043 OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
6044 implicit_omit, lhs);
6045 break;
6046 case Ttcn::Template::TEMPLATE_NOTUSED:
6047 if (c == Ttcn::Template::C_MUST_COMPLETE) {
6048 t_comp->error("Not used symbol `-' is not allowed in this context");
6049 } else if (c == Ttcn::Template::C_PARTIAL && i >= nof_base_comps) {
6050 t_comp->error("Not used symbol `-' cannot be used here because "
6051 "there is no corresponding element in the base template");
6052 }
6053 break;
6054 default:
6055 bool embedded_modified = (c == Ttcn::Template::C_MAY_INCOMPLETE) ||
6056 (c == Ttcn::Template::C_PARTIAL && i < nof_base_comps);
6057 self_ref |= u.seof.ofType->chk_this_template_generic(t_comp,
6058 (embedded_modified ? INCOMPLETE_ALLOWED : INCOMPLETE_NOT_ALLOWED),
6059 OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, implicit_omit, lhs);
6060 break;
6061 }
6062 }
6063 break; }
6064 case Ttcn::Template::INDEXED_TEMPLATE_LIST: {
6065 map<Int, Int> index_map;
6066 for (size_t i = 0; i < t->get_nof_comps(); i++) {
6067 Ttcn::IndexedTemplate *it = t->get_indexedtemp_byIndex(i);
6068 Value *index_value = (it->get_index()).get_val();
6069 // The index value must be Type::EXPECTED_DYNAMIC_VALUE integer, but
6070 // it's not required to be known at compile time.
6071 index_value->chk_expr_int(Type::EXPECTED_DYNAMIC_VALUE);
6072 Template *it_comp = it->get_template();
6073 Error_Context cntxt(it_comp, "In component %lu",
6074 (unsigned long)(i + 1));
6075 if (index_value->get_value_refd_last()->get_valuetype() == Value::V_INT) {
6076 const int_val_t *index_int = index_value->get_value_refd_last()
6077 ->get_val_Int();
6078 if (*index_int > INT_MAX) {
6079 index_value->error("An integer value less than `%d' was expected "
6080 "for indexing type `%s' instead of `%s'", INT_MAX,
6081 get_typename().c_str(), (index_int->t_str()).c_str());
6082 index_value->set_valuetype(Value::V_ERROR);
6083 } else {
6084 Int index = index_int->get_val();
6085 if (index < 0) {
6086 index_value->error("A non-negative integer value was expected "
6087 "for indexing type `%s' instead of `%s'",
6088 get_typename().c_str(), Int2string(index).c_str());
6089 index_value->set_valuetype(Value::V_ERROR);
6090 } else if (index_map.has_key(index)) {
6091 index_value->error("Duplicate index value `%s' for components "
6092 "`%s' and `%s'", Int2string(index).c_str(),
6093 Int2string((Int)i + 1).c_str(),
6094 Int2string(*index_map[index]).c_str());
6095 index_value->set_valuetype(Value::V_ERROR);
6096 } else {
6097 index_map.add(index, new Int((Int)i + 1));
6098 }
6099 }
6100 }
6101 it_comp->set_my_governor(u.seof.ofType);
6102 u.seof.ofType->chk_this_template_ref(it_comp);
6103 self_ref |= u.seof.ofType->chk_this_template_generic(it_comp,
6104 INCOMPLETE_ALLOWED, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED,
6105 SUB_CHK, implicit_omit, lhs);
6106 }
6107 for (size_t i = 0; i < index_map.size(); i++)
6108 delete index_map.get_nth_elem(i);
6109 index_map.clear();
6110 break; }
6111 default:
6112 t->error("%s cannot be used for `record of' type `%s'",
6113 t->get_templatetype_str(), get_typename().c_str());
6114 break;
6115 }
6116 return self_ref;
6117 }
6118
6119 bool Type::chk_this_template_SetOf(Template *t, namedbool is_modified,
6120 namedbool implicit_omit, Common::Assignment *lhs)
6121 {
6122 bool self_ref = false;
6123 Ttcn::Template::templatetype_t temptype = t->get_templatetype();
6124 switch (temptype) {
6125 case Ttcn::Template::OMIT_VALUE:
6126 if(t->get_length_restriction())
6127 t->warning("Redundant usage of length restriction with `omit'");
6128 break;
6129 case Ttcn::Template::SUPERSET_MATCH:
6130 case Ttcn::Template::SUBSET_MATCH: {
6131 const char *settype = temptype == Ttcn::Template::SUPERSET_MATCH ?
6132 "superset" : "subset";
6133 size_t nof_comps = t->get_nof_comps();
6134 for (size_t i = 0; i < nof_comps; i++) {
6135 Template *t_comp = t->get_temp_byIndex(i);
6136 Error_Context cntxt(t_comp, "In element %lu of %s",
6137 (unsigned long) (i + 1), settype);
6138 t_comp->set_my_governor(u.seof.ofType);
6139 u.seof.ofType->chk_this_template_ref(t_comp);
6140 // the elements of sets must be always complete
6141 self_ref |= u.seof.ofType->chk_this_template_generic(t_comp,
6142 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED,
6143 SUB_CHK, implicit_omit, lhs);
6144 if (t_comp->get_template_refd_last()->get_templatetype() ==
6145 Ttcn::Template::ANY_OR_OMIT) {
6146 if (temptype == Ttcn::Template::SUPERSET_MATCH)
6147 t_comp->warning("`*' in superset has no effect during matching");
6148 else t_comp->warning("`*' in subset. This template will match "
6149 "everything");
6150 }
6151 }
6152 break;}
6153 case Ttcn::Template::TEMPLATE_LIST: {
6154 Ttcn::Template::completeness_t c =
6155 t->get_completeness_condition_seof(is_modified);
6156 Template *t_base;
6157 size_t nof_base_comps;
6158 if (c == Ttcn::Template::C_PARTIAL) {
6159 t_base = t->get_base_template()->get_template_refd_last();
6160 // it is sure that t_base is a TEMPLATE_LIST
6161 nof_base_comps = t_base->get_nof_comps();
6162 } else {
6163 t_base = 0;
6164 nof_base_comps = 0;
6165 }
6166 size_t nof_comps = t->get_nof_comps();
6167 for(size_t i = 0; i < nof_comps; i++) {
6168 Template *t_comp = t->get_temp_byIndex(i);
6169 Error_Context cntxt(t_comp, "In component %lu", (unsigned long)(i+1));
6170 t_comp->set_my_governor(u.seof.ofType);
6171 if (t_base && i < nof_base_comps)
6172 t_comp->set_base_template(t_base->get_temp_byIndex(i));
6173 u.seof.ofType->chk_this_template_ref(t_comp);
6174 switch (t_comp->get_templatetype()) {
6175 case Ttcn::Template::PERMUTATION_MATCH:
6176 t_comp->error("%s cannot be used for `set of' type `%s'",
6177 t_comp->get_templatetype_str(), get_typename().c_str());
6178 break;
6179 case Ttcn::Template::TEMPLATE_NOTUSED:
6180 if (c == Ttcn::Template::C_MUST_COMPLETE) {
6181 t_comp->error("Not used symbol `-' is not allowed in this context");
6182 } else if (c == Ttcn::Template::C_PARTIAL && i >= nof_base_comps) {
6183 t_comp->error("Not used symbol `-' cannot be used here because "
6184 "there is no corresponding element in the base template");
6185 }
6186 break;
6187 default:
6188 bool embedded_modified = (c == Ttcn::Template::C_MAY_INCOMPLETE) ||
6189 (c == Ttcn::Template::C_PARTIAL && i < nof_base_comps);
6190 self_ref |= u.seof.ofType->chk_this_template_generic(t_comp,
6191 (embedded_modified ? INCOMPLETE_ALLOWED : INCOMPLETE_NOT_ALLOWED),
6192 OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, implicit_omit, lhs);
6193 break;
6194 }
6195 }
6196 break; }
6197 case Ttcn::Template::INDEXED_TEMPLATE_LIST: {
6198 map<Int, Int> index_map;
6199 for (size_t i = 0; i < t->get_nof_comps(); i++) {
6200 Ttcn::IndexedTemplate *it = t->get_indexedtemp_byIndex(i);
6201 Value *index_value = (it->get_index()).get_val();
6202 index_value->chk_expr_int(Type::EXPECTED_DYNAMIC_VALUE);
6203 Template *it_comp = it->get_template();
6204 Error_Context cntxt(it_comp, "In component %lu",
6205 (unsigned long)(i + 1));
6206 if (index_value->get_value_refd_last()->get_valuetype() == Value::V_INT) {
6207 const int_val_t *index_int = index_value->get_value_refd_last()
6208 ->get_val_Int();
6209 if (*index_int > INT_MAX) {
6210 index_value->error("An integer value less than `%d' was expected "
6211 "for indexing type `%s' instead of `%s'", INT_MAX,
6212 get_typename().c_str(), (index_int->t_str()).c_str());
6213 index_value->set_valuetype(Value::V_ERROR);
6214 } else {
6215 Int index = index_int->get_val();
6216 if (index < 0) {
6217 index_value->error("A non-negative integer value was expected "
6218 "for indexing type `%s' instead of `%s'",
6219 get_typename().c_str(), Int2string(index).c_str());
6220 index_value->set_valuetype(Value::V_ERROR);
6221 } else if (index_map.has_key(index)) {
6222 index_value->error("Duplicate index value `%s' for components "
6223 "`%s' and `%s'", Int2string(index).c_str(),
6224 Int2string((Int)i + 1).c_str(),
6225 Int2string(*index_map[index]).c_str());
6226 index_value->set_valuetype(Value::V_ERROR);
6227 } else {
6228 index_map.add(index, new Int((Int)i + 1));
6229 }
6230 }
6231 }
6232 it_comp->set_my_governor(u.seof.ofType);
6233 u.seof.ofType->chk_this_template_ref(it_comp);
6234 self_ref |= u.seof.ofType->chk_this_template_generic(it_comp,
6235 INCOMPLETE_ALLOWED, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED,
6236 SUB_CHK, implicit_omit, lhs);
6237 }
6238 for (size_t i = 0; i < index_map.size(); i++)
6239 delete index_map.get_nth_elem(i);
6240 index_map.clear();
6241 break; }
6242 default:
6243 t->error("%s cannot be used for `set of' type `%s'",
6244 t->get_templatetype_str(), get_typename().c_str());
6245 break;
6246 }
6247 return self_ref;
6248 }
6249
6250 bool Type::chk_this_template_array(Template *t, namedbool is_modified,
6251 namedbool implicit_omit, Common::Assignment *lhs)
6252 {
6253 bool self_ref = false;
6254 switch (t->get_templatetype()) {
6255 case Ttcn::Template::OMIT_VALUE:
6256 if (t->get_length_restriction())
6257 t->warning("Redundant usage of length restriction with `omit'");
6258 break;
6259 case Ttcn::Template::PERMUTATION_MATCH: {
6260 size_t nof_comps = t->get_nof_comps();
6261 for (size_t i = 0; i < nof_comps; i++) {
6262 Template *t_comp = t->get_temp_byIndex(i);
6263 Error_Context cntxt(t_comp, "In element %lu of permutation",
6264 (unsigned long) (i + 1));
6265 t_comp->set_my_governor(u.array.element_type);
6266 u.array.element_type->chk_this_template_ref(t_comp);
6267 // the elements of permutation must be always complete
6268 self_ref |= u.array.element_type->chk_this_template_generic(t_comp,
6269 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
6270 NOT_IMPLICIT_OMIT, lhs);
6271 }
6272 break; }
6273 case Ttcn::Template::TEMPLATE_LIST: {
6274 Template *t_base = t->get_base_template();
6275 size_t nof_base_comps = 0;
6276 if (t_base) {
6277 t_base = t_base->get_template_refd_last();
6278 if (t_base->get_templatetype() == Ttcn::Template::TEMPLATE_LIST)
6279 nof_base_comps = t_base->get_nof_comps();
6280 else t_base = 0; // error recovery
6281 }
6282 if (!u.array.dimension->get_has_error()) {
6283 size_t array_size = u.array.dimension->get_size();
6284 size_t template_size = t->get_nof_listitems();
6285 if (array_size != template_size) {
6286 if (t->is_flattened()){
6287 t->error("Too %s elements in the array template: %lu was expected "
6288 "instead of %lu",
6289 array_size > template_size ? "few" : "many",
6290 (unsigned long)array_size, (unsigned long)template_size);
6291 }
6292 else {
6293 t->warning("The size of template cannot be resolved "
6294 "so it could not be compared to the array size");
6295 }
6296 }
6297 }
6298 size_t nof_comps = t->get_nof_comps();
6299 for (size_t i = 0; i < nof_comps; i++) {
6300 Template *t_comp = t->get_temp_byIndex(i);
6301 Error_Context cntxt(t_comp, "In array element %lu",
6302 (unsigned long)(i + 1));
6303 t_comp->set_my_governor(u.array.element_type);
6304 if (t_base && i < nof_base_comps)
6305 t_comp->set_base_template(t_base->get_temp_byIndex(i));
6306 u.array.element_type->chk_this_template_ref(t_comp);
6307 switch (t_comp->get_templatetype()) {
6308 case Ttcn::Template::PERMUTATION_MATCH:
6309 // the elements of permutation has to be checked by u.seof.ofType
6310 // the templates within the permutation always have to be complete
6311 self_ref |= chk_this_template_generic(t_comp, INCOMPLETE_NOT_ALLOWED,
6312 OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
6313 implicit_omit, lhs);
6314 break;
6315 case Ttcn::Template::TEMPLATE_NOTUSED:
6316 if (!is_modified)
6317 t_comp->error("Not used symbol `-' is not allowed in this "
6318 "context");
6319 break;
6320 default:
6321 self_ref |= u.array.element_type->chk_this_template_generic(t_comp,
6322 is_modified, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, implicit_omit, lhs);
6323 break;
6324 }
6325 }
6326 break; }
6327 case Ttcn::Template::INDEXED_TEMPLATE_LIST: {
6328 map<Int, Int> index_map;
6329 for (size_t i = 0; i < t->get_nof_comps(); i++) {
6330 Ttcn::IndexedTemplate *it = t->get_indexedtemp_byIndex(i);
6331 Value *index_value = (it->get_index()).get_val();
6332 u.array.dimension->chk_index(index_value,
6333 Type::EXPECTED_DYNAMIC_VALUE);
6334 Template *it_comp = it->get_template();
6335 Error_Context cntxt(it_comp, "In component %lu",
6336 (unsigned long)(i + 1));
6337 if (index_value->get_value_refd_last()
6338 ->get_valuetype() == Value::V_INT) {
6339 const int_val_t *index_int = index_value->get_value_refd_last()
6340 ->get_val_Int();
6341 if (*index_int > INT_MAX) {
6342 index_value->error("An integer value less than `%d' was expected "
6343 "for indexing type `%s' instead of `%s'",
6344 INT_MAX, get_typename().c_str(),
6345 (index_int->t_str()).c_str());
6346 index_value->set_valuetype(Value::V_ERROR);
6347 } else {
6348 Int index = index_int->get_val();
6349 if (index_map.has_key(index)) {
6350 index_value->error("Duplicate index value `%s' for components "
6351 "`%s' and `%s'", Int2string(index).c_str(),
6352 Int2string((Int)i + 1).c_str(),
6353 Int2string(*index_map[index]).c_str());
6354 index_value->set_valuetype(Value::V_ERROR);
6355 } else {
6356 index_map.add(index, new Int((Int)i + 1));
6357 }
6358 }
6359 }
6360 it_comp->set_my_governor(u.array.element_type);
6361 u.array.element_type->chk_this_template_ref(it_comp);
6362 self_ref |= u.array.element_type->chk_this_template_generic(it_comp,
6363 is_modified, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, implicit_omit, lhs);
6364 }
6365 for (size_t i = 0; i < index_map.size(); i++)
6366 delete index_map.get_nth_elem(i);
6367 index_map.clear();
6368 break; }
6369 default:
6370 t->error("%s cannot be used for array type `%s'",
6371 t->get_templatetype_str(), get_typename().c_str());
6372 break;
6373 }
6374 return self_ref;
6375 }
6376
6377 void Type::chk_this_template_Fat(Template *t)
6378 {
6379 t->error("%s cannot be used for type `%s'",t->get_templatetype_str(),
6380 get_typename().c_str());
6381 if(t->get_length_restriction()) t->error("Length restriction is not "
6382 "allowed for type `%s'", get_typename().c_str());
6383 }
6384
6385 void Type::chk_this_template_Signature(Template *t, namedbool is_modified)
6386 {
6387 bool self_ref = false;
6388 size_t n_type_params = get_nof_comps();
6389 switch (t->get_templatetype()) {
6390 case Ttcn::Template::TEMPLATE_LIST:
6391 // conversion: value list -> assignment notation
6392 t->set_templatetype(Ttcn::Template::NAMED_TEMPLATE_LIST);
6393 // no break
6394 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
6395 map<string, Ttcn::NamedTemplate> comp_map;
6396 // it is set to false if we have lost the ordering
6397 bool in_synch = true;
6398 size_t n_template_comps = t->get_nof_comps();
6399 size_t t_i = 0;
6400 for (size_t v_i = 0; v_i < n_template_comps; v_i++) {
6401 Ttcn::NamedTemplate *nt = t->get_namedtemp_byIndex(v_i);
6402 const Identifier& temp_id = nt->get_name();
6403 const string& temp_name = temp_id.get_name();
6404 const char *temp_dispname_str = temp_id.get_dispname().c_str();
6405 if (!has_comp_withName(temp_id)) {
6406 nt->error("Reference to non-existent parameter `%s' in template "
6407 "for signature `%s'", temp_dispname_str, get_typename().c_str());
6408 in_synch = false;
6409 continue;
6410 } else if (comp_map.has_key(temp_name)) {
6411 nt->error("Duplicate parameter `%s' in template for signature `%s'",
6412 temp_dispname_str, get_typename().c_str());
6413 comp_map[temp_name]->note("Parameter `%s' is already given here",
6414 temp_dispname_str);
6415 in_synch = false;
6416 } else comp_map.add(temp_name, nt);
6417 const SignatureParam *par =
6418 u.signature.parameters->get_param_byName(temp_id);
6419 if (in_synch) {
6420 SignatureParam *par2 = 0;
6421 for ( ; t_i < n_type_params; t_i++) {
6422 par2 = u.signature.parameters->get_param_byIndex(t_i);
6423 if (par2 == par) break;
6424 }
6425 if (par2 != par) {
6426 nt->error("Unexpected parameter `%s' in signature template",
6427 temp_dispname_str);
6428 in_synch = false;
6429 } else t_i++;
6430 }
6431 Type *type = par->get_type();
6432 Template *comp_t = nt->get_template();
6433 Error_Context cntxt(comp_t, "In template for signature parameter `%s'",
6434 temp_dispname_str);
6435 comp_t->set_my_governor(type);
6436 type->chk_this_template_ref(comp_t);
6437 self_ref |= type->chk_this_template_generic(comp_t, is_modified, OMIT_NOT_ALLOWED, ANY_OR_OMIT_NOT_ALLOWED,
6438 SUB_CHK, NOT_IMPLICIT_OMIT, NULL);
6439 }
6440 if(!is_modified) {
6441 SignatureParam *first_undef_in = NULL,
6442 *first_undef_out = NULL;
6443 for (size_t i = 0; i < n_type_params; i++) {
6444 SignatureParam *par = u.signature.parameters->get_param_byIndex(i);
6445 const Identifier& id = par->get_id();
6446 if (!comp_map.has_key(id.get_name()) ||
6447 comp_map[id.get_name()]->get_template()->get_templatetype() ==
6448 Template::TEMPLATE_NOTUSED) {
6449 switch(par->get_direction()) {
6450 case SignatureParam::PARAM_IN:
6451 if(!first_undef_in) first_undef_in = par;
6452 break;
6453 case SignatureParam::PARAM_OUT:
6454 if(!first_undef_out) first_undef_out = par;
6455 break;
6456 default: //inout
6457 t->error("Signature template is incomplete, because the inout "
6458 "parameter `%s' is missing", id.get_dispname().c_str());
6459 }
6460 }
6461 }
6462 if(first_undef_in!=NULL && first_undef_out!=NULL)
6463 t->error("Signature template is incomplete, because the in parameter "
6464 "`%s' and the out parameter `%s' is missing",
6465 first_undef_in->get_id().get_dispname().c_str(),
6466 first_undef_out->get_id().get_dispname().c_str());
6467 }
6468 comp_map.clear();
6469 break;}
6470 default:
6471 t->error("%s cannot be used for signature `%s'",
6472 t->get_templatetype_str(), get_typename().c_str());
6473 break;
6474 }
6475 if (t->get_length_restriction())
6476 t->error("Length restriction is not allowed in a template for "
6477 "signature `%s'", get_typename().c_str());
6478 }
6479
6480 } // namespace Common
This page took 0.182479 seconds and 5 git commands to generate.