Sync with 5.4.2
[deliverable/titan.core.git] / compiler2 / subtype.cc
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #include "subtype.hh"
9 #include "../common/dbgnew.hh"
10 #include "Identifier.hh"
11 #include "Value.hh"
12 #include "Setting.hh"
13 #include "Type.hh"
14 #include "CompilerError.hh"
15 #include "Valuestuff.hh"
16 #include "ttcn3/TtcnTemplate.hh"
17 #include "ttcn3/Templatestuff.hh"
18 #include "ttcn3/PatternString.hh"
19 #include "Constraint.hh"
20 #include "../common/JSON_Tokenizer.hh"
21 #include "ttcn3/Ttcn2Json.hh"
22
23 #include <limits.h>
24
25 namespace Common {
26
27 /**************************
28 class SubTypeParse
29 **************************/
30
31 SubTypeParse::SubTypeParse(Value *p_single)
32 : selection(STP_SINGLE)
33 {
34 if (!p_single) FATAL_ERROR("SubTypeParse::SubTypeParse()");
35 single = p_single;
36 }
37
38 SubTypeParse::SubTypeParse(Value *p_min, bool p_min_exclusive, Value *p_max, bool p_max_exclusive)
39 : selection(STP_RANGE)
40 {
41 range.min = p_min;
42 range.min_exclusive = p_min_exclusive;
43 range.max = p_max;
44 range.max_exclusive = p_max_exclusive;
45 }
46
47 SubTypeParse::SubTypeParse(Ttcn::LengthRestriction *p_length)
48 : selection(STP_LENGTH)
49 {
50 if (!p_length) FATAL_ERROR("SubTypeParse::SubTypeParse()");
51 length = p_length;
52 }
53
54 SubTypeParse::SubTypeParse(Ttcn::PatternString *p_pattern)
55 : selection(STP_PATTERN)
56 {
57 if (!p_pattern) FATAL_ERROR("SubTypeParse::SubTypeParse()");
58 pattern = p_pattern;
59 }
60
61 SubTypeParse::~SubTypeParse()
62 {
63 switch (selection) {
64 case STP_SINGLE:
65 delete single;
66 break;
67 case STP_RANGE:
68 delete range.min;
69 delete range.max;
70 break;
71 case STP_LENGTH:
72 delete length;
73 break;
74 case STP_PATTERN:
75 delete pattern;
76 break;
77 default:
78 FATAL_ERROR("SubTypeParse::~SubTypeParse()");
79 }
80 }
81
82 Value *SubTypeParse::Single() const
83 {
84 if (selection != STP_SINGLE) FATAL_ERROR("SubTypeParse::Single()");
85 return single;
86 }
87
88 Value *SubTypeParse::Min() const
89 {
90 if (selection != STP_RANGE) FATAL_ERROR("SubTypeParse::Min()");
91 return range.min;
92 }
93
94 bool SubTypeParse::MinExclusive() const
95 {
96 if (selection != STP_RANGE) FATAL_ERROR("SubTypeParse::MinExclusive()");
97 return range.min_exclusive;
98 }
99
100 Value *SubTypeParse::Max() const
101 {
102 if (selection != STP_RANGE) FATAL_ERROR("SubTypeParse::Max()");
103 return range.max;
104 }
105
106 bool SubTypeParse::MaxExclusive() const
107 {
108 if (selection != STP_RANGE) FATAL_ERROR("SubTypeParse::MaxExclusive()");
109 return range.max_exclusive;
110 }
111
112 Ttcn::LengthRestriction *SubTypeParse::Length() const
113 {
114 if (selection != STP_LENGTH) FATAL_ERROR("SubTypeParse::Length()");
115 return length;
116 }
117
118 Ttcn::PatternString *SubTypeParse::Pattern() const
119 {
120 if (selection != STP_PATTERN) FATAL_ERROR("SubTypeParse::Pattern()");
121 return pattern;
122 }
123
124 /********************
125 class SubtypeConstraint
126 ********************/
127
128 SubtypeConstraint::SubtypeConstraint(subtype_t st)
129 {
130 subtype = st;
131 length_restriction = NULL;
132 switch (subtype) {
133 case ST_INTEGER:
134 integer_st = NULL;
135 break;
136 case ST_FLOAT:
137 float_st = NULL;
138 break;
139 case ST_BOOLEAN:
140 boolean_st = NULL;
141 break;
142 case ST_VERDICTTYPE:
143 verdict_st = NULL;
144 break;
145 case ST_BITSTRING:
146 bitstring_st = NULL;
147 break;
148 case ST_HEXSTRING:
149 hexstring_st = NULL;
150 break;
151 case ST_OCTETSTRING:
152 octetstring_st = NULL;
153 break;
154 case ST_CHARSTRING:
155 charstring_st = NULL;
156 break;
157 case ST_UNIVERSAL_CHARSTRING:
158 universal_charstring_st = NULL;
159 break;
160 case ST_OBJID:
161 case ST_RECORD:
162 case ST_SET:
163 case ST_ENUM:
164 case ST_UNION:
165 case ST_FUNCTION:
166 case ST_ALTSTEP:
167 case ST_TESTCASE:
168 value_st = NULL;
169 break;
170 case ST_RECORDOF:
171 case ST_SETOF:
172 recof_st = NULL;
173 break;
174 default:
175 FATAL_ERROR("SubtypeConstraint::SubtypeConstraint()");
176 }
177 }
178
179 void SubtypeConstraint::copy(const SubtypeConstraint* other)
180 {
181 if ((other==NULL) || (other->subtype!=subtype)) FATAL_ERROR("SubtypeConstraint::copy()");
182 switch (subtype) {
183 case ST_INTEGER:
184 delete integer_st;
185 integer_st = other->integer_st ? new IntegerRangeListConstraint(*(other->integer_st)) : NULL;
186 break;
187 case ST_FLOAT:
188 delete float_st;
189 float_st = other->float_st ? new RealRangeListConstraint(*(other->float_st)) : NULL;
190 break;
191 case ST_BOOLEAN:
192 delete boolean_st;
193 boolean_st = other->boolean_st ? new BooleanListConstraint(*(other->boolean_st)) : NULL;
194 break;
195 case ST_VERDICTTYPE:
196 delete verdict_st;
197 verdict_st = other->verdict_st ? new VerdicttypeListConstraint(*(other->verdict_st)) : NULL;
198 break;
199 case ST_BITSTRING:
200 delete bitstring_st;
201 bitstring_st = other->bitstring_st ? new BitstringConstraint(*(other->bitstring_st)) : NULL;
202 break;
203 case ST_HEXSTRING:
204 delete hexstring_st;
205 hexstring_st = other->hexstring_st ? new HexstringConstraint(*(other->hexstring_st)) : NULL;
206 break;
207 case ST_OCTETSTRING:
208 delete octetstring_st;
209 octetstring_st = other->octetstring_st ? new OctetstringConstraint(*(other->octetstring_st)) : NULL;
210 break;
211 case ST_CHARSTRING:
212 delete charstring_st;
213 charstring_st = other->charstring_st ? new CharstringSubtypeTreeElement(*(other->charstring_st)) : NULL;
214 break;
215 case ST_UNIVERSAL_CHARSTRING:
216 delete universal_charstring_st;
217 universal_charstring_st = other->universal_charstring_st ? new UniversalCharstringSubtypeTreeElement(*(other->universal_charstring_st)) : NULL;
218 break;
219 case ST_OBJID:
220 case ST_RECORD:
221 case ST_SET:
222 case ST_ENUM:
223 case ST_UNION:
224 case ST_FUNCTION:
225 case ST_ALTSTEP:
226 case ST_TESTCASE:
227 delete value_st;
228 value_st = other->value_st ? new ValueListConstraint(*(other->value_st)) : NULL;
229 break;
230 case ST_RECORDOF:
231 case ST_SETOF:
232 delete recof_st;
233 recof_st = other->recof_st ? new RecofConstraint(*(other->recof_st)) : NULL;
234 break;
235 default:
236 FATAL_ERROR("SubtypeConstraint::copy()");
237 }
238 delete length_restriction;
239 length_restriction = other->length_restriction ? new SizeRangeListConstraint(*(other->length_restriction)) : NULL;
240 }
241
242 // used by get_asn_type_constraint() to store singleton objects and delete them on program exit
243 struct AsnTypeConstraintSingleton
244 {
245 SubtypeConstraint *printablestring_stc, *numericstring_stc, *bmpstring_stc;
246 AsnTypeConstraintSingleton():
247 printablestring_stc(NULL), numericstring_stc(NULL), bmpstring_stc(NULL) {}
248 ~AsnTypeConstraintSingleton();
249 };
250
251 AsnTypeConstraintSingleton::~AsnTypeConstraintSingleton()
252 {
253 delete printablestring_stc;
254 delete numericstring_stc;
255 delete bmpstring_stc;
256 }
257
258 SubtypeConstraint* SubtypeConstraint::get_asn_type_constraint(Type* type)
259 {
260 static AsnTypeConstraintSingleton asn_tcs;
261 static const char_limit_t zero('0'), nine('9'),
262 bigA('A'), bigZ('Z'), smalla('a'), smallz('z');
263 static const universal_char_limit_t uni_zero(0);
264 static const universal_char_limit_t uni_ffff((1<<16)-1);
265 static const CharRangeListConstraint numeric_string_char_range(
266 CharRangeListConstraint(zero, nine) +
267 CharRangeListConstraint(char_limit_t(' ')));
268 static const CharRangeListConstraint printable_string_char_range(
269 CharRangeListConstraint(bigA, bigZ) +
270 CharRangeListConstraint(smalla, smallz) +
271 CharRangeListConstraint(zero , nine) +
272 CharRangeListConstraint(char_limit_t(' ')) +
273 CharRangeListConstraint(char_limit_t('\'')) +
274 CharRangeListConstraint(char_limit_t('(')) +
275 CharRangeListConstraint(char_limit_t(')')) +
276 CharRangeListConstraint(char_limit_t('+')) +
277 CharRangeListConstraint(char_limit_t(',')) +
278 CharRangeListConstraint(char_limit_t('-')) +
279 CharRangeListConstraint(char_limit_t('.')) +
280 CharRangeListConstraint(char_limit_t('/')) +
281 CharRangeListConstraint(char_limit_t(':')) +
282 CharRangeListConstraint(char_limit_t('=')) +
283 CharRangeListConstraint(char_limit_t('?')));
284 static const UniversalCharRangeListConstraint bmp_string_char_range(
285 UniversalCharRangeListConstraint(uni_zero, uni_ffff));
286
287 switch (type->get_typetype()) {
288 case Type::T_TELETEXSTRING:
289 // TODO: based on ITU-T Recommendation T.61
290 return NULL;
291 case Type::T_VIDEOTEXSTRING:
292 // TODO: based on ITU-T Recommendation T.100 and T.101
293 return NULL;
294 case Type::T_NUMERICSTRING:
295 if (asn_tcs.numericstring_stc==NULL) {
296 asn_tcs.numericstring_stc = new SubtypeConstraint(ST_CHARSTRING);
297 asn_tcs.numericstring_stc->charstring_st = new CharstringSubtypeTreeElement(numeric_string_char_range, false);
298 }
299 return asn_tcs.numericstring_stc;
300 case Type::T_PRINTABLESTRING:
301 if (asn_tcs.printablestring_stc==NULL) {
302 asn_tcs.printablestring_stc = new SubtypeConstraint(ST_CHARSTRING);
303 asn_tcs.printablestring_stc->charstring_st = new CharstringSubtypeTreeElement(printable_string_char_range, false);
304 }
305 return asn_tcs.printablestring_stc;
306 case Type::T_BMPSTRING:
307 if (asn_tcs.bmpstring_stc==NULL) {
308 asn_tcs.bmpstring_stc = new SubtypeConstraint(ST_UNIVERSAL_CHARSTRING);
309 asn_tcs.bmpstring_stc->universal_charstring_st = new UniversalCharstringSubtypeTreeElement(bmp_string_char_range, false);
310 }
311 return asn_tcs.bmpstring_stc;
312 default:
313 return NULL;
314 }
315 }
316
317 SubtypeConstraint* SubtypeConstraint::create_from_asn_value(Type* type, Value* value)
318 {
319 Value* v = value->get_value_refd_last();
320 subtype_t st_t = type->get_subtype_type();
321 if ( (st_t==ST_ERROR) || (v->get_valuetype()==Value::V_ERROR) ) return NULL;
322 SubtypeConstraint* stc = new SubtypeConstraint(st_t);
323 switch (v->get_valuetype()) {
324 case Value::V_INT:
325 if (st_t!=ST_INTEGER) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
326 stc->integer_st = new IntegerRangeListConstraint(int_limit_t(*(v->get_val_Int())));
327 break;
328 case Value::V_REAL: {
329 if (st_t!=ST_FLOAT) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
330 ttcn3float r = v->get_val_Real();
331 if (r!=r) stc->float_st = new RealRangeListConstraint(true);
332 else stc->float_st = new RealRangeListConstraint(real_limit_t(r));
333 } break;
334 case Value::V_BOOL:
335 if (st_t!=ST_BOOLEAN) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
336 stc->boolean_st = new BooleanListConstraint(v->get_val_bool());
337 break;
338 case Value::V_OID:
339 case Value::V_ROID:
340 if (v->has_oid_error()) goto invalid_value;
341 if (st_t!=ST_OBJID) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
342 stc->value_st = new ValueListConstraint(v);
343 break;
344 case Value::V_BSTR:
345 if (st_t!=ST_BITSTRING) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
346 stc->bitstring_st = new BitstringConstraint(v->get_val_str());
347 break;
348 case Value::V_HSTR:
349 if (st_t!=ST_HEXSTRING) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
350 stc->hexstring_st = new HexstringConstraint(v->get_val_str());
351 break;
352 case Value::V_OSTR:
353 if (st_t!=ST_OCTETSTRING) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
354 stc->octetstring_st = new OctetstringConstraint(v->get_val_str());
355 break;
356 case Value::V_CSTR:
357 if (st_t!=ST_CHARSTRING) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
358 stc->charstring_st = new CharstringSubtypeTreeElement(StringValueConstraint<string>(v->get_val_str()));
359 break;
360 case Value::V_ISO2022STR:
361 if (st_t!=ST_CHARSTRING) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
362 stc->charstring_st = new CharstringSubtypeTreeElement(StringValueConstraint<string>(v->get_val_iso2022str()));
363 break;
364 case Value::V_CHARSYMS:
365 case Value::V_USTR:
366 if (st_t!=ST_UNIVERSAL_CHARSTRING) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
367 stc->universal_charstring_st = new UniversalCharstringSubtypeTreeElement(StringValueConstraint<ustring>(v->get_val_ustr()));
368 break;
369 case Value::V_ENUM:
370 case Value::V_NULL: // FIXME: should go to ST_NULL
371 if (st_t!=ST_ENUM) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
372 stc->value_st = new ValueListConstraint(v);
373 break;
374 case Value::V_CHOICE:
375 case Value::V_OPENTYPE: // FIXME?
376 if (st_t!=ST_UNION) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
377 stc->value_st = new ValueListConstraint(v);
378 break;
379 case Value::V_SEQ:
380 if (st_t!=ST_RECORD) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
381 stc->value_st = new ValueListConstraint(v);
382 break;
383 case Value::V_SET:
384 if (st_t!=ST_SET) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
385 stc->value_st = new ValueListConstraint(v);
386 break;
387 case Value::V_SEQOF:
388 if (st_t!=ST_RECORDOF) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
389 stc->recof_st = new RecofConstraint(v);
390 break;
391 case Value::V_SETOF:
392 if (st_t!=ST_SETOF) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
393 stc->recof_st = new RecofConstraint(v);
394 break;
395 default:
396 goto invalid_value;
397 }
398 return stc;
399 invalid_value:
400 delete stc;
401 return NULL;
402 }
403
404 SubtypeConstraint* SubtypeConstraint::create_from_asn_charvalues(Type* type, Value* value)
405 {
406 Value* v = value->get_value_refd_last();
407 subtype_t st_t = type->get_subtype_type();
408 if ( (st_t==ST_ERROR) || (v->get_valuetype()==Value::V_ERROR) ) return NULL;
409 SubtypeConstraint* stc = new SubtypeConstraint(st_t);
410 switch (v->get_valuetype()) {
411 case Value::V_CSTR:
412 case Value::V_ISO2022STR: {
413 if (st_t!=ST_CHARSTRING) FATAL_ERROR("SubtypeConstraint::create_from_asn_charvalues()");
414 CharRangeListConstraint charvalues;
415 string val_str = (v->get_valuetype()==Value::V_CSTR) ? v->get_val_str() : v->get_val_iso2022str();
416 for (size_t i=0; i<val_str.size(); i++) {
417 if (!char_limit_t::is_valid_value(val_str[i])) {
418 value->error("Invalid char in string %s at index %lu",
419 value->get_stringRepr().c_str(), (unsigned long)i);
420 goto invalid_value;
421 }
422 charvalues = charvalues + CharRangeListConstraint(val_str[i]);
423 }
424 stc->charstring_st = new CharstringSubtypeTreeElement(charvalues, true);
425 } break;
426 case Value::V_CHARSYMS: {
427 case Value::V_USTR:
428 if (st_t!=ST_UNIVERSAL_CHARSTRING) FATAL_ERROR("SubtypeConstraint::create_from_asn_charvalues()");
429 UniversalCharRangeListConstraint ucharvalues;
430 ustring val_ustr = v->get_val_ustr();
431 for (size_t i=0; i<val_ustr.size(); i++) {
432 if (!universal_char_limit_t::is_valid_value(val_ustr[i])) {
433 value->error("Invalid universal char in string %s at index %lu",
434 value->get_stringRepr().c_str(), (unsigned long)i);
435 goto invalid_value;
436 }
437 ucharvalues = ucharvalues + UniversalCharRangeListConstraint(val_ustr[i]);
438 }
439 stc->universal_charstring_st = new UniversalCharstringSubtypeTreeElement(ucharvalues, true);
440 } break;
441 default:
442 // error was already reported
443 goto invalid_value;
444 }
445 return stc;
446 invalid_value:
447 delete stc;
448 return NULL;
449 }
450
451 int_limit_t SubtypeConstraint::get_int_limit(bool is_upper, Location* loc)
452 {
453 int_limit_t default_limit = is_upper ?
454 int_limit_t::maximum :
455 ((subtype==ST_INTEGER) ? int_limit_t::minimum : int_limit_t(int_val_t((Int)0)));
456 switch (subtype) {
457 case ST_INTEGER:
458 if (integer_st) {
459 if (integer_st->is_empty()==TTRUE) {
460 loc->error("Cannot determine the value of %s: the parent subtype is an empty set.",
461 is_upper?"MAX":"MIN");
462 return default_limit;
463 } else {
464 return is_upper ? integer_st->get_maximal() : integer_st->get_minimal();
465 }
466 }
467 return default_limit;
468 case ST_BITSTRING:
469 if (bitstring_st) {
470 size_limit_t sl;
471 tribool tb = bitstring_st->get_size_limit(is_upper, sl);
472 if (tb==TTRUE) return sl.to_int_limit();
473 break;
474 }
475 return default_limit;
476 case ST_HEXSTRING:
477 if (hexstring_st) {
478 size_limit_t sl;
479 tribool tb = hexstring_st->get_size_limit(is_upper, sl);
480 if (tb==TTRUE) return sl.to_int_limit();
481 break;
482 }
483 return default_limit;
484 case ST_OCTETSTRING:
485 if (octetstring_st) {
486 size_limit_t sl;
487 tribool tb = octetstring_st->get_size_limit(is_upper, sl);
488 if (tb==TTRUE) return sl.to_int_limit();
489 break;
490 }
491 return default_limit;
492 case ST_CHARSTRING:
493 if (charstring_st) {
494 size_limit_t sl;
495 tribool tb = charstring_st->get_size_limit(is_upper, sl);
496 switch (tb) {
497 case TFALSE:
498 loc->error("Cannot determine the value of %s: the parent subtype does "
499 "not define a %simal size value", is_upper?"MAX":"MIN", is_upper?"max":"min");
500 break;
501 case TUNKNOWN:
502 loc->warning("Cannot determine the value of %s from parent subtype %s",
503 is_upper?"MAX":"MIN", to_string().c_str());
504 break;
505 case TTRUE:
506 return sl.to_int_limit();
507 default:
508 FATAL_ERROR("SubtypeConstraint::get_int_limit()");
509 }
510 }
511 return default_limit;
512 case ST_UNIVERSAL_CHARSTRING:
513 if (universal_charstring_st) {
514 size_limit_t sl;
515 tribool tb = universal_charstring_st->get_size_limit(is_upper, sl);
516 switch (tb) {
517 case TFALSE:
518 loc->error("Cannot determine the value of %s: the parent subtype does "
519 "not define a %simal size value", is_upper?"MAX":"MIN", is_upper?"max":"min");
520 break;
521 case TUNKNOWN:
522 loc->warning("Cannot determine the value of %s from parent subtype %s",
523 is_upper?"MAX":"MIN", to_string().c_str());
524 break;
525 case TTRUE:
526 return sl.to_int_limit();
527 default:
528 FATAL_ERROR("SubtypeConstraint::get_int_limit()");
529 }
530 }
531 return default_limit;
532 case ST_RECORDOF:
533 case ST_SETOF:
534 if (recof_st) {
535 size_limit_t sl;
536 tribool tb = recof_st->get_size_limit(is_upper, sl);
537 if (tb==TTRUE) return sl.to_int_limit();
538 break;
539 }
540 return default_limit;
541 default:
542 FATAL_ERROR("SubtypeConstraint::get_int_limit()");
543 }
544 loc->error("Cannot determine the value of %s from parent subtype %s",
545 is_upper?"MAX":"MIN", to_string().c_str());
546 return default_limit;
547 }
548
549 SubtypeConstraint* SubtypeConstraint::create_from_asn_range(
550 Value* vmin, bool min_exclusive, Value* vmax, bool max_exclusive,
551 Location* loc, subtype_t st_t, SubtypeConstraint* parent_subtype)
552 {
553 switch (st_t) {
554 case SubtypeConstraint::ST_INTEGER: {
555 if (((vmin!=NULL) && (vmin->get_valuetype()!=Value::V_INT)) ||
556 ((vmax!=NULL) && (vmax->get_valuetype()!=Value::V_INT))) return NULL;
557
558 int_limit_t min_limit;
559 if (vmin) {
560 min_limit = int_limit_t(*(vmin->get_val_Int()));
561 } else { // MIN was used
562 if (parent_subtype) {
563 min_limit = parent_subtype->get_int_limit(false, loc);
564 } else {
565 min_limit = int_limit_t::minimum;
566 }
567 }
568
569 if (min_exclusive) {
570 if (min_limit==int_limit_t::minimum) {
571 loc->error("invalid lower boundary, -infinity cannot be excluded from an INTEGER value range constraint");
572 return NULL;
573 } else {
574 min_limit = min_limit.next();
575 }
576 }
577
578 int_limit_t max_limit;
579 if (vmax) {
580 max_limit = int_limit_t(*(vmax->get_val_Int()));
581 } else { // MAX was used
582 if (parent_subtype) {
583 max_limit = parent_subtype->get_int_limit(true, loc);
584 } else {
585 max_limit = int_limit_t::maximum;
586 }
587 }
588
589 if (max_exclusive) {
590 if (max_limit==int_limit_t::maximum) {
591 loc->error("invalid upper boundary, infinity cannot be excluded from an INTEGER value range constraint");
592 return NULL;
593 } else {
594 max_limit = max_limit.previous();
595 }
596 }
597 if (max_limit<min_limit) {
598 loc->error("lower boundary is bigger than upper boundary in INTEGER value range constraint");
599 return NULL;
600 }
601 SubtypeConstraint* stc = new SubtypeConstraint(st_t);
602 stc->integer_st = new IntegerRangeListConstraint(min_limit, max_limit);
603 return stc;
604 } break;
605 case ST_FLOAT: {
606 if (((vmin!=NULL) && (vmin->get_valuetype()!=Value::V_REAL)) ||
607 ((vmax!=NULL) && (vmax->get_valuetype()!=Value::V_REAL))) return NULL;
608 if ((vmin!=NULL) && (vmin->get_val_Real()!=vmin->get_val_Real())) {
609 loc->error("lower boundary cannot be NOT-A-NUMBER in REAL value range constraint");
610 return NULL;
611 }
612 if ((vmax!=NULL) && (vmax->get_val_Real()!=vmax->get_val_Real())) {
613 loc->error("upper boundary cannot be NOT-A-NUMBER in REAL value range constraint");
614 return NULL;
615 }
616
617 if (parent_subtype && (parent_subtype->subtype!=ST_FLOAT)) FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
618 real_limit_t min_limit;
619 if (vmin) {
620 min_limit = real_limit_t(vmin->get_val_Real());
621 } else { // MIN was used
622 if (parent_subtype && parent_subtype->float_st) {
623 if (parent_subtype->float_st->is_range_empty()==TTRUE) {
624 loc->error("Cannot determine the value of MIN: the parent subtype has no range");
625 min_limit = real_limit_t::minimum;
626 } else {
627 min_limit = parent_subtype->float_st->get_minimal();
628 }
629 } else {
630 min_limit = real_limit_t::minimum;
631 }
632 }
633
634 if (min_exclusive) {
635 min_limit = min_limit.next();
636 }
637
638 real_limit_t max_limit;
639 if (vmax) {
640 max_limit = real_limit_t(vmax->get_val_Real());
641 } else { // MAX was used
642 if (parent_subtype && parent_subtype->float_st) {
643 if (parent_subtype->float_st->is_range_empty()==TTRUE) {
644 loc->error("Cannot determine the value of MAX: the parent subtype has no range");
645 max_limit = real_limit_t::maximum;
646 } else {
647 max_limit = parent_subtype->float_st->get_maximal();
648 }
649 } else {
650 max_limit = real_limit_t::maximum;
651 }
652 }
653
654 if (max_exclusive) {
655 max_limit = max_limit.previous();
656 }
657 if (max_limit<min_limit) {
658 loc->error("lower boundary is bigger than upper boundary in REAL value range constraint");
659 return NULL;
660 }
661 SubtypeConstraint* stc = new SubtypeConstraint(st_t);
662 stc->float_st = new RealRangeListConstraint(min_limit, max_limit);
663 return stc;
664 } break;
665 case ST_CHARSTRING: {
666 if (((vmin!=NULL) && (vmin->get_valuetype()!=Value::V_CSTR)) ||
667 ((vmax!=NULL) && (vmax->get_valuetype()!=Value::V_CSTR))) return NULL;
668 if (vmin && (vmin->get_val_str().size()!=1)) {
669 vmin->error("lower boundary of string value range constraint must be a single element string");
670 return NULL;
671 }
672 if (vmax && (vmax->get_val_str().size()!=1)) {
673 vmax->error("upper boundary of string value range constraint must be a single element string");
674 return NULL;
675 }
676 if (vmin && !char_limit_t::is_valid_value(*vmin->get_val_str().c_str())) {
677 vmin->error("lower boundary of string value range constraint is an invalid char");
678 return NULL;
679 }
680 if (vmax && !char_limit_t::is_valid_value(*vmax->get_val_str().c_str())) {
681 vmax->error("upper boundary of string value range constraint is an invalid char");
682 return NULL;
683 }
684
685 if (parent_subtype && (parent_subtype->subtype!=ST_CHARSTRING)) FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
686
687 char_limit_t min_limit;
688 if (vmin) {
689 min_limit = char_limit_t(*vmin->get_val_str().c_str());
690 } else { // MIN was used
691 if (parent_subtype && parent_subtype->charstring_st) {
692 tribool tb = parent_subtype->charstring_st->get_alphabet_limit(false, min_limit);
693 switch (tb) {
694 case TFALSE:
695 loc->error("Cannot determine the value of MIN: the parent subtype does not define a minimal char value");
696 min_limit = char_limit_t::minimum;
697 break;
698 case TUNKNOWN:
699 loc->warning("Cannot determine the value of MIN, using the minimal char value of the type");
700 min_limit = char_limit_t::minimum;
701 break;
702 case TTRUE:
703 // min_limit was set to the correct value
704 break;
705 default:
706 FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
707 }
708 } else {
709 min_limit = char_limit_t::minimum;
710 }
711 }
712
713 if (min_exclusive) {
714 if (min_limit==char_limit_t::maximum) {
715 loc->error("exclusive lower boundary is not a legal character");
716 return NULL;
717 }
718 min_limit = min_limit.next();
719 }
720
721 char_limit_t max_limit;
722 if (vmax) {
723 max_limit = char_limit_t(*vmax->get_val_str().c_str());
724 } else { // MAX was used
725 if (parent_subtype && parent_subtype->charstring_st) {
726 tribool tb = parent_subtype->charstring_st->get_alphabet_limit(true, max_limit);
727 switch (tb) {
728 case TFALSE:
729 loc->error("Cannot determine the value of MAX: the parent subtype does not define a maximal char value");
730 max_limit = char_limit_t::maximum;
731 break;
732 case TUNKNOWN:
733 loc->warning("Cannot determine the value of MAX, using the maximal char value of the type");
734 max_limit = char_limit_t::maximum;
735 break;
736 case TTRUE:
737 // max_limit was set to the correct value
738 break;
739 default:
740 FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
741 }
742 } else {
743 max_limit = char_limit_t::maximum;
744 }
745 }
746
747 if (max_exclusive) {
748 if (max_limit==char_limit_t::minimum) {
749 loc->error("exclusive upper boundary is not a legal character");
750 return NULL;
751 }
752 max_limit = max_limit.previous();
753 }
754 if (max_limit<min_limit) {
755 loc->error("lower boundary is bigger than upper boundary in string value range constraint");
756 return NULL;
757 }
758 SubtypeConstraint* stc = new SubtypeConstraint(st_t);
759 stc->charstring_st = new CharstringSubtypeTreeElement(CharRangeListConstraint(min_limit,max_limit), true);
760 return stc;
761 } break;
762 case ST_UNIVERSAL_CHARSTRING: {
763 if (((vmin!=NULL) && (vmin->get_valuetype()!=Value::V_USTR)) ||
764 ((vmax!=NULL) && (vmax->get_valuetype()!=Value::V_USTR))) return NULL;
765 if (vmin && (vmin->get_val_ustr().size()!=1)) {
766 vmin->error("lower boundary of string value range constraint must be a single element string");
767 return NULL;
768 }
769 if (vmax && (vmax->get_val_ustr().size()!=1)) {
770 vmax->error("upper boundary of string value range constraint must be a single element string");
771 return NULL;
772 }
773 if (vmin && !universal_char_limit_t::is_valid_value(*vmin->get_val_ustr().u_str())) {
774 vmin->error("lower boundary of string value range constraint is an invalid universal char");
775 return NULL;
776 }
777 if (vmax && !universal_char_limit_t::is_valid_value(*vmax->get_val_ustr().u_str())) {
778 vmax->error("upper boundary of string value range constraint is an invalid universal char");
779 return NULL;
780 }
781
782 if (parent_subtype && (parent_subtype->subtype!=ST_UNIVERSAL_CHARSTRING)) FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
783 universal_char_limit_t min_limit;
784 if (vmin) {
785 min_limit = universal_char_limit_t(*vmin->get_val_ustr().u_str());
786 } else { // MIN was used
787 if (parent_subtype && parent_subtype->universal_charstring_st) {
788 tribool tb = parent_subtype->universal_charstring_st->get_alphabet_limit(false, min_limit);
789 switch (tb) {
790 case TFALSE:
791 loc->error("Cannot determine the value of MIN: the parent subtype does not define a minimal char value");
792 min_limit = universal_char_limit_t::minimum;
793 break;
794 case TUNKNOWN:
795 loc->warning("Cannot determine the value of MIN, using the minimal char value of the type");
796 min_limit = universal_char_limit_t::minimum;
797 break;
798 case TTRUE:
799 // min_limit was set to the correct value
800 break;
801 default:
802 FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
803 }
804 } else {
805 min_limit = universal_char_limit_t::minimum;
806 }
807 }
808
809 if (min_exclusive) {
810 if (min_limit==universal_char_limit_t::maximum) {
811 loc->error("exclusive lower boundary is not a legal character");
812 return NULL;
813 }
814 min_limit = min_limit.next();
815 }
816
817 universal_char_limit_t max_limit;
818 if (vmax) {
819 max_limit = universal_char_limit_t(*vmax->get_val_ustr().u_str());
820 } else { // MAX was used
821 if (parent_subtype && parent_subtype->universal_charstring_st) {
822 tribool tb = parent_subtype->universal_charstring_st->get_alphabet_limit(true, max_limit);
823 switch (tb) {
824 case TFALSE:
825 loc->error("Cannot determine the value of MAX: the parent subtype does not define a maximal char value");
826 max_limit = universal_char_limit_t::maximum;
827 break;
828 case TUNKNOWN:
829 loc->warning("Cannot determine the value of MAX, using the maximal char value of the type");
830 max_limit = universal_char_limit_t::maximum;
831 break;
832 case TTRUE:
833 // max_limit was set to the correct value
834 break;
835 default:
836 FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
837 }
838 } else {
839 max_limit = universal_char_limit_t::maximum;
840 }
841 }
842
843 if (max_exclusive) {
844 if (max_limit==universal_char_limit_t::minimum) {
845 loc->error("exclusive upper boundary is not a legal character");
846 return NULL;
847 }
848 max_limit = max_limit.previous();
849 }
850 if (max_limit<min_limit) {
851 loc->error("lower boundary is bigger than upper boundary in string value range constraint");
852 return NULL;
853 }
854 SubtypeConstraint* stc = new SubtypeConstraint(st_t);
855 stc->universal_charstring_st = new UniversalCharstringSubtypeTreeElement(UniversalCharRangeListConstraint(min_limit,max_limit), true);
856 return stc;
857 } break;
858 default:
859 FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
860 }
861 return NULL;
862 }
863
864 SubtypeConstraint* SubtypeConstraint::create_from_contained_subtype(SubtypeConstraint* contained_stc, bool char_context, Location* loc)
865 {
866 if (contained_stc==NULL) return NULL;
867 SubtypeConstraint* rv_stc = NULL;
868 if (char_context) {
869 switch (contained_stc->get_subtypetype()) {
870 case ST_CHARSTRING:
871 if (contained_stc->charstring_st==NULL) {
872 rv_stc = new SubtypeConstraint(contained_stc->get_subtypetype()); // full set
873 } else {
874 if (contained_stc->charstring_st->is_valid_range()) {
875 rv_stc = new SubtypeConstraint(contained_stc->get_subtypetype());
876 rv_stc->copy(contained_stc);
877 rv_stc->charstring_st->set_char_context(true);
878 } else {
879 loc->error("The type of the contained subtype constraint cannot be used in a permitted alphabet constraint");
880 }
881 }
882 break;
883 case ST_UNIVERSAL_CHARSTRING:
884 if (contained_stc->universal_charstring_st==NULL) {
885 rv_stc = new SubtypeConstraint(contained_stc->get_subtypetype()); // full set
886 } else {
887 if (contained_stc->universal_charstring_st->is_valid_range()) {
888 rv_stc = new SubtypeConstraint(contained_stc->get_subtypetype());
889 rv_stc->copy(contained_stc);
890 rv_stc->universal_charstring_st->set_char_context(true);
891 } else {
892 loc->error("The type of the contained subtype constraint cannot be used in a permitted alphabet constraint");
893 }
894 }
895 break;
896 default:
897 // error was already reported
898 break;
899 }
900 } else {
901 rv_stc = new SubtypeConstraint(contained_stc->get_subtypetype());
902 rv_stc->copy(contained_stc);
903 }
904 return rv_stc;
905 }
906
907 SubtypeConstraint* SubtypeConstraint::create_asn_size_constraint(
908 SubtypeConstraint* integer_stc, bool char_context, Type* type, Location* loc)
909 {
910 if (integer_stc==NULL) return NULL;
911 // convert IntegerRangeListConstraint to SizeRangeListConstraint
912 if (integer_stc->subtype!=ST_INTEGER) FATAL_ERROR("SubtypeConstraint::create_asn_size_constraint()");
913 SizeRangeListConstraint size_constraint(size_limit_t::minimum, size_limit_t::maximum);
914 if (integer_stc->integer_st) {
915 static const int_val_t zero((Int)0);
916 static const int_limit_t ilt0(zero);
917 IntegerRangeListConstraint valid_range(ilt0, int_limit_t::maximum);
918 if (integer_stc->integer_st->is_subset(valid_range)==TFALSE) {
919 loc->error("Range %s is not a valid range for a size constraint", integer_stc->to_string().c_str());
920 } else {
921 bool success = convert_int_to_size(*(integer_stc->integer_st), size_constraint);
922 if (!success) {
923 loc->error("One or more INTEGER values of range %s are too large to be used in a size constraint", integer_stc->to_string().c_str());
924 }
925 }
926 }
927 subtype_t st_t = type->get_subtype_type();
928 if (st_t==ST_ERROR) return NULL;
929 SubtypeConstraint* stc = new SubtypeConstraint(st_t);
930
931 if (!char_context) {
932 stc->length_restriction = new SizeRangeListConstraint(size_constraint); // FIXME? : is this Ok if not a top level constraint?
933 }
934
935 switch (st_t) {
936 case ST_BITSTRING:
937 stc->bitstring_st = new BitstringConstraint(size_constraint);
938 break;
939 case ST_HEXSTRING:
940 stc->hexstring_st = new HexstringConstraint(size_constraint);
941 break;
942 case ST_OCTETSTRING:
943 stc->octetstring_st = new OctetstringConstraint(size_constraint);
944 break;
945 case ST_CHARSTRING:
946 if (char_context) {
947 if (size_constraint.is_equal(SizeRangeListConstraint(size_limit_t(1)))==TFALSE) {
948 loc->error("Only SIZE(1) constraint can be used inside a permitted alphabet constraint");
949 delete stc;
950 return NULL;
951 }
952 // SIZE(1) is allowed in char context, it means ALL
953 } else {
954 stc->charstring_st = new CharstringSubtypeTreeElement(size_constraint);
955 }
956 break;
957 case ST_UNIVERSAL_CHARSTRING:
958 if (char_context) {
959 if (size_constraint.is_equal(SizeRangeListConstraint(size_limit_t(1)))==TFALSE) {
960 loc->error("Only SIZE(1) constraint can be used inside a permitted alphabet constraint");
961 delete stc;
962 return NULL;
963 }
964 // SIZE(1) is allowed in char context, it means ALL
965 } else {
966 stc->universal_charstring_st = new UniversalCharstringSubtypeTreeElement(size_constraint);
967 }
968 break;
969 case ST_RECORDOF:
970 case ST_SETOF:
971 stc->recof_st = new RecofConstraint(size_constraint);
972 break;
973 default:
974 loc->error("Size constraint is not allowed for type `%s'", type->get_typename().c_str());
975 delete stc;
976 return NULL;
977 }
978 return stc;
979 }
980
981 SubtypeConstraint* SubtypeConstraint::create_permitted_alphabet_constraint(
982 SubtypeConstraint* stc, bool char_context, Type* type, Location* loc)
983 {
984 if (char_context) {
985 loc->error("Permitted alphabet constraint not allowed inside a permitted alphabet constraint");
986 return NULL;
987 }
988 subtype_t st_t = type->get_subtype_type();
989 switch (st_t) {
990 case ST_CHARSTRING:
991 case ST_UNIVERSAL_CHARSTRING: {
992 if (stc==NULL) return NULL; // error was reported there
993 if (st_t!=stc->get_subtypetype()) FATAL_ERROR("SubtypeConstraint::create_permitted_alphabet_constraint()");
994 SubtypeConstraint* rv_stc = new SubtypeConstraint(st_t);
995 if (st_t==ST_CHARSTRING) {
996 if (stc->charstring_st) {
997 rv_stc->charstring_st = new CharstringSubtypeTreeElement(*(stc->charstring_st));
998 rv_stc->charstring_st->set_char_context(false);
999 }
1000 } else {
1001 if (stc->universal_charstring_st) {
1002 rv_stc->universal_charstring_st = new UniversalCharstringSubtypeTreeElement(*(stc->universal_charstring_st));
1003 rv_stc->universal_charstring_st->set_char_context(false);
1004 }
1005 }
1006 return rv_stc;
1007 } break;
1008 case ST_ERROR:
1009 // error already reported
1010 break;
1011 default:
1012 loc->error("Permitted alphabet constraint is not allowed for type `%s'", type->get_typename().c_str());
1013 break;
1014 }
1015 return NULL;
1016 }
1017
1018 void SubtypeConstraint::set_to_error()
1019 {
1020 switch (subtype) {
1021 case ST_ERROR:
1022 break;
1023 case ST_INTEGER:
1024 delete integer_st;
1025 break;
1026 case ST_FLOAT:
1027 delete float_st;
1028 break;
1029 case ST_BOOLEAN:
1030 delete boolean_st;
1031 break;
1032 case ST_VERDICTTYPE:
1033 delete verdict_st;
1034 break;
1035 case ST_BITSTRING:
1036 delete bitstring_st;
1037 break;
1038 case ST_HEXSTRING:
1039 delete hexstring_st;
1040 break;
1041 case ST_OCTETSTRING:
1042 delete octetstring_st;
1043 break;
1044 case ST_CHARSTRING:
1045 delete charstring_st;
1046 break;
1047 case ST_UNIVERSAL_CHARSTRING:
1048 delete universal_charstring_st;
1049 break;
1050 case ST_OBJID:
1051 case ST_RECORD:
1052 case ST_SET:
1053 case ST_ENUM:
1054 case ST_UNION:
1055 case ST_FUNCTION:
1056 case ST_ALTSTEP:
1057 case ST_TESTCASE:
1058 delete value_st;
1059 break;
1060 case ST_RECORDOF:
1061 case ST_SETOF:
1062 delete recof_st;
1063 break;
1064 default:
1065 FATAL_ERROR("SubtypeConstraint::set_to_error()");
1066 }
1067 subtype = ST_ERROR;
1068 delete length_restriction;
1069 length_restriction = NULL;
1070 }
1071
1072 string SubtypeConstraint::to_string() const
1073 {
1074 switch (subtype) {
1075 case ST_ERROR:
1076 return string("<error>");
1077 case ST_INTEGER:
1078 return (integer_st==NULL) ? string() : integer_st->to_string();
1079 case ST_FLOAT:
1080 return (float_st==NULL) ? string() : float_st->to_string();
1081 case ST_BOOLEAN:
1082 return (boolean_st==NULL) ? string() : boolean_st->to_string();
1083 case ST_VERDICTTYPE:
1084 return (verdict_st==NULL) ? string() : verdict_st->to_string();
1085 case ST_BITSTRING:
1086 return (bitstring_st==NULL) ? string() : bitstring_st->to_string();
1087 case ST_HEXSTRING:
1088 return (hexstring_st==NULL) ? string() : hexstring_st->to_string();
1089 case ST_OCTETSTRING:
1090 return (octetstring_st==NULL) ? string() : octetstring_st->to_string();
1091 case ST_CHARSTRING:
1092 return (charstring_st==NULL) ? string() : charstring_st->to_string();
1093 case ST_UNIVERSAL_CHARSTRING:
1094 return (universal_charstring_st==NULL) ? string() : universal_charstring_st->to_string();
1095 case ST_OBJID:
1096 case ST_RECORD:
1097 case ST_SET:
1098 case ST_ENUM:
1099 case ST_UNION:
1100 case ST_FUNCTION:
1101 case ST_ALTSTEP:
1102 case ST_TESTCASE:
1103 return (value_st==NULL) ? string() : value_st->to_string();
1104 case ST_RECORDOF:
1105 case ST_SETOF:
1106 return (recof_st==NULL) ? string() : recof_st->to_string();
1107 default:
1108 FATAL_ERROR("SubtypeConstraint::to_string()");
1109 }
1110 }
1111
1112 bool SubtypeConstraint::is_compatible(const SubtypeConstraint *p_st) const
1113 {
1114 if (p_st==NULL) return true; // the other type has no subtype restriction
1115 if ( (subtype==ST_ERROR) || (p_st->subtype==ST_ERROR) ) return true;
1116 if (subtype!=p_st->subtype) FATAL_ERROR("SubtypeConstraint::is_compatible()");
1117 // if the resulting set.is_empty()==TUNKNOWN then remain silent
1118 switch (subtype) {
1119 case ST_INTEGER:
1120 if ((integer_st==NULL) || (p_st->integer_st==NULL)) return true;
1121 return ((*integer_st**(p_st->integer_st)).is_empty()!=TTRUE);
1122 case ST_FLOAT:
1123 if ((float_st==NULL) || (p_st->float_st==NULL)) return true;
1124 return ((*float_st**(p_st->float_st)).is_empty()!=TTRUE);
1125 case ST_BOOLEAN:
1126 if ((boolean_st==NULL) || (p_st->boolean_st==NULL)) return true;
1127 return ((*boolean_st**(p_st->boolean_st)).is_empty()!=TTRUE);
1128 case ST_VERDICTTYPE:
1129 if ((verdict_st==NULL) || (p_st->verdict_st==NULL)) return true;
1130 return ((*verdict_st**(p_st->verdict_st)).is_empty()!=TTRUE);
1131 case ST_BITSTRING:
1132 if ((bitstring_st==NULL) || (p_st->bitstring_st==NULL)) return true;
1133 return ((*bitstring_st**(p_st->bitstring_st)).is_empty()!=TTRUE);
1134 case ST_HEXSTRING:
1135 if ((hexstring_st==NULL) || (p_st->hexstring_st==NULL)) return true;
1136 return ((*hexstring_st**(p_st->hexstring_st)).is_empty()!=TTRUE);
1137 case ST_OCTETSTRING:
1138 if ((octetstring_st==NULL) || (p_st->octetstring_st==NULL)) return true;
1139 return ((*octetstring_st**(p_st->octetstring_st)).is_empty()!=TTRUE);
1140 case ST_CHARSTRING: {
1141 if ((charstring_st==NULL) || (p_st->charstring_st==NULL)) return true;
1142 CharstringSubtypeTreeElement* cc = new CharstringSubtypeTreeElement(
1143 CharstringSubtypeTreeElement::ET_INTERSECTION,
1144 new CharstringSubtypeTreeElement(*charstring_st),
1145 new CharstringSubtypeTreeElement(*(p_st->charstring_st))
1146 );
1147 bool rv = (cc->is_empty()!=TTRUE);
1148 delete cc;
1149 return rv;
1150 }
1151 case ST_UNIVERSAL_CHARSTRING: {
1152 if ((universal_charstring_st==NULL) || (p_st->universal_charstring_st==NULL)) return true;
1153 UniversalCharstringSubtypeTreeElement* ucc = new UniversalCharstringSubtypeTreeElement(
1154 UniversalCharstringSubtypeTreeElement::ET_INTERSECTION,
1155 new UniversalCharstringSubtypeTreeElement(*universal_charstring_st),
1156 new UniversalCharstringSubtypeTreeElement(*(p_st->universal_charstring_st))
1157 );
1158 bool rv = (ucc->is_empty()!=TTRUE);
1159 delete ucc;
1160 return rv;
1161 }
1162 case ST_OBJID:
1163 case ST_RECORD:
1164 case ST_SET:
1165 case ST_ENUM:
1166 case ST_UNION:
1167 case ST_FUNCTION:
1168 case ST_ALTSTEP:
1169 case ST_TESTCASE:
1170 if ((value_st==NULL) || (p_st->value_st==NULL)) return true;
1171 return ((*value_st**(p_st->value_st)).is_empty()!=TTRUE);
1172 case ST_RECORDOF:
1173 case ST_SETOF:
1174 if ((recof_st==NULL) || (p_st->recof_st==NULL)) return true;
1175 return ((*recof_st**(p_st->recof_st)).is_empty()!=TTRUE);
1176 default:
1177 FATAL_ERROR("SubtypeConstraint::is_compatible()");
1178 }
1179 return true;
1180 }
1181
1182 bool SubtypeConstraint::is_compatible_with_elem() const
1183 {
1184 if (subtype==ST_ERROR) return true;
1185 switch (subtype) {
1186 case ST_BITSTRING: {
1187 static BitstringConstraint str_elem(size_limit_t(1));
1188 if (bitstring_st==NULL) return true;
1189 return ((*bitstring_st*str_elem).is_empty()!=TTRUE);
1190 }
1191 case ST_HEXSTRING: {
1192 static HexstringConstraint str_elem(size_limit_t(1));
1193 if (hexstring_st==NULL) return true;
1194 return ((*hexstring_st*str_elem).is_empty()!=TTRUE);
1195 }
1196 case ST_OCTETSTRING: {
1197 static OctetstringConstraint str_elem(size_limit_t(1));
1198 if (octetstring_st==NULL) return true;
1199 return ((*octetstring_st*str_elem).is_empty()!=TTRUE);
1200 }
1201 case ST_CHARSTRING: {
1202 size_limit_t t = size_limit_t(1);
1203 SizeRangeListConstraint temp = SizeRangeListConstraint(t);
1204 static CharstringSubtypeTreeElement str_elem(temp);
1205 if (charstring_st==NULL) return true;
1206 CharstringSubtypeTreeElement* cc = new CharstringSubtypeTreeElement(
1207 CharstringSubtypeTreeElement::ET_INTERSECTION,
1208 new CharstringSubtypeTreeElement(*charstring_st),
1209 new CharstringSubtypeTreeElement(str_elem)
1210 );
1211 bool rv = (cc->is_empty()!=TTRUE);
1212 delete cc;
1213 return rv;
1214 }
1215 case ST_UNIVERSAL_CHARSTRING: {
1216 size_limit_t t = size_limit_t(1);
1217 SizeRangeListConstraint temp = SizeRangeListConstraint(t);
1218 static UniversalCharstringSubtypeTreeElement str_elem(temp);
1219 if (universal_charstring_st==NULL) return true;
1220 UniversalCharstringSubtypeTreeElement* ucc = new UniversalCharstringSubtypeTreeElement(
1221 UniversalCharstringSubtypeTreeElement::ET_INTERSECTION,
1222 new UniversalCharstringSubtypeTreeElement(*universal_charstring_st),
1223 new UniversalCharstringSubtypeTreeElement(str_elem)
1224 );
1225 bool rv = (ucc->is_empty()!=TTRUE);
1226 delete ucc;
1227 return rv;
1228 }
1229 default:
1230 FATAL_ERROR("SubtypeConstraint::is_compatible_with_elem()");
1231 }
1232 return true;
1233 }
1234
1235 bool SubtypeConstraint::is_length_compatible(const SubtypeConstraint *p_st) const
1236 {
1237 if (p_st==NULL) FATAL_ERROR("SubtypeConstraint::is_length_compatible()");
1238 if ((subtype==ST_ERROR) || (p_st->subtype==ST_ERROR)) return true;
1239 if (subtype != ST_RECORDOF && subtype != ST_SETOF &&
1240 p_st->subtype != ST_RECORDOF && p_st->subtype != ST_SETOF)
1241 FATAL_ERROR("SubtypeConstraint::is_length_compatible()");
1242 if (length_restriction==NULL || p_st->length_restriction==NULL) return true;
1243 return ((*length_restriction * *(p_st->length_restriction)).is_empty()!=TTRUE);
1244 }
1245
1246 bool SubtypeConstraint::is_upper_limit_infinity() const
1247 {
1248 if (ST_INTEGER == subtype && integer_st) {
1249 return integer_st->is_upper_limit_infinity();
1250 }
1251 if (ST_FLOAT == subtype && float_st) {
1252 return float_st->is_upper_limit_infinity();
1253 }
1254 return false;
1255 }
1256
1257 bool SubtypeConstraint::is_lower_limit_infinity() const
1258 {
1259 if (ST_INTEGER == subtype && integer_st) {
1260 return integer_st->is_lower_limit_infinity();
1261 }
1262
1263 if (ST_FLOAT == subtype && float_st) {
1264 return float_st->is_lower_limit_infinity();
1265 }
1266 return false;
1267 }
1268
1269
1270 void SubtypeConstraint::except(const SubtypeConstraint* other)
1271 {
1272 if (other==NULL) FATAL_ERROR("SubtypeConstraint::except()");
1273 if (subtype!=other->subtype) FATAL_ERROR("SubtypeConstraint::except()");
1274 switch (subtype) {
1275 case ST_INTEGER:
1276 if (other->integer_st==NULL) {
1277 if (integer_st==NULL) {
1278 integer_st = new IntegerRangeListConstraint();
1279 } else {
1280 *integer_st = IntegerRangeListConstraint();
1281 }
1282 } else {
1283 if (integer_st==NULL) {
1284 integer_st = new IntegerRangeListConstraint(~*(other->integer_st));
1285 } else {
1286 *integer_st = *integer_st - *(other->integer_st);
1287 }
1288 }
1289 break;
1290 case ST_FLOAT:
1291 if (other->float_st==NULL) {
1292 if (float_st==NULL) {
1293 float_st = new RealRangeListConstraint();
1294 } else {
1295 *float_st = RealRangeListConstraint();
1296 }
1297 } else {
1298 if (float_st==NULL) {
1299 float_st = new RealRangeListConstraint(~*(other->float_st));
1300 } else {
1301 *float_st = *float_st - *(other->float_st);
1302 }
1303 }
1304 break;
1305 case ST_BOOLEAN:
1306 if (other->boolean_st==NULL) {
1307 if (boolean_st==NULL) {
1308 boolean_st = new BooleanListConstraint();
1309 } else {
1310 *boolean_st = BooleanListConstraint();
1311 }
1312 } else {
1313 if (boolean_st==NULL) {
1314 boolean_st = new BooleanListConstraint(~*(other->boolean_st));
1315 } else {
1316 *boolean_st = *boolean_st - *(other->boolean_st);
1317 }
1318 }
1319 break;
1320 case ST_VERDICTTYPE:
1321 if (other->verdict_st==NULL) {
1322 if (verdict_st==NULL) {
1323 verdict_st = new VerdicttypeListConstraint();
1324 } else {
1325 *verdict_st = VerdicttypeListConstraint();
1326 }
1327 } else {
1328 if (verdict_st==NULL) {
1329 verdict_st = new VerdicttypeListConstraint(~*(other->verdict_st));
1330 } else {
1331 *verdict_st = *verdict_st - *(other->verdict_st);
1332 }
1333 }
1334 break;
1335 case ST_BITSTRING:
1336 if (other->bitstring_st==NULL) {
1337 if (bitstring_st==NULL) {
1338 bitstring_st = new BitstringConstraint();
1339 } else {
1340 *bitstring_st = BitstringConstraint();
1341 }
1342 } else {
1343 if (bitstring_st==NULL) {
1344 bitstring_st = new BitstringConstraint(~*(other->bitstring_st));
1345 } else {
1346 *bitstring_st = *bitstring_st - *(other->bitstring_st);
1347 }
1348 }
1349 break;
1350 case ST_HEXSTRING:
1351 if (other->hexstring_st==NULL) {
1352 if (hexstring_st==NULL) {
1353 hexstring_st = new HexstringConstraint();
1354 } else {
1355 *hexstring_st = HexstringConstraint();
1356 }
1357 } else {
1358 if (hexstring_st==NULL) {
1359 hexstring_st = new HexstringConstraint(~*(other->hexstring_st));
1360 } else {
1361 *hexstring_st = *hexstring_st - *(other->hexstring_st);
1362 }
1363 }
1364 break;
1365 case ST_OCTETSTRING:
1366 if (other->octetstring_st==NULL) {
1367 if (octetstring_st==NULL) {
1368 octetstring_st = new OctetstringConstraint();
1369 } else {
1370 *octetstring_st = OctetstringConstraint();
1371 }
1372 } else {
1373 if (octetstring_st==NULL) {
1374 octetstring_st = new OctetstringConstraint(~*(other->octetstring_st));
1375 } else {
1376 *octetstring_st = *octetstring_st - *(other->octetstring_st);
1377 }
1378 }
1379 break;
1380 case ST_CHARSTRING:
1381 if (other->charstring_st==NULL) {
1382 if (charstring_st==NULL) {
1383 charstring_st = new CharstringSubtypeTreeElement();
1384 } else {
1385 *charstring_st = CharstringSubtypeTreeElement();
1386 }
1387 } else {
1388 if (charstring_st==NULL) {
1389 CharstringSubtypeTreeElement* call_st = new CharstringSubtypeTreeElement();
1390 call_st->set_all();
1391 charstring_st = new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_EXCEPT,
1392 call_st, new CharstringSubtypeTreeElement(*(other->charstring_st)));
1393 } else {
1394 charstring_st = new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_EXCEPT,
1395 charstring_st, new CharstringSubtypeTreeElement(*(other->charstring_st)));
1396 }
1397 }
1398 break;
1399 case ST_UNIVERSAL_CHARSTRING:
1400 if (other->universal_charstring_st==NULL) {
1401 if (universal_charstring_st==NULL) {
1402 universal_charstring_st = new UniversalCharstringSubtypeTreeElement();
1403 } else {
1404 *universal_charstring_st = UniversalCharstringSubtypeTreeElement();
1405 }
1406 } else {
1407 if (universal_charstring_st==NULL) {
1408 UniversalCharstringSubtypeTreeElement* ucall_st = new UniversalCharstringSubtypeTreeElement();
1409 ucall_st->set_all();
1410 universal_charstring_st = new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_EXCEPT,
1411 ucall_st, new UniversalCharstringSubtypeTreeElement(*(other->universal_charstring_st)));
1412 } else {
1413 universal_charstring_st = new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_EXCEPT,
1414 universal_charstring_st, new UniversalCharstringSubtypeTreeElement(*(other->universal_charstring_st)));
1415 }
1416 }
1417 break;
1418 case ST_OBJID:
1419 case ST_RECORD:
1420 case ST_SET:
1421 case ST_ENUM:
1422 case ST_UNION:
1423 case ST_FUNCTION:
1424 case ST_ALTSTEP:
1425 case ST_TESTCASE:
1426 if (other->value_st==NULL) {
1427 if (value_st==NULL) {
1428 value_st = new ValueListConstraint();
1429 } else {
1430 *value_st = ValueListConstraint();
1431 }
1432 } else {
1433 if (value_st==NULL) {
1434 value_st = new ValueListConstraint(~*(other->value_st));
1435 } else {
1436 *value_st = *value_st - *(other->value_st);
1437 }
1438 }
1439 break;
1440 case ST_RECORDOF:
1441 case ST_SETOF:
1442 if (other->recof_st==NULL) {
1443 if (recof_st==NULL) {
1444 recof_st = new RecofConstraint();
1445 } else {
1446 *recof_st = RecofConstraint();
1447 }
1448 } else {
1449 if (recof_st==NULL) {
1450 recof_st = new RecofConstraint(~*(other->recof_st));
1451 } else {
1452 *recof_st = *recof_st - *(other->recof_st);
1453 }
1454 }
1455 break;
1456 default:
1457 FATAL_ERROR("SubtypeConstraint::except()");
1458 }
1459 if (other->length_restriction==NULL) {
1460 if (length_restriction==NULL) {
1461 length_restriction = new SizeRangeListConstraint();
1462 } else {
1463 *length_restriction = SizeRangeListConstraint();
1464 }
1465 } else {
1466 if (length_restriction==NULL) {
1467 length_restriction = new SizeRangeListConstraint(~*(other->length_restriction));
1468 } else {
1469 *length_restriction = *length_restriction - *(other->length_restriction);
1470 }
1471 }
1472 }
1473
1474 void SubtypeConstraint::union_(const SubtypeConstraint* other)
1475 {
1476 if (other==NULL) FATAL_ERROR("SubtypeConstraint::union_()");
1477 if (subtype!=other->subtype) FATAL_ERROR("SubtypeConstraint::union_()");
1478 switch (subtype) {
1479 case ST_INTEGER:
1480 if (integer_st==NULL) break;
1481 if (other->integer_st==NULL) { delete integer_st; integer_st = NULL; break; }
1482 *integer_st = *integer_st + *(other->integer_st);
1483 break;
1484 case ST_FLOAT:
1485 if (float_st==NULL) break;
1486 if (other->float_st==NULL) { delete float_st; float_st = NULL; break; }
1487 *float_st = *float_st + *(other->float_st);
1488 break;
1489 case ST_BOOLEAN:
1490 if (boolean_st==NULL) break;
1491 if (other->boolean_st==NULL) { delete boolean_st; boolean_st = NULL; break; }
1492 *boolean_st = *boolean_st + *(other->boolean_st);
1493 break;
1494 case ST_VERDICTTYPE:
1495 if (verdict_st==NULL) break;
1496 if (other->verdict_st==NULL) { delete verdict_st; verdict_st = NULL; break; }
1497 *verdict_st = *verdict_st + *(other->verdict_st);
1498 break;
1499 case ST_BITSTRING:
1500 if (bitstring_st==NULL) break;
1501 if (other->bitstring_st==NULL) { delete bitstring_st; bitstring_st = NULL; break; }
1502 *bitstring_st = *bitstring_st + *(other->bitstring_st);
1503 break;
1504 case ST_HEXSTRING:
1505 if (hexstring_st==NULL) break;
1506 if (other->hexstring_st==NULL) { delete hexstring_st; hexstring_st = NULL; break; }
1507 *hexstring_st = *hexstring_st + *(other->hexstring_st);
1508 break;
1509 case ST_OCTETSTRING:
1510 if (octetstring_st==NULL) break;
1511 if (other->octetstring_st==NULL) { delete octetstring_st; octetstring_st = NULL; break; }
1512 *octetstring_st = *octetstring_st + *(other->octetstring_st);
1513 break;
1514 case ST_CHARSTRING:
1515 if (charstring_st==NULL) break;
1516 if (other->charstring_st==NULL) { delete charstring_st; charstring_st = NULL; break; }
1517 charstring_st = new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_UNION,
1518 charstring_st, new CharstringSubtypeTreeElement(*(other->charstring_st)));
1519 break;
1520 case ST_UNIVERSAL_CHARSTRING:
1521 if (universal_charstring_st==NULL) break;
1522 if (other->universal_charstring_st==NULL) { delete universal_charstring_st; universal_charstring_st = NULL; break; }
1523 universal_charstring_st = new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_UNION,
1524 universal_charstring_st, new UniversalCharstringSubtypeTreeElement(*(other->universal_charstring_st)));
1525 break;
1526 case ST_OBJID:
1527 case ST_RECORD:
1528 case ST_SET:
1529 case ST_ENUM:
1530 case ST_UNION:
1531 case ST_FUNCTION:
1532 case ST_ALTSTEP:
1533 case ST_TESTCASE:
1534 if (value_st==NULL) break;
1535 if (other->value_st==NULL) { delete value_st; value_st = NULL; break; }
1536 *value_st = *value_st + *(other->value_st);
1537 break;
1538 case ST_RECORDOF:
1539 case ST_SETOF:
1540 if (recof_st==NULL) break;
1541 if (other->recof_st==NULL) { delete recof_st; recof_st = NULL; break; }
1542 *recof_st = *recof_st + *(other->recof_st);
1543 break;
1544 default:
1545 FATAL_ERROR("SubtypeConstraint::union_()");
1546 }
1547 if (length_restriction!=NULL) {
1548 if (other->length_restriction==NULL) {
1549 delete length_restriction;
1550 length_restriction = NULL;
1551 } else {
1552 *length_restriction = *length_restriction + *(other->length_restriction);
1553 }
1554 }
1555 }
1556
1557 void SubtypeConstraint::intersection(const SubtypeConstraint* other)
1558 {
1559 if (other==NULL) FATAL_ERROR("SubtypeConstraint::intersection()");
1560 if (subtype!=other->subtype) FATAL_ERROR("SubtypeConstraint::intersection()");
1561 switch (subtype) {
1562 case ST_INTEGER:
1563 if (other->integer_st!=NULL) {
1564 if (integer_st==NULL) {
1565 integer_st = new IntegerRangeListConstraint(*(other->integer_st));
1566 } else {
1567 *integer_st = *integer_st * *(other->integer_st);
1568 }
1569 }
1570 break;
1571 case ST_FLOAT:
1572 if (other->float_st!=NULL) {
1573 if (float_st==NULL) {
1574 float_st = new RealRangeListConstraint(*(other->float_st));
1575 } else {
1576 *float_st = *float_st * *(other->float_st);
1577 }
1578 }
1579 break;
1580 case ST_BOOLEAN:
1581 if (other->boolean_st!=NULL) {
1582 if (boolean_st==NULL) {
1583 boolean_st = new BooleanListConstraint(*(other->boolean_st));
1584 } else {
1585 *boolean_st = *boolean_st * *(other->boolean_st);
1586 }
1587 }
1588 break;
1589 case ST_VERDICTTYPE:
1590 if (other->verdict_st!=NULL) {
1591 if (verdict_st==NULL) {
1592 verdict_st = new VerdicttypeListConstraint(*(other->verdict_st));
1593 } else {
1594 *verdict_st = *verdict_st * *(other->verdict_st);
1595 }
1596 }
1597 break;
1598 case ST_BITSTRING:
1599 if (other->bitstring_st!=NULL) {
1600 if (bitstring_st==NULL) {
1601 bitstring_st = new BitstringConstraint(*(other->bitstring_st));
1602 } else {
1603 *bitstring_st = *bitstring_st * *(other->bitstring_st);
1604 }
1605 }
1606 break;
1607 case ST_HEXSTRING:
1608 if (other->hexstring_st!=NULL) {
1609 if (hexstring_st==NULL) {
1610 hexstring_st = new HexstringConstraint(*(other->hexstring_st));
1611 } else {
1612 *hexstring_st = *hexstring_st * *(other->hexstring_st);
1613 }
1614 }
1615 break;
1616 case ST_OCTETSTRING:
1617 if (other->octetstring_st!=NULL) {
1618 if (octetstring_st==NULL) {
1619 octetstring_st = new OctetstringConstraint(*(other->octetstring_st));
1620 } else {
1621 *octetstring_st = *octetstring_st * *(other->octetstring_st);
1622 }
1623 }
1624 break;
1625 case ST_CHARSTRING:
1626 if (other->charstring_st!=NULL) {
1627 if (charstring_st==NULL) {
1628 charstring_st = new CharstringSubtypeTreeElement(*(other->charstring_st));
1629 } else {
1630 charstring_st = new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_INTERSECTION,
1631 charstring_st, new CharstringSubtypeTreeElement(*(other->charstring_st)));
1632 }
1633 }
1634 break;
1635 case ST_UNIVERSAL_CHARSTRING:
1636 if (other->universal_charstring_st!=NULL) {
1637 if (universal_charstring_st==NULL) {
1638 universal_charstring_st = new UniversalCharstringSubtypeTreeElement(*(other->universal_charstring_st));
1639 } else {
1640 universal_charstring_st = new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_INTERSECTION,
1641 universal_charstring_st, new UniversalCharstringSubtypeTreeElement(*(other->universal_charstring_st)));
1642 }
1643 }
1644 break;
1645 case ST_OBJID:
1646 case ST_RECORD:
1647 case ST_SET:
1648 case ST_ENUM:
1649 case ST_UNION:
1650 case ST_FUNCTION:
1651 case ST_ALTSTEP:
1652 case ST_TESTCASE:
1653 if (other->value_st!=NULL) {
1654 if (value_st==NULL) {
1655 value_st = new ValueListConstraint(*(other->value_st));
1656 } else {
1657 *value_st = *value_st * *(other->value_st);
1658 }
1659 }
1660 break;
1661 case ST_RECORDOF:
1662 case ST_SETOF:
1663 if (other->recof_st!=NULL) {
1664 if (recof_st==NULL) {
1665 recof_st = new RecofConstraint(*(other->recof_st));
1666 } else {
1667 *recof_st = *recof_st * *(other->recof_st);
1668 }
1669 }
1670 break;
1671 default:
1672 FATAL_ERROR("SubtypeConstraint::intersection()");
1673 }
1674 if (other->length_restriction!=NULL) {
1675 if (length_restriction==NULL) {
1676 length_restriction = new SizeRangeListConstraint(*(other->length_restriction));
1677 } else {
1678 *length_restriction = *length_restriction * *(other->length_restriction);
1679 }
1680 }
1681 }
1682
1683 tribool SubtypeConstraint::is_subset(const SubtypeConstraint* other) const
1684 {
1685 if (other==NULL) return TTRUE;
1686 if (other->subtype!=subtype) FATAL_ERROR("SubtypeConstraint::is_subset()");
1687 switch (subtype) {
1688 case ST_INTEGER:
1689 if (other->integer_st==NULL) return TTRUE;
1690 return integer_st ? integer_st->is_subset(*(other->integer_st)) : TTRUE;
1691 case ST_FLOAT:
1692 if (other->float_st==NULL) return TTRUE;
1693 return float_st ? float_st->is_subset(*(other->float_st)) : TTRUE;
1694 case ST_BOOLEAN:
1695 if (other->boolean_st==NULL) return TTRUE;
1696 return boolean_st ? boolean_st->is_subset(*(other->boolean_st)) : TTRUE;
1697 case ST_VERDICTTYPE:
1698 if (other->verdict_st==NULL) return TTRUE;
1699 return verdict_st ? verdict_st->is_subset(*(other->verdict_st)) : TTRUE;
1700 case ST_BITSTRING:
1701 if (other->bitstring_st==NULL) return TTRUE;
1702 return bitstring_st ? bitstring_st->is_subset(*(other->bitstring_st)) : TTRUE;
1703 case ST_HEXSTRING:
1704 if (other->hexstring_st==NULL) return TTRUE;
1705 return hexstring_st ? hexstring_st->is_subset(*(other->hexstring_st)) : TTRUE;
1706 case ST_OCTETSTRING:
1707 if (other->octetstring_st==NULL) return TTRUE;
1708 return octetstring_st ? octetstring_st->is_subset(*(other->octetstring_st)) : TTRUE;
1709 case ST_CHARSTRING:
1710 if (other->charstring_st==NULL) return TTRUE;
1711 return charstring_st ? charstring_st->is_subset(other->charstring_st) : TTRUE;
1712 case ST_UNIVERSAL_CHARSTRING:
1713 if (other->universal_charstring_st==NULL) return TTRUE;
1714 return universal_charstring_st ? universal_charstring_st->is_subset(other->universal_charstring_st) : TTRUE;
1715 case ST_OBJID:
1716 case ST_RECORD:
1717 case ST_SET:
1718 case ST_ENUM:
1719 case ST_UNION:
1720 case ST_FUNCTION:
1721 case ST_ALTSTEP:
1722 case ST_TESTCASE:
1723 if (other->value_st==NULL) return TTRUE;
1724 return value_st ? value_st->is_subset(*(other->value_st)) : TTRUE;
1725 case ST_RECORDOF:
1726 case ST_SETOF:
1727 if (other->recof_st==NULL) return TTRUE;
1728 return recof_st ? recof_st->is_subset(*(other->recof_st)) : TTRUE;
1729 default:
1730 FATAL_ERROR("SubtypeConstraint::is_subset()");
1731 }
1732 return TUNKNOWN;
1733 }
1734
1735 /********************
1736 class SubType
1737 ********************/
1738
1739 SubType::SubType(subtype_t st, Type *p_my_owner, SubType* p_parent_subtype,
1740 vector<SubTypeParse> *p_parsed, Constraints* p_asn_constraints)
1741 : SubtypeConstraint(st), my_owner(p_my_owner), parent_subtype(p_parent_subtype)
1742 , parsed(p_parsed), asn_constraints(p_asn_constraints)
1743 , root(0), extendable(false), extension(0), checked(STC_NO)
1744 , my_parents()
1745 {
1746 if (p_my_owner==NULL) FATAL_ERROR("SubType::SubType()");
1747 }
1748
1749 SubType::~SubType()
1750 {
1751 my_parents.clear();
1752 }
1753
1754 void SubType::chk_this_value(Value *value)
1755 {
1756 if (checked==STC_NO) FATAL_ERROR("SubType::chk_this_value()");
1757 if ((checked==STC_CHECKING) || (subtype==ST_ERROR)) return;
1758 Value *val = value->get_value_refd_last();
1759 bool is_invalid = false;
1760 switch (val->get_valuetype()) {
1761 case Value::V_INT:
1762 if (subtype!=ST_INTEGER) FATAL_ERROR("SubType::chk_this_value()");
1763 is_invalid = (integer_st!=NULL) && !integer_st->is_element(int_limit_t(*(val->get_val_Int())));
1764 break;
1765 case Value::V_REAL:
1766 if (subtype!=ST_FLOAT) FATAL_ERROR("SubType::chk_this_value()");
1767 is_invalid = (float_st!=NULL) && !float_st->is_element(val->get_val_Real());
1768 break;
1769 case Value::V_BOOL:
1770 if (subtype!=ST_BOOLEAN) FATAL_ERROR("SubType::chk_this_value()");
1771 is_invalid = (boolean_st!=NULL) && !boolean_st->is_element(val->get_val_bool());
1772 break;
1773 case Value::V_VERDICT: {
1774 if (subtype!=ST_VERDICTTYPE) FATAL_ERROR("SubType::chk_this_value()");
1775 VerdicttypeListConstraint::verdicttype_constraint_t vtc;
1776 switch (val->get_val_verdict()) {
1777 case Value::Verdict_NONE: vtc = VerdicttypeListConstraint::VC_NONE; break;
1778 case Value::Verdict_PASS: vtc = VerdicttypeListConstraint::VC_PASS; break;
1779 case Value::Verdict_INCONC: vtc = VerdicttypeListConstraint::VC_INCONC; break;
1780 case Value::Verdict_FAIL: vtc = VerdicttypeListConstraint::VC_FAIL; break;
1781 case Value::Verdict_ERROR: vtc = VerdicttypeListConstraint::VC_ERROR; break;
1782 default: FATAL_ERROR("SubType::chk_this_value()");
1783 }
1784 is_invalid = (verdict_st!=NULL) && !verdict_st->is_element(vtc);
1785 } break;
1786 case Value::V_BSTR:
1787 if (subtype!=ST_BITSTRING) FATAL_ERROR("SubType::chk_this_value()");
1788 is_invalid = (bitstring_st!=NULL) && !bitstring_st->is_element(val->get_val_str());
1789 break;
1790 case Value::V_HSTR:
1791 if (subtype!=ST_HEXSTRING) FATAL_ERROR("SubType::chk_this_value()");
1792 is_invalid = (hexstring_st!=NULL) && !hexstring_st->is_element(val->get_val_str());
1793 break;
1794 case Value::V_OSTR:
1795 if (subtype!=ST_OCTETSTRING) FATAL_ERROR("SubType::chk_this_value()");
1796 is_invalid = (octetstring_st!=NULL) && !octetstring_st->is_element(val->get_val_str());
1797 break;
1798 case Value::V_CSTR:
1799 case Value::V_ISO2022STR:
1800 if (subtype!=ST_CHARSTRING) FATAL_ERROR("SubType::chk_this_value()");
1801 is_invalid = (charstring_st!=NULL) && !charstring_st->is_element(val->get_val_str());
1802 break;
1803 case Value::V_USTR:
1804 case Value::V_CHARSYMS:
1805 if (subtype!=ST_UNIVERSAL_CHARSTRING) FATAL_ERROR("SubType::chk_this_value()");
1806 is_invalid = (universal_charstring_st!=NULL) && !universal_charstring_st->is_element(val->get_val_ustr());
1807 break;
1808 case Value::V_SEQOF:
1809 if (subtype!=ST_RECORDOF) FATAL_ERROR("SubType::chk_this_value()");
1810 if (value->is_unfoldable()) return;
1811 is_invalid = (recof_st!=NULL) && !recof_st->is_element(val);
1812 break;
1813 case Value::V_SETOF:
1814 if (subtype!=ST_SETOF) FATAL_ERROR("SubType::chk_this_value()");
1815 if (value->is_unfoldable()) return;
1816 is_invalid = (recof_st!=NULL) && !recof_st->is_element(val);
1817 break;
1818 case Value::V_OID:
1819 case Value::V_ROID:
1820 if (subtype!=ST_OBJID) FATAL_ERROR("SubType::chk_this_value()");
1821 if (value->is_unfoldable()) return;
1822 is_invalid = (value_st!=NULL) && !value_st->is_element(val);
1823 break;
1824 case Value::V_ENUM:
1825 case Value::V_NULL: // FIXME: should go to ST_NULL
1826 if (subtype!=ST_ENUM) FATAL_ERROR("SubType::chk_this_value()");
1827 if (value->is_unfoldable()) return;
1828 is_invalid = (value_st!=NULL) && !value_st->is_element(val);
1829 break;
1830 case Value::V_CHOICE:
1831 case Value::V_OPENTYPE: // FIXME?
1832 if (subtype!=ST_UNION) FATAL_ERROR("SubType::chk_this_value()");
1833 if (value->is_unfoldable()) return;
1834 is_invalid = (value_st!=NULL) && !value_st->is_element(val);
1835 break;
1836 case Value::V_SEQ:
1837 if (subtype!=ST_RECORD) FATAL_ERROR("SubType::chk_this_value()");
1838 if (value->is_unfoldable()) return;
1839 is_invalid = (value_st!=NULL) && !value_st->is_element(val);
1840 break;
1841 case Value::V_SET:
1842 if (subtype!=ST_SET) FATAL_ERROR("SubType::chk_this_value()");
1843 if (value->is_unfoldable()) return;
1844 is_invalid = (value_st!=NULL) && !value_st->is_element(val);
1845 break;
1846 case Value::V_FUNCTION:
1847 if (subtype!=ST_FUNCTION) FATAL_ERROR("SubType::chk_this_value()");
1848 if (value->is_unfoldable()) return;
1849 is_invalid = (value_st!=NULL) && !value_st->is_element(val);
1850 break;
1851 case Value::V_ALTSTEP:
1852 if (subtype!=ST_ALTSTEP) FATAL_ERROR("SubType::chk_this_value()");
1853 if (value->is_unfoldable()) return;
1854 is_invalid = (value_st!=NULL) && !value_st->is_element(val);
1855 break;
1856 case Value::V_TESTCASE:
1857 if (subtype!=ST_TESTCASE) FATAL_ERROR("SubType::chk_this_value()");
1858 if (value->is_unfoldable()) return;
1859 is_invalid = (value_st!=NULL) && !value_st->is_element(val);
1860 break;
1861 case Value::V_ERROR:
1862 return;
1863 default:
1864 return;
1865 }
1866 if (is_invalid) {
1867 value->error("%s is not a valid value for type `%s' which has subtype %s",
1868 val->get_stringRepr().c_str(),
1869 my_owner->get_typename().c_str(),
1870 to_string().c_str());
1871 }
1872 }
1873
1874 /** \todo revise */
1875 void SubType::chk_this_template_generic(Template *templ)
1876 {
1877 if (checked==STC_NO) FATAL_ERROR("SubType::chk_this_template_generic()");
1878 if ((checked==STC_CHECKING) || (subtype==ST_ERROR)) return;
1879 templ = templ->get_template_refd_last();
1880 switch (templ->get_templatetype()) {
1881 case Ttcn::Template::OMIT_VALUE:
1882 case Ttcn::Template::ANY_OR_OMIT:
1883 case Ttcn::Template::TEMPLATE_ERROR:
1884 case Ttcn::Template::ANY_VALUE:
1885 break;
1886 case Ttcn::Template::VALUE_LIST:
1887 case Ttcn::Template::COMPLEMENTED_LIST:
1888 /* Should be canonical before */
1889 break;
1890 case Ttcn::Template::SPECIFIC_VALUE:
1891 /* SPECIFIC_VALUE must be already checked in Type::chk_this_template() */
1892 break;
1893 case Ttcn::Template::TEMPLATE_REFD:
1894 /* unfoldable reference: cannot be checked at compile time */
1895 break;
1896 case Ttcn::Template::TEMPLATE_INVOKE:
1897 /* should be already checked in Type::chk_this_template() */
1898 break;
1899 default:
1900 chk_this_template(templ);
1901 break;
1902 }
1903 chk_this_template_length_restriction(templ);
1904 }
1905
1906 /** \todo revise */
1907 void SubType::chk_this_template(Template *templ)
1908 {
1909 switch (templ->get_templatetype()) {
1910 case Template::TEMPLATE_LIST:
1911 if ( (length_restriction!=NULL) && !length_restriction->is_empty() ) {
1912 size_t nof_comp_woaon = templ->get_nof_comps_not_anyornone();
1913 if (!templ->temps_contains_anyornone_symbol() &&
1914 nof_comp_woaon < length_restriction->get_minimal().get_size()) {
1915 templ->error("At least %s elements must be present in the list",
1916 Int2string((Int)(length_restriction->get_minimal().get_size())).c_str());
1917 return;
1918 } else if ( !length_restriction->get_maximal().get_infinity() && (nof_comp_woaon > length_restriction->get_maximal().get_size()) ) {
1919 templ->error("There must not be more than %s elements in the list",
1920 Int2string((Int)(length_restriction->get_maximal().get_size())).c_str());
1921 return;
1922 }
1923 }
1924 break;
1925 /* Simply break. We don't know how many elements are there.
1926 SUPERSET_MATCH/SUBSET_MATCH is not possible to be an
1927 INDEXED_TEMPLATE_LIST. */
1928 case Template::INDEXED_TEMPLATE_LIST:
1929 break;
1930 case Template::NAMED_TEMPLATE_LIST:
1931 break;
1932 case Template::VALUE_RANGE:
1933 /* Should be canonical before */
1934 break;
1935 case Template::ALL_FROM:
1936 case Template::VALUE_LIST_ALL_FROM:
1937 break;
1938 case Template::SUPERSET_MATCH:
1939 case Template::SUBSET_MATCH:
1940 if (subtype!=ST_SETOF){
1941 templ->error("'subset' template matching mechanism can be used "
1942 "only with 'set of' types");
1943 return;
1944 }
1945 for (size_t i=0;i<templ->get_nof_comps();i++)
1946 chk_this_template_generic(templ->get_temp_byIndex(i));
1947 break;
1948 case Template::BSTR_PATTERN:
1949 chk_this_template_pattern("bitstring", templ);
1950 break;
1951 case Template::HSTR_PATTERN:
1952 chk_this_template_pattern("hexstring", templ);
1953 break;
1954 case Template::OSTR_PATTERN:
1955 chk_this_template_pattern("octetstring", templ);
1956 break;
1957 case Template::CSTR_PATTERN:
1958 chk_this_template_pattern("charstring", templ);
1959 break;
1960 case Template::USTR_PATTERN:
1961 chk_this_template_pattern("universal charstring", templ);
1962 break;
1963 case Template::TEMPLATE_ERROR:
1964 break;
1965 default:
1966 FATAL_ERROR("SubType::chk_this_template()");
1967 break;
1968 }
1969 }
1970
1971 void SubType::chk_this_template_length_restriction(Template *templ)
1972 {
1973 if (!templ->is_length_restricted()) return;
1974 // if there is a length restriction on the template then check if
1975 // the intersection of the two restrictions is not empty
1976 size_limit_t tmpl_min_len(size_limit_t(0));
1977 size_limit_t tmpl_max_len(size_limit_t::INFINITE_SIZE);
1978 Ttcn::LengthRestriction *lr=templ->get_length_restriction();
1979 lr->chk(Type::EXPECTED_DYNAMIC_VALUE);
1980 if (!lr->get_is_range()) { //Template's lr is single
1981 Value *tmp_val=lr->get_single_value();
1982 if (tmp_val->get_valuetype()!=Value::V_INT) return;
1983 Int templ_len = tmp_val->get_val_Int()->get_val();
1984 tmpl_min_len = tmpl_max_len = size_limit_t((size_t)templ_len);
1985 } else { //Template's lr is range
1986 Value *tmp_lower=lr->get_lower_value();
1987 if (tmp_lower->get_valuetype()!=Value::V_INT) return;
1988 Int templ_lower = tmp_lower->get_val_Int()->get_val();
1989 tmpl_min_len = size_limit_t((size_t)templ_lower);
1990 Value *tmp_upper=lr->get_upper_value();
1991 if (tmp_upper && tmp_upper->get_valuetype()!=Value::V_INT) return;
1992 if (tmp_upper) tmpl_max_len = size_limit_t((size_t)tmp_upper->get_val_Int()->get_val());
1993 }
1994
1995 bool is_err = false;
1996 switch (subtype) {
1997 case ST_BITSTRING:
1998 if (bitstring_st!=NULL) {
1999 BitstringConstraint bc = *bitstring_st * BitstringConstraint(tmpl_min_len,tmpl_max_len);
2000 if (bc.is_empty()==TTRUE) is_err = true;
2001 }
2002 break;
2003 case ST_HEXSTRING:
2004 if (hexstring_st!=NULL) {
2005 HexstringConstraint hc = *hexstring_st * HexstringConstraint(tmpl_min_len,tmpl_max_len);
2006 if (hc.is_empty()==TTRUE) is_err = true;
2007 }
2008 break;
2009 case ST_OCTETSTRING:
2010 if (octetstring_st!=NULL) {
2011 OctetstringConstraint oc = *octetstring_st * OctetstringConstraint(tmpl_min_len,tmpl_max_len);
2012 if (oc.is_empty()==TTRUE) is_err = true;
2013 }
2014 break;
2015 case ST_CHARSTRING:
2016 if (charstring_st!=NULL) {
2017 CharstringSubtypeTreeElement* cc = new CharstringSubtypeTreeElement(
2018 CharstringSubtypeTreeElement::ET_INTERSECTION,
2019 new CharstringSubtypeTreeElement(*charstring_st),
2020 new CharstringSubtypeTreeElement(SizeRangeListConstraint(tmpl_min_len,tmpl_max_len))
2021 );
2022 if (cc->is_empty()==TTRUE) is_err = true;
2023 delete cc;
2024 }
2025 break;
2026 case ST_UNIVERSAL_CHARSTRING:
2027 if (universal_charstring_st!=NULL) {
2028 UniversalCharstringSubtypeTreeElement* ucc = new UniversalCharstringSubtypeTreeElement(
2029 UniversalCharstringSubtypeTreeElement::ET_INTERSECTION,
2030 new UniversalCharstringSubtypeTreeElement(*universal_charstring_st),
2031 new UniversalCharstringSubtypeTreeElement(SizeRangeListConstraint(tmpl_min_len,tmpl_max_len))
2032 );
2033 if (ucc->is_empty()==TTRUE) is_err = true;
2034 delete ucc;
2035 }
2036 break;
2037 case ST_RECORDOF:
2038 case ST_SETOF:
2039 if (recof_st!=NULL) {
2040 RecofConstraint rc = *recof_st * RecofConstraint(tmpl_min_len,tmpl_max_len);
2041 if (rc.is_empty()==TTRUE) is_err = true;
2042 }
2043 break;
2044 default:
2045 break;
2046 }
2047 if (is_err) {
2048 templ->error("Template's length restriction %s is outside of the type's subtype constraint %s",
2049 SizeRangeListConstraint(tmpl_min_len,tmpl_max_len).to_string().c_str(), to_string().c_str());
2050 }
2051 }
2052
2053 void SubType::chk_this_template_pattern(const char *patt_type, Template *templ)
2054 {
2055 Template::templatetype_t temptype= templ->get_templatetype();
2056 if ((temptype==Template::BSTR_PATTERN && subtype!=ST_BITSTRING) ||
2057 (temptype==Template::HSTR_PATTERN && subtype!=ST_HEXSTRING) ||
2058 (temptype==Template::OSTR_PATTERN && subtype!=ST_OCTETSTRING) ||
2059 (temptype==Template::CSTR_PATTERN && subtype!=ST_CHARSTRING) ||
2060 (temptype==Template::USTR_PATTERN && subtype!=ST_UNIVERSAL_CHARSTRING))
2061 {
2062 templ->error("Template is incompatible with subtype");
2063 return;
2064 }
2065 if ( (length_restriction!=NULL) && !length_restriction->is_empty() ) {
2066 Int patt_min_len = static_cast<Int>(templ->get_min_length_of_pattern());
2067 if (patt_min_len < (Int)(length_restriction->get_minimal().get_size()) &&
2068 !templ->pattern_contains_anyornone_symbol()) {
2069 templ->error("At least %s string elements must be present in the %s",
2070 Int2string((Int)(length_restriction->get_minimal().get_size())).c_str(), patt_type);
2071 } else if ( !length_restriction->get_maximal().get_infinity() && (patt_min_len > (Int)(length_restriction->get_maximal().get_size())) ) {
2072 templ->error("There must not be more than %s string elements in the %s",
2073 Int2string((Int)(length_restriction->get_maximal().get_size())).c_str(), patt_type);
2074 }
2075 }
2076 }
2077
2078 void SubType::add_ttcn_value(Value *v)
2079 {
2080 if (value_st==NULL) value_st = new ValueListConstraint(v);
2081 else *value_st = *value_st + ValueListConstraint(v);
2082 }
2083
2084 void SubType::add_ttcn_recof(Value *v)
2085 {
2086 if (recof_st==NULL) recof_st = new RecofConstraint(v);
2087 else *recof_st = *recof_st + RecofConstraint(v);
2088 }
2089
2090 bool SubType::add_ttcn_type_list_subtype(SubType* p_st)
2091 {
2092 switch (subtype) {
2093 case ST_INTEGER:
2094 if (p_st->integer_st==NULL) return false;
2095 if (integer_st==NULL) integer_st = new IntegerRangeListConstraint(*(p_st->integer_st));
2096 else *integer_st = *integer_st + *(p_st->integer_st);
2097 break;
2098 case ST_FLOAT:
2099 if (p_st->float_st==NULL) return false;
2100 if (float_st==NULL) float_st = new RealRangeListConstraint(*(p_st->float_st));
2101 else *float_st = *float_st + *(p_st->float_st);
2102 break;
2103 case ST_BOOLEAN:
2104 if (p_st->boolean_st==NULL) return false;
2105 if (boolean_st==NULL) boolean_st = new BooleanListConstraint(*(p_st->boolean_st));
2106 else *boolean_st = *boolean_st + *(p_st->boolean_st);
2107 break;
2108 case ST_VERDICTTYPE:
2109 if (p_st->verdict_st==NULL) return false;
2110 if (verdict_st==NULL) verdict_st = new VerdicttypeListConstraint(*(p_st->verdict_st));
2111 else *verdict_st = *verdict_st + *(p_st->verdict_st);
2112 break;
2113 case ST_BITSTRING:
2114 if (p_st->bitstring_st==NULL) return false;
2115 if (bitstring_st==NULL) bitstring_st = new BitstringConstraint(*(p_st->bitstring_st));
2116 else *bitstring_st = *bitstring_st + *(p_st->bitstring_st);
2117 break;
2118 case ST_HEXSTRING:
2119 if (p_st->hexstring_st==NULL) return false;
2120 if (hexstring_st==NULL) hexstring_st = new HexstringConstraint(*(p_st->hexstring_st));
2121 else *hexstring_st = *hexstring_st + *(p_st->hexstring_st);
2122 break;
2123 case ST_OCTETSTRING:
2124 if (p_st->octetstring_st==NULL) return false;
2125 if (octetstring_st==NULL) octetstring_st = new OctetstringConstraint(*(p_st->octetstring_st));
2126 else *octetstring_st = *octetstring_st + *(p_st->octetstring_st);
2127 break;
2128 case ST_CHARSTRING:
2129 if (p_st->charstring_st==NULL) return false;
2130 if (charstring_st==NULL) {
2131 charstring_st = new CharstringSubtypeTreeElement(*(p_st->charstring_st));
2132 } else {
2133 charstring_st = new CharstringSubtypeTreeElement(
2134 CharstringSubtypeTreeElement::ET_UNION,
2135 charstring_st,
2136 new CharstringSubtypeTreeElement(*(p_st->charstring_st)));
2137 }
2138 break;
2139 case ST_UNIVERSAL_CHARSTRING:
2140 if (p_st->universal_charstring_st==NULL) return false;
2141 if (universal_charstring_st==NULL) {
2142 universal_charstring_st = new UniversalCharstringSubtypeTreeElement(*(p_st->universal_charstring_st));
2143 } else {
2144 universal_charstring_st = new UniversalCharstringSubtypeTreeElement(
2145 UniversalCharstringSubtypeTreeElement::ET_UNION,
2146 universal_charstring_st,
2147 new UniversalCharstringSubtypeTreeElement(*(p_st->universal_charstring_st)));
2148 }
2149 break;
2150 case ST_OBJID:
2151 case ST_RECORD:
2152 case ST_SET:
2153 case ST_ENUM:
2154 case ST_UNION:
2155 case ST_FUNCTION:
2156 case ST_ALTSTEP:
2157 case ST_TESTCASE:
2158 if (p_st->value_st==NULL) return false;
2159 if (value_st==NULL) value_st = new ValueListConstraint(*(p_st->value_st));
2160 else *value_st = *value_st + *(p_st->value_st);
2161 break;
2162 case ST_RECORDOF:
2163 case ST_SETOF:
2164 if (p_st->recof_st==NULL) return false;
2165 if (recof_st==NULL) recof_st = new RecofConstraint(*(p_st->recof_st));
2166 else *recof_st = *recof_st + *(p_st->recof_st);
2167 break;
2168 default:
2169 FATAL_ERROR("SubType::add_ttcn_type_list_subtype()");
2170 }
2171 return true;
2172 }
2173
2174
2175 bool SubType::add_parent_subtype(SubType* st)
2176 {
2177 if (st==NULL) FATAL_ERROR("SubType::add_parent_subtype()");
2178 if (my_parents.has_key(st)) return true; // it was already successfully added -> ignore
2179 ReferenceChain refch(my_owner, "While checking circular type references in subtype definitions");
2180 refch.add(my_owner->get_fullname()); // current type
2181 // recursive check for all parents of referenced type
2182 if (!st->chk_recursion(refch)) return false;
2183 // if no recursion was detected then add the referenced type as parent
2184 my_parents.add(st,NULL);
2185 return true;
2186 }
2187
2188 bool SubType::chk_recursion(ReferenceChain& refch)
2189 {
2190 if (!refch.add(my_owner->get_fullname())) return false; // try the referenced type
2191 for (size_t i = 0; i < my_parents.size(); i++) {
2192 refch.mark_state();
2193 if (!my_parents.get_nth_key(i)->chk_recursion(refch)) return false;
2194 refch.prev_state();
2195 }
2196 return true;
2197 }
2198
2199 bool SubType::add_ttcn_single(Value *val, size_t restriction_index)
2200 {
2201 val->set_my_scope(my_owner->get_my_scope());
2202 val->set_my_governor(my_owner);
2203 val->set_fullname(my_owner->get_fullname()+".<single_restriction_"+Int2string(restriction_index) + ">");
2204 my_owner->chk_this_value_ref(val);
2205
2206 // check if this is type reference, if not then fall through
2207 if (val->get_valuetype()==Value::V_REFD) {
2208 Reference* ref = val->get_reference();
2209 Assignment *ass = ref->get_refd_assignment();
2210 if (ass==NULL) return false; // defintion was not found, error was reported
2211 if (ass->get_asstype()==Assignment::A_TYPE) {
2212 Type* t = ass->get_Type();
2213 t->chk();
2214 if (t->get_typetype()==Type::T_ERROR) return false;
2215 // if there were subreferences then get the referenced field's type
2216 if (ref->get_subrefs()) {
2217 t = t->get_field_type(ref->get_subrefs(), Type::EXPECTED_CONSTANT);
2218 if ( (t==NULL) || (t->get_typetype()==Type::T_ERROR) ) return false;
2219 t->chk();
2220 if (t->get_typetype()==Type::T_ERROR) return false;
2221 }
2222 if (!t->is_identical(my_owner)) {
2223 val->error("Reference `%s' must refer to a type which has the same root type as this type",
2224 val->get_reference()->get_dispname().c_str());
2225 return false;
2226 }
2227 // check subtype of referenced type
2228 SubType* t_st = t->get_sub_type();
2229 if (t_st==NULL) {
2230 val->error("Type referenced by `%s' does not have a subtype",
2231 val->get_reference()->get_dispname().c_str());
2232 return false;
2233 }
2234
2235 // check circular subtype reference
2236 if (!add_parent_subtype(t_st)) return false;
2237
2238 if (t_st->get_subtypetype()==ST_ERROR) return false;
2239 if (t_st->get_subtypetype()!=subtype) FATAL_ERROR("SubType::add_ttcn_single()");
2240 // add the subtype as union
2241 bool added = add_ttcn_type_list_subtype(t_st);
2242 if (!added) {
2243 val->error("Type referenced by `%s' does not have a subtype",
2244 val->get_reference()->get_dispname().c_str());
2245 }
2246 return added;
2247 }
2248 }
2249
2250 my_owner->chk_this_value(val, 0, Type::EXPECTED_CONSTANT,
2251 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, NO_SUB_CHK);
2252
2253 Value *v=val->get_value_refd_last();
2254
2255 switch (v->get_valuetype()) {
2256 case Value::V_INT:
2257 if (subtype!=ST_INTEGER) FATAL_ERROR("SubType::add_ttcn_single()");
2258 if (integer_st==NULL) integer_st = new IntegerRangeListConstraint(int_limit_t(*(v->get_val_Int())));
2259 else *integer_st = *integer_st + IntegerRangeListConstraint(int_limit_t(*(v->get_val_Int())));
2260 break;
2261 case Value::V_REAL: {
2262 if (subtype!=ST_FLOAT) FATAL_ERROR("SubType::add_ttcn_single()");
2263 ttcn3float r = v->get_val_Real();
2264 if (r!=r) {
2265 if (float_st==NULL) float_st = new RealRangeListConstraint(true);
2266 else *float_st = *float_st + RealRangeListConstraint(true);
2267 } else {
2268 if (float_st==NULL) float_st = new RealRangeListConstraint(real_limit_t(r));
2269 else *float_st = *float_st + RealRangeListConstraint(real_limit_t(r));
2270 }
2271 } break;
2272 case Value::V_BOOL:
2273 if (subtype!=ST_BOOLEAN) FATAL_ERROR("SubType::add_ttcn_single()");
2274 if (boolean_st==NULL) boolean_st = new BooleanListConstraint(v->get_val_bool());
2275 else *boolean_st = *boolean_st + BooleanListConstraint(v->get_val_bool());
2276 break;
2277 case Value::V_VERDICT: {
2278 if (subtype!=ST_VERDICTTYPE) FATAL_ERROR("SubType::add_ttcn_single()");
2279 VerdicttypeListConstraint::verdicttype_constraint_t vtc;
2280 switch (v->get_val_verdict()) {
2281 case Value::Verdict_NONE: vtc = VerdicttypeListConstraint::VC_NONE; break;
2282 case Value::Verdict_PASS: vtc = VerdicttypeListConstraint::VC_PASS; break;
2283 case Value::Verdict_INCONC: vtc = VerdicttypeListConstraint::VC_INCONC; break;
2284 case Value::Verdict_FAIL: vtc = VerdicttypeListConstraint::VC_FAIL; break;
2285 case Value::Verdict_ERROR: vtc = VerdicttypeListConstraint::VC_ERROR; break;
2286 default: FATAL_ERROR("SubType::add_ttcn_single()");
2287 }
2288 if (verdict_st==NULL) verdict_st = new VerdicttypeListConstraint(vtc);
2289 else *verdict_st = *verdict_st + VerdicttypeListConstraint(vtc);
2290 } break;
2291 case Value::V_OID:
2292 if (v->has_oid_error()) return false;
2293 if (subtype!=ST_OBJID) FATAL_ERROR("SubType::add_ttcn_single()");
2294 if (value_st==NULL) value_st = new ValueListConstraint(v);
2295 else *value_st = *value_st + ValueListConstraint(v);
2296 break;
2297 case Value::V_BSTR:
2298 if (subtype!=ST_BITSTRING) FATAL_ERROR("SubType::add_ttcn_single()");
2299 if (bitstring_st==NULL) bitstring_st = new BitstringConstraint(v->get_val_str());
2300 else *bitstring_st = *bitstring_st + BitstringConstraint(v->get_val_str());
2301 break;
2302 case Value::V_HSTR:
2303 if (subtype!=ST_HEXSTRING) FATAL_ERROR("SubType::add_ttcn_single()");
2304 if (hexstring_st==NULL) hexstring_st = new HexstringConstraint(v->get_val_str());
2305 else *hexstring_st = *hexstring_st + HexstringConstraint(v->get_val_str());
2306 break;
2307 case Value::V_OSTR:
2308 if (subtype!=ST_OCTETSTRING) FATAL_ERROR("SubType::add_ttcn_single()");
2309 if (octetstring_st==NULL) octetstring_st = new OctetstringConstraint(v->get_val_str());
2310 else *octetstring_st = *octetstring_st + OctetstringConstraint(v->get_val_str());
2311 break;
2312 case Value::V_CSTR: {
2313 if (subtype!=ST_CHARSTRING) FATAL_ERROR("SubType::add_ttcn_single()");
2314 CharstringSubtypeTreeElement* cst_elem = new CharstringSubtypeTreeElement(StringValueConstraint<string>(v->get_val_str()));
2315 if (charstring_st==NULL) charstring_st = cst_elem;
2316 else charstring_st = new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_UNION, charstring_st, cst_elem);
2317 } break;
2318 case Value::V_USTR: {
2319 if (subtype!=ST_UNIVERSAL_CHARSTRING) FATAL_ERROR("SubType::add_ttcn_single()");
2320 UniversalCharstringSubtypeTreeElement* ucst_elem = new UniversalCharstringSubtypeTreeElement(StringValueConstraint<ustring>(v->get_val_ustr()));
2321 if (universal_charstring_st==NULL) universal_charstring_st = ucst_elem;
2322 else universal_charstring_st = new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_UNION, universal_charstring_st, ucst_elem);
2323 } break;
2324 case Value::V_ENUM:
2325 case Value::V_NULL: // FIXME: should go to ST_NULL
2326 if (subtype!=ST_ENUM) FATAL_ERROR("SubType::add_ttcn_single()");
2327 add_ttcn_value(v);
2328 break;
2329 case Value::V_CHOICE:
2330 if (subtype!=ST_UNION) FATAL_ERROR("SubType::add_ttcn_single()");
2331 add_ttcn_value(v);
2332 break;
2333 case Value::V_SEQ:
2334 if (subtype!=ST_RECORD) FATAL_ERROR("SubType::add_ttcn_single()");
2335 add_ttcn_value(v);
2336 break;
2337 case Value::V_SET:
2338 if (subtype!=ST_SET) FATAL_ERROR("SubType::add_ttcn_single()");
2339 add_ttcn_value(v);
2340 break;
2341 case Value::V_FUNCTION:
2342 if (subtype!=ST_FUNCTION) FATAL_ERROR("SubType::add_ttcn_single()");
2343 add_ttcn_value(v);
2344 break;
2345 case Value::V_ALTSTEP:
2346 if (subtype!=ST_ALTSTEP) FATAL_ERROR("SubType::add_ttcn_single()");
2347 add_ttcn_value(v);
2348 break;
2349 case Value::V_TESTCASE:
2350 if (subtype!=ST_TESTCASE) FATAL_ERROR("SubType::add_ttcn_single()");
2351 add_ttcn_value(v);
2352 break;
2353 case Value::V_SEQOF:
2354 if (subtype!=ST_RECORDOF) FATAL_ERROR("SubType::add_ttcn_single()");
2355 add_ttcn_recof(v);
2356 break;
2357 case Value::V_SETOF:
2358 if (subtype!=ST_SETOF) FATAL_ERROR("SubType::add_ttcn_single()");
2359 add_ttcn_recof(v);
2360 break;
2361 case Value::V_ERROR:
2362 return false;
2363 default:
2364 return false;
2365 }
2366 return true;
2367 }
2368
2369 bool SubType::add_ttcn_range(Value *min, bool min_exclusive,
2370 Value *max, bool max_exclusive, size_t restriction_index, bool has_other)
2371 {
2372 switch (subtype) {
2373 case ST_INTEGER:
2374 case ST_FLOAT:
2375 case ST_CHARSTRING:
2376 case ST_UNIVERSAL_CHARSTRING:
2377 break;
2378 default:
2379 my_owner->error("Range subtyping is not allowed for type `%s'",
2380 my_owner->get_typename().c_str());
2381 return false;
2382 }
2383
2384 Value *vmin,*vmax;
2385 if (min==NULL) vmin=NULL;
2386 else {
2387 min->set_my_scope(my_owner->get_my_scope());
2388 min->set_fullname(my_owner->get_fullname()+".<range_restriction_"+Int2string(restriction_index)+"_lower>");
2389 my_owner->chk_this_value_ref(min);
2390 my_owner->chk_this_value(min, 0, Type::EXPECTED_CONSTANT,
2391 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, NO_SUB_CHK);
2392 vmin=min->get_value_refd_last();
2393 }
2394 if (max==NULL) vmax=NULL;
2395 else {
2396 max->set_my_scope(my_owner->get_my_scope());
2397 max->set_fullname(my_owner->get_fullname()+".<range_restriction_"+Int2string(restriction_index)+"_upper>");
2398 my_owner->chk_this_value_ref(max);
2399 my_owner->chk_this_value(max, 0, Type::EXPECTED_CONSTANT,
2400 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, NO_SUB_CHK);
2401 vmax=max->get_value_refd_last();
2402 }
2403
2404 if ( (vmin!=NULL) && (vmax!=NULL) && (vmin->get_valuetype()!=vmax->get_valuetype()) ) return false;
2405
2406 switch (subtype) {
2407 case ST_INTEGER: {
2408 if (((vmin!=NULL) && (vmin->get_valuetype()!=Value::V_INT)) ||
2409 ((vmax!=NULL) && (vmax->get_valuetype()!=Value::V_INT))) return false;
2410 int_limit_t min_limit = (vmin!=NULL) ? int_limit_t(*(vmin->get_val_Int())) : int_limit_t::minimum;
2411 if (min_exclusive) {
2412 if (min_limit==int_limit_t::minimum) {
2413 my_owner->error("invalid lower boundary, -infinity cannot be excluded from an integer subtype range");
2414 return false;
2415 } else {
2416 if (min_limit==int_limit_t::maximum) {
2417 my_owner->error("!infinity is not a valid lower boundary");
2418 return false;
2419 }
2420 min_limit = min_limit.next();
2421 }
2422 }
2423 int_limit_t max_limit = (vmax!=NULL) ? int_limit_t(*(vmax->get_val_Int())) : int_limit_t::maximum;
2424 if (max_exclusive) {
2425 if (max_limit==int_limit_t::maximum) {
2426 my_owner->error("invalid upper boundary, infinity cannot be excluded from an integer subtype range");
2427 return false;
2428 } else {
2429 if (max_limit==int_limit_t::minimum) {
2430 my_owner->error("!-infinity is not a valid upper boundary");
2431 return false;
2432 }
2433 max_limit = max_limit.previous();
2434 }
2435 }
2436 if (max_limit<min_limit) {
2437 my_owner->error("lower boundary is bigger than upper boundary in integer subtype range");
2438 return false;
2439 }
2440 if (integer_st==NULL) integer_st = new IntegerRangeListConstraint(min_limit, max_limit);
2441 else *integer_st = *integer_st + IntegerRangeListConstraint(min_limit, max_limit);
2442 } break;
2443 case ST_FLOAT: {
2444 if (((vmin!=NULL) && (vmin->get_valuetype()!=Value::V_REAL)) ||
2445 ((vmax!=NULL) && (vmax->get_valuetype()!=Value::V_REAL))) return false;
2446 if ((vmin!=NULL) && (vmin->get_val_Real()!=vmin->get_val_Real())) {
2447 my_owner->error("lower boundary cannot be not_a_number in float subtype range");
2448 return false;
2449 }
2450 if ((vmax!=NULL) && (vmax->get_val_Real()!=vmax->get_val_Real())) {
2451 my_owner->error("upper boundary cannot be not_a_number in float subtype range");
2452 return false;
2453 }
2454 real_limit_t min_limit = (vmin!=NULL) ? real_limit_t(vmin->get_val_Real()) : real_limit_t::minimum;
2455 if (min_exclusive) {
2456 if (min_limit==real_limit_t::maximum) {
2457 my_owner->error("!infinity is not a valid lower boundary");
2458 return false;
2459 }
2460 min_limit = min_limit.next();
2461 }
2462 real_limit_t max_limit = (vmax!=NULL) ? real_limit_t(vmax->get_val_Real()) : real_limit_t::maximum;
2463 if (max_exclusive) {
2464 if (max_limit==real_limit_t::minimum) {
2465 my_owner->error("!-infinity is not a valid upper boundary");
2466 return false;
2467 }
2468 max_limit = max_limit.previous();
2469 }
2470 if (max_limit<min_limit) {
2471 my_owner->error("lower boundary is bigger than upper boundary in float subtype range");
2472 return false;
2473 }
2474 if (float_st==NULL) float_st = new RealRangeListConstraint(min_limit, max_limit);
2475 else *float_st = *float_st + RealRangeListConstraint(min_limit, max_limit);
2476 } break;
2477 case ST_CHARSTRING: {
2478 if (((vmin!=NULL) && (vmin->get_valuetype()!=Value::V_CSTR)) ||
2479 ((vmax!=NULL) && (vmax->get_valuetype()!=Value::V_CSTR))) return false;
2480 if ((vmin==NULL)&&(vmax==NULL)) {
2481 my_owner->error("a range subtype of a charstring cannot be (-infinity..infinity)");
2482 return false;
2483 }
2484 if (vmin==NULL) {
2485 my_owner->error("lower boundary of a charstring subtype range cannot be -infinity");
2486 return false;
2487 }
2488 if (vmax==NULL) {
2489 my_owner->error("upper boundary of a charstring subtype range cannot be infinity");
2490 return false;
2491 }
2492 if (vmin->get_val_str().size()!=1) {
2493 min->error("lower boundary of charstring subtype range must be a single element string");
2494 return false;
2495 }
2496 if (vmax->get_val_str().size()!=1) {
2497 max->error("upper boundary of charstring subtype range must be a single element string");
2498 return false;
2499 }
2500 if (!char_limit_t::is_valid_value(*vmin->get_val_str().c_str())) {
2501 min->error("lower boundary of charstring subtype range is an invalid char");
2502 return false;
2503 }
2504 if (!char_limit_t::is_valid_value(*vmax->get_val_str().c_str())) {
2505 max->error("upper boundary of charstring subtype range is an invalid char");
2506 return false;
2507 }
2508 char_limit_t min_limit(*vmin->get_val_str().c_str()), max_limit(*vmax->get_val_str().c_str());
2509 if (min_exclusive) {
2510 if (min_limit==char_limit_t::maximum) {
2511 min->error("exclusive lower boundary is not a legal charstring character");
2512 return false;
2513 }
2514 min_limit = min_limit.next();
2515 }
2516 if (max_exclusive) {
2517 if (max_limit==char_limit_t::minimum) {
2518 max->error("exclusive upper boundary is not a legal charstring character");
2519 return false;
2520 }
2521 max_limit = max_limit.previous();
2522 }
2523 if (max_limit<min_limit) {
2524 my_owner->error("lower boundary is bigger than upper boundary in charstring subtype range");
2525 return false;
2526 }
2527 if (charstring_st==NULL) charstring_st = new CharstringSubtypeTreeElement(CharRangeListConstraint(min_limit,max_limit), false);
2528 else {
2529 if (!has_other) { // union in char context can be done only with range constraints
2530 charstring_st->set_char_context(true);
2531 charstring_st = new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_UNION,
2532 charstring_st,
2533 new CharstringSubtypeTreeElement(CharRangeListConstraint(min_limit,max_limit), true));
2534 charstring_st->set_char_context(false);
2535 } else {
2536 // ignore it, error reported elsewhere
2537 return false;
2538 }
2539 }
2540 } break;
2541 case ST_UNIVERSAL_CHARSTRING: {
2542 if (((vmin!=NULL) && (vmin->get_valuetype()!=Value::V_USTR)) ||
2543 ((vmax!=NULL) && (vmax->get_valuetype()!=Value::V_USTR))) return false;
2544 if ((vmin==NULL)&&(vmax==NULL)) {
2545 my_owner->error("a range subtype of a universal charstring cannot be (-infinity..infinity)");
2546 return false;
2547 }
2548 if (vmin==NULL) {
2549 my_owner->error("lower boundary of a universal charstring subtype range cannot be -infinity");
2550 return false;
2551 }
2552 if (vmax==NULL) {
2553 my_owner->error("upper boundary of a universal charstring subtype range cannot be infinity");
2554 return false;
2555 }
2556 if (vmin->get_val_ustr().size()!=1) {
2557 min->error("lower boundary of universal charstring subtype range must be a single element string");
2558 return false;
2559 }
2560 if (vmax->get_val_ustr().size()!=1) {
2561 max->error("upper boundary of universal charstring subtype range must be a single element string");
2562 return false;
2563 }
2564 if (!universal_char_limit_t::is_valid_value(*vmin->get_val_ustr().u_str())) {
2565 min->error("lower boundary of universal charstring subtype range is an invalid char");
2566 return false;
2567 }
2568 if (!universal_char_limit_t::is_valid_value(*vmax->get_val_ustr().u_str())) {
2569 max->error("upper boundary of universal charstring subtype range is an invalid char");
2570 return false;
2571 }
2572 universal_char_limit_t min_limit(*vmin->get_val_ustr().u_str()), max_limit(*vmax->get_val_ustr().u_str());
2573 if (min_exclusive) {
2574 if (min_limit==universal_char_limit_t::maximum) {
2575 min->error("exclusive lower boundary is not a legal universal charstring character");
2576 return false;
2577 }
2578 min_limit = min_limit.next();
2579 }
2580 if (max_exclusive) {
2581 if (max_limit==universal_char_limit_t::minimum) {
2582 max->error("exclusive upper boundary is not a legal universal charstring character");
2583 return false;
2584 }
2585 max_limit = max_limit.previous();
2586 }
2587 if (max_limit<min_limit) {
2588 my_owner->error("lower boundary is bigger than upper boundary in universal charstring subtype range");
2589 return false;
2590 }
2591
2592 if (universal_charstring_st==NULL) universal_charstring_st = new UniversalCharstringSubtypeTreeElement(UniversalCharRangeListConstraint(min_limit,max_limit), false);
2593 else {
2594 if (!has_other) { // union in char context can be done only with range constraints
2595 universal_charstring_st->set_char_context(true);
2596 universal_charstring_st = new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_UNION,
2597 universal_charstring_st,
2598 new UniversalCharstringSubtypeTreeElement(UniversalCharRangeListConstraint(min_limit,max_limit), true));
2599 universal_charstring_st->set_char_context(false);
2600 } else {
2601 // ignore it, error reported elsewhere
2602 return false;
2603 }
2604 }
2605 } break;
2606 default:
2607 FATAL_ERROR("SubType::add_ttcn_range()");
2608 }
2609 return true;
2610 }
2611
2612 bool SubType::set_ttcn_length(const size_limit_t& min, const size_limit_t& max)
2613 {
2614 switch (subtype) {
2615 case ST_BITSTRING: {
2616 if (bitstring_st==NULL) bitstring_st = new BitstringConstraint(min,max);
2617 else *bitstring_st = *bitstring_st * BitstringConstraint(min,max);
2618 } break;
2619 case ST_HEXSTRING: {
2620 if (hexstring_st==NULL) hexstring_st = new HexstringConstraint(min,max);
2621 else *hexstring_st = *hexstring_st * HexstringConstraint(min,max);
2622 } break;
2623 case ST_OCTETSTRING: {
2624 if (octetstring_st==NULL) octetstring_st = new OctetstringConstraint(min,max);
2625 else *octetstring_st = *octetstring_st * OctetstringConstraint(min,max);
2626 } break;
2627 case ST_CHARSTRING: {
2628 CharstringSubtypeTreeElement* cst_elem = new CharstringSubtypeTreeElement(SizeRangeListConstraint(min,max));
2629 if (charstring_st==NULL) {
2630 charstring_st = cst_elem;
2631 } else {
2632 charstring_st = new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_INTERSECTION, charstring_st, cst_elem);
2633 }
2634 } break;
2635 case ST_UNIVERSAL_CHARSTRING: {
2636 UniversalCharstringSubtypeTreeElement* ucst_elem = new UniversalCharstringSubtypeTreeElement(SizeRangeListConstraint(min,max));
2637 if (universal_charstring_st==NULL) {
2638 universal_charstring_st = ucst_elem;
2639 } else {
2640 universal_charstring_st = new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_INTERSECTION, universal_charstring_st, ucst_elem);
2641 }
2642 } break;
2643 case ST_RECORDOF:
2644 case ST_SETOF: {
2645 if (recof_st==NULL) recof_st = new RecofConstraint(min,max);
2646 else *recof_st = *recof_st * RecofConstraint(min,max);
2647 } break;
2648 default:
2649 my_owner->error("Length subtyping is not allowed for type `%s'",
2650 my_owner->get_typename().c_str());
2651 return false;
2652 }
2653 if (length_restriction==NULL) length_restriction = new SizeRangeListConstraint(min,max);
2654 else *length_restriction = *length_restriction * SizeRangeListConstraint(min,max);
2655 return true;
2656 }
2657
2658 void SubType::chk_boundary_valid(Value* boundary, Int max_value, const char* boundary_name)
2659 {
2660 const int_val_t *int_val = boundary->get_val_Int();
2661 if (*int_val > int_val_t(max_value)) {
2662 boundary->error("The %s should be less than `%s' instead of `%s'",
2663 boundary_name,
2664 int_val_t(max_value).t_str().c_str(),
2665 int_val->t_str().c_str());
2666 boundary->set_valuetype(Value::V_ERROR);
2667 }
2668 }
2669
2670 bool SubType::add_ttcn_length(Ttcn::LengthRestriction *lr, size_t restriction_index)
2671 {
2672 string s;
2673 lr->append_stringRepr(s);
2674 Value *lower=NULL,*upper=NULL;
2675 lr->set_my_scope(my_owner->get_my_scope());
2676 lr->set_fullname(my_owner->get_fullname()+".<length_restriction_"+Int2string(restriction_index)+">");
2677 lr->chk(Type::EXPECTED_CONSTANT);
2678 lower = lr->get_is_range() ? lr->get_lower_value() : lr->get_single_value();
2679 if (!lower->get_my_scope()) FATAL_ERROR("no scope");
2680 if (lower->get_valuetype() != Value::V_INT) return false;
2681 if (lr->get_is_range()) {
2682 upper = lr->get_upper_value();
2683 if (upper) {//HAS_UPPER
2684 if (upper->get_valuetype()!=Value::V_INT) return false;
2685 if (!upper->get_my_scope()) upper->set_my_scope(my_owner->get_my_scope());
2686 chk_boundary_valid(upper, INT_MAX, "upper boundary");
2687 if (upper->get_valuetype()!=Value::V_INT) return false;
2688 return set_ttcn_length(size_limit_t((size_t)lower->get_val_Int()->get_val()),
2689 size_limit_t((size_t)upper->get_val_Int()->get_val()));
2690 } else {//INFINITY:
2691 chk_boundary_valid(lower, INT_MAX, "lower boundary");
2692 if (lower->get_valuetype()!=Value::V_INT) return false;
2693 return set_ttcn_length(size_limit_t((size_t)lower->get_val_Int()->get_val()),
2694 size_limit_t(size_limit_t::INFINITE_SIZE));
2695 }
2696 }
2697 else {//SINGLE:
2698 chk_boundary_valid(lower, INT_MAX, "length restriction value");
2699 if (lower->get_valuetype()!=Value::V_INT) return false;
2700 return set_ttcn_length(size_limit_t((size_t)lower->get_val_Int()->get_val()),
2701 size_limit_t((size_t)lower->get_val_Int()->get_val()));
2702 }
2703 }
2704
2705 bool SubType::add_ttcn_pattern(Ttcn::PatternString* pattern, size_t restriction_index)
2706 {
2707 pattern->set_my_scope(my_owner->get_my_scope());
2708 pattern->set_fullname(my_owner->get_fullname()+".<pattern_restriction_"+Int2string(restriction_index) + ">");
2709 switch (subtype) {
2710 case ST_CHARSTRING: {
2711 Error_Context cntxt(my_owner, "In character string pattern");
2712 pattern->chk_refs(Type::EXPECTED_CONSTANT);
2713 pattern->join_strings();
2714 if (!pattern->has_refs()) { // if chk_refs didn't remove all references then ignore
2715 pattern->chk_pattern();
2716 CharstringSubtypeTreeElement* cst_elem = new CharstringSubtypeTreeElement(StringPatternConstraint(pattern));
2717 if (charstring_st==NULL) {
2718 charstring_st = cst_elem;
2719 } else {
2720 charstring_st = new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_INTERSECTION, charstring_st, cst_elem);
2721 }
2722 }
2723 } break;
2724 case ST_UNIVERSAL_CHARSTRING: {
2725 Error_Context cntxt(my_owner, "In universal string pattern");
2726 pattern->set_pattern_type(Ttcn::PatternString::USTR_PATTERN);
2727 pattern->chk_refs(Type::EXPECTED_CONSTANT);
2728 pattern->join_strings();
2729 if (!pattern->has_refs()) { // if chk_refs didn't remove all references then ignore
2730 pattern->chk_pattern();
2731 UniversalCharstringSubtypeTreeElement* ucst_elem = new UniversalCharstringSubtypeTreeElement(StringPatternConstraint(pattern));
2732 if (universal_charstring_st==NULL) {
2733 universal_charstring_st = ucst_elem;
2734 } else {
2735 universal_charstring_st = new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_INTERSECTION, universal_charstring_st, ucst_elem);
2736 }
2737 }
2738 } break;
2739 default:
2740 my_owner->error("Pattern subtyping of type `%s' is not allowed", my_owner->get_typename().c_str());
2741 return false;
2742 }
2743 return true;
2744 }
2745
2746 void SubType::print_full_warning() const
2747 {
2748 my_owner->warning("The subtype of type `%s' is a full set, "
2749 "it does not constrain the root type.", my_owner->get_typename().c_str());
2750 }
2751
2752 void SubType::chk()
2753 {
2754 if ((checked!=STC_NO) || (subtype==ST_ERROR)) FATAL_ERROR("SubType::chk()");
2755 checked = STC_CHECKING;
2756
2757 // check for circular subtype reference
2758 if (parent_subtype && !add_parent_subtype(parent_subtype)) {
2759 set_to_error();
2760 checked = STC_YES;
2761 return;
2762 }
2763
2764 if (parsed) { // has TTCN-3 subtype constraint
2765 size_t added_count = 0;
2766 bool has_single = false, has_range = false,
2767 has_length = false, has_pattern = false;
2768 for (size_t i = 0; i < parsed->size(); i++) {
2769 bool added = false;
2770 SubTypeParse *parse = (*parsed)[i];
2771 switch (parse->get_selection()) {
2772 case SubTypeParse::STP_SINGLE:
2773 has_single = true;
2774 added = add_ttcn_single(parse->Single(),i);
2775 break;
2776 case SubTypeParse::STP_RANGE:
2777 has_range = true;
2778 added = add_ttcn_range(parse->Min(), parse->MinExclusive(),
2779 parse->Max(), parse->MaxExclusive(), i,
2780 has_single || has_length || has_pattern);
2781 break;
2782 case SubTypeParse::STP_LENGTH:
2783 has_length = true;
2784 added = add_ttcn_length(parse->Length(),i);
2785 break;
2786 case SubTypeParse::STP_PATTERN:
2787 has_pattern = true;
2788 added = add_ttcn_pattern(parse->Pattern(),i);
2789 break;
2790 default:
2791 FATAL_ERROR("SubType::chk(): invalid SubTypeParse selection");
2792 } // switch
2793 if (added) added_count++;
2794 }//for
2795 switch (subtype) {
2796 case ST_CHARSTRING:
2797 case ST_UNIVERSAL_CHARSTRING:
2798 if (has_single && has_range) {
2799 my_owner->error(
2800 "Mixing of value list and range subtyping is not allowed for type `%s'",
2801 my_owner->get_typename().c_str());
2802 set_to_error();
2803 checked = STC_YES;
2804 return;
2805 }
2806 break;
2807 default:
2808 // in other cases mixing of different restrictions (which are legal for
2809 // this type) is properly regulated by the TTCN-3 BNF itself
2810 break;
2811 }
2812 if (added_count<parsed->size()) {
2813 set_to_error();
2814 checked = STC_YES;
2815 return;
2816 }
2817 if (subtype==ST_ERROR) { checked = STC_YES; return; }
2818
2819 if (parent_subtype) {
2820 if (is_subset(parent_subtype->get_root())==TFALSE) {
2821 my_owner->error("The subtype restriction is not a subset of the restriction on the parent type. "
2822 "Subtype %s is not subset of subtype %s", to_string().c_str(), parent_subtype->get_root()->to_string().c_str());
2823 set_to_error();
2824 checked = STC_YES;
2825 return;
2826 }
2827 intersection(parent_subtype->get_root());
2828 }
2829 } else if (asn_constraints) { // has ASN.1 subtype constraint
2830 SubtypeConstraint* asn_parent_subtype = NULL;
2831 if (parent_subtype) {
2832 // the type constraint of the ASN.1 type is already in the parent_subtype,
2833 // don't add it multiple times
2834 asn_parent_subtype = parent_subtype->get_root();
2835 } else {
2836 asn_parent_subtype = get_asn_type_constraint(my_owner);
2837 }
2838 asn_constraints->chk(asn_parent_subtype);
2839 root = asn_constraints->get_subtype();
2840 extendable = asn_constraints->is_extendable();
2841 extension = asn_constraints->get_extension();
2842 // the TTCN-3 subtype will be the union of the root and extension parts
2843 // the ETSI ES 201 873-7 V4.1.2 (2009-07) document says to "ignore any extension markers"
2844 // but titan now works this way :)
2845 if (root) copy(root);
2846 if (extension) union_(extension);
2847 } else { // no constraints on this type -> this is an alias type, just copy the subtype from the other
2848 if (parent_subtype) {
2849 root = parent_subtype->root;
2850 extendable = parent_subtype->extendable;
2851 extension = parent_subtype->extension;
2852 copy(parent_subtype);
2853 } else {
2854 SubtypeConstraint* asn_parent_subtype = get_asn_type_constraint(my_owner);
2855 if (asn_parent_subtype) copy(asn_parent_subtype);
2856 }
2857 }
2858
2859 // check if subtype is valid: it must not be an empty set (is_empty==TTRUE)
2860 // issue warning if subtype is given but is full set (is_full==TTRUE)
2861 // ignore cases of TUNKNOWN when compiler can't figure out if the aggregate
2862 // set is empty or full
2863 switch (subtype) {
2864 case ST_INTEGER:
2865 if (integer_st!=NULL) {
2866 if (integer_st->is_empty()==TTRUE) goto empty_error;
2867 if (integer_st->is_full()==TTRUE) {
2868 print_full_warning();
2869 delete integer_st;
2870 integer_st = NULL;
2871 }
2872 }
2873 break;
2874 case ST_FLOAT:
2875 if (float_st!=NULL) {
2876 if (float_st->is_empty()==TTRUE) goto empty_error;
2877 if (float_st->is_full()==TTRUE) {
2878 print_full_warning();
2879 delete float_st;
2880 float_st = NULL;
2881 }
2882 }
2883 break;
2884 case ST_BOOLEAN:
2885 if (boolean_st!=NULL) {
2886 if (boolean_st->is_empty()==TTRUE) goto empty_error;
2887 if (boolean_st->is_full()==TTRUE) {
2888 print_full_warning();
2889 delete boolean_st;
2890 boolean_st = NULL;
2891 }
2892 }
2893 break;
2894 case ST_VERDICTTYPE:
2895 if (verdict_st!=NULL) {
2896 if (verdict_st->is_empty()==TTRUE) goto empty_error;
2897 if (verdict_st->is_full()==TTRUE) {
2898 print_full_warning();
2899 delete verdict_st;
2900 verdict_st = NULL;
2901 }
2902 }
2903 break;
2904 case ST_BITSTRING:
2905 if (bitstring_st!=NULL) {
2906 if (bitstring_st->is_empty()==TTRUE) goto empty_error;
2907 if (bitstring_st->is_full()==TTRUE) {
2908 print_full_warning();
2909 delete bitstring_st;
2910 bitstring_st = NULL;
2911 }
2912 }
2913 break;
2914 case ST_HEXSTRING:
2915 if (hexstring_st!=NULL) {
2916 if (hexstring_st->is_empty()==TTRUE) goto empty_error;
2917 if (hexstring_st->is_full()==TTRUE) {
2918 print_full_warning();
2919 delete hexstring_st;
2920 hexstring_st = NULL;
2921 }
2922 }
2923 break;
2924 case ST_OCTETSTRING:
2925 if (octetstring_st!=NULL) {
2926 if (octetstring_st->is_empty()==TTRUE) goto empty_error;
2927 if (octetstring_st->is_full()==TTRUE) {
2928 print_full_warning();
2929 delete octetstring_st;
2930 octetstring_st = NULL;
2931 }
2932 }
2933 break;
2934 case ST_CHARSTRING:
2935 if (charstring_st!=NULL) {
2936 if (charstring_st->is_empty()==TTRUE) goto empty_error;
2937 if (charstring_st->is_full()==TTRUE) {
2938 print_full_warning();
2939 delete charstring_st;
2940 charstring_st = NULL;
2941 }
2942 }
2943 break;
2944 case ST_UNIVERSAL_CHARSTRING:
2945 if (universal_charstring_st!=NULL) {
2946 if (universal_charstring_st->is_empty()==TTRUE) goto empty_error;
2947 if (universal_charstring_st->is_full()==TTRUE) {
2948 print_full_warning();
2949 delete universal_charstring_st;
2950 universal_charstring_st = NULL;
2951 }
2952 }
2953 break;
2954 case ST_OBJID:
2955 case ST_RECORD:
2956 case ST_SET:
2957 case ST_ENUM:
2958 case ST_UNION:
2959 case ST_FUNCTION:
2960 case ST_ALTSTEP:
2961 case ST_TESTCASE:
2962 if (value_st!=NULL) {
2963 if (value_st->is_empty()==TTRUE) goto empty_error;
2964 if (value_st->is_full()==TTRUE) {
2965 print_full_warning();
2966 delete value_st;
2967 value_st = NULL;
2968 }
2969 }
2970 break;
2971 case ST_RECORDOF:
2972 case ST_SETOF:
2973 if (recof_st!=NULL) {
2974 if (recof_st->is_empty()==TTRUE) goto empty_error;
2975 if (recof_st->is_full()==TTRUE) {
2976 print_full_warning();
2977 delete recof_st;
2978 recof_st = NULL;
2979 }
2980 }
2981 break;
2982 default:
2983 FATAL_ERROR("SubType::chk()");
2984 }
2985 if ((length_restriction!=NULL) && (length_restriction->is_full()==TTRUE)) {
2986 delete length_restriction;
2987 length_restriction = NULL;
2988 }
2989 checked = STC_YES;
2990 return;
2991
2992 empty_error:
2993 my_owner->error("The subtype is an empty set");
2994 set_to_error();
2995 checked = STC_YES;
2996 return;
2997 }
2998
2999 void SubType::dump(unsigned level) const
3000 {
3001 string str = to_string();
3002 if (str.size()>0) DEBUG(level, "restriction(s): %s", str.c_str());
3003 }
3004
3005 Int SubType::get_length_restriction() const
3006 {
3007 if (checked!=STC_YES) FATAL_ERROR("SubType::get_length_restriction()");
3008 if (parsed==NULL) return -1; // only own length restriction counts
3009 if (length_restriction==NULL) return -1;
3010 if (length_restriction->is_empty()) return -1;
3011 return ( (length_restriction->get_minimal()==length_restriction->get_maximal()) ?
3012 (Int)(length_restriction->get_minimal().get_size()) :
3013 -1 );
3014 }
3015
3016 bool SubType::zero_length_allowed() const
3017 {
3018 if (checked!=STC_YES) FATAL_ERROR("SubType::zero_length_allowed()");
3019 if (parsed==NULL) return true; // only own length restriction counts
3020 if (length_restriction==NULL) return true;
3021 return length_restriction->is_element(size_limit_t(0));
3022 }
3023
3024 string SubType::to_string() const
3025 {
3026 if (root) {
3027 string ret_val(root->to_string());
3028 if (extendable) ret_val += ", ...";
3029 if (extension) {
3030 ret_val += ", ";
3031 ret_val += extension->to_string();
3032 }
3033 return ret_val;
3034 }
3035 return SubtypeConstraint::to_string();
3036 }
3037
3038 ////////////////////////////////////////////////////////////////////////////////
3039
3040 void SubType::generate_code(output_struct &)
3041 {
3042 if (checked!=STC_YES) FATAL_ERROR("SubType::generate_code()");
3043 }
3044
3045 void SubType::generate_json_schema(JSON_Tokenizer& json,
3046 bool allow_special_float /* = true */)
3047 {
3048 bool has_value_list = false;
3049 size_t nof_ranges = 0;
3050 for (size_t i = 0; i < parsed->size(); ++i) {
3051 SubTypeParse *parse = (*parsed)[i];
3052 switch (parse->get_selection()) {
3053 case SubTypeParse::STP_SINGLE:
3054 // single values will be added later, all at once
3055 has_value_list = true;
3056 break;
3057 case SubTypeParse::STP_RANGE:
3058 ++nof_ranges;
3059 break;
3060 case SubTypeParse::STP_LENGTH: {
3061 Ttcn::LengthRestriction* len_res = parse->Length();
3062 Value* min_val = len_res->get_is_range() ? len_res->get_lower_value() :
3063 len_res->get_single_value();
3064 Value* max_val = len_res->get_is_range() ? len_res->get_upper_value() :
3065 len_res->get_single_value();
3066 const char* json_min = NULL;
3067 const char* json_max = NULL;
3068 switch (subtype) {
3069 case ST_RECORDOF:
3070 case ST_SETOF:
3071 // use minItems and maxItems for record of/set of
3072 json_min = "minItems";
3073 json_max = "maxItems";
3074 break;
3075 case ST_BITSTRING:
3076 case ST_HEXSTRING:
3077 case ST_OCTETSTRING:
3078 case ST_CHARSTRING:
3079 case ST_UNIVERSAL_CHARSTRING:
3080 // use minLength and maxLength for string types
3081 json_min = "minLength";
3082 json_max = "maxLength";
3083 break;
3084 default:
3085 FATAL_ERROR("SubType::generate_json_schema - length %d", subtype);
3086 }
3087 json.put_next_token(JSON_TOKEN_NAME, json_min);
3088 min_val->generate_json_value(json);
3089 if (max_val != NULL) {
3090 json.put_next_token(JSON_TOKEN_NAME, json_max);
3091 max_val->generate_json_value(json);
3092 }
3093 break; }
3094 case SubTypeParse::STP_PATTERN: {
3095 json.put_next_token(JSON_TOKEN_NAME, "pattern");
3096 char* json_pattern = parse->Pattern()->convert_to_json();
3097 json.put_next_token(JSON_TOKEN_STRING, json_pattern);
3098 Free(json_pattern);
3099 break; }
3100 default:
3101 break;
3102 }
3103 }
3104
3105 bool need_anyOf = (subtype == ST_INTEGER || subtype == ST_FLOAT) &&
3106 (nof_ranges + (has_value_list ? 1 : 0) > 1);
3107 if (need_anyOf) {
3108 // there are multiple value range/value list restrictions,
3109 // they need to be grouped in an 'anyOf' structure
3110 json.put_next_token(JSON_TOKEN_NAME, "anyOf");
3111 json.put_next_token(JSON_TOKEN_ARRAY_START);
3112 json.put_next_token(JSON_TOKEN_OBJECT_START);
3113 }
3114 if (has_value_list) {
3115 // generate the value list into an enum
3116 json.put_next_token(JSON_TOKEN_NAME, "enum");
3117 json.put_next_token(JSON_TOKEN_ARRAY_START);
3118 generate_json_schema_value_list(json, allow_special_float, false);
3119 json.put_next_token(JSON_TOKEN_ARRAY_END);
3120 if (my_owner->has_as_value_union()) {
3121 // the original value list cannot always be recreated from the generated
3122 // JSON value list in case of "as value" unions (because there are no field
3123 // names)
3124 // the list needs to be regenerated with field names (as if it was a regular
3125 // union) under a new keyword (valueList)
3126 json.put_next_token(JSON_TOKEN_NAME, "valueList");
3127 json.put_next_token(JSON_TOKEN_ARRAY_START);
3128 generate_json_schema_value_list(json, allow_special_float, true);
3129 json.put_next_token(JSON_TOKEN_ARRAY_END);
3130 }
3131 }
3132 if (need_anyOf && has_value_list) {
3133 // end of the value list and beginning of the first value range
3134 json.put_next_token(JSON_TOKEN_OBJECT_END);
3135 json.put_next_token(JSON_TOKEN_OBJECT_START);
3136 }
3137 if (nof_ranges > 0) {
3138 switch (subtype) {
3139 case ST_INTEGER:
3140 case ST_FLOAT:
3141 generate_json_schema_number_ranges(json);
3142 break;
3143 case ST_CHARSTRING:
3144 case ST_UNIVERSAL_CHARSTRING: {
3145 // merge all string range restrictions into one JSON schema pattern
3146 char* pattern_str = mcopystrn("\"^[", 3);
3147 pattern_str = generate_json_schema_string_ranges(pattern_str);
3148 pattern_str = mputstrn(pattern_str, "]*$\"", 4);
3149 json.put_next_token(JSON_TOKEN_NAME, "pattern");
3150 json.put_next_token(JSON_TOKEN_STRING, pattern_str);
3151 Free(pattern_str);
3152 break; }
3153 default:
3154 FATAL_ERROR("SubType::generate_json_schema - range %d", subtype);
3155 }
3156 }
3157 if (need_anyOf) {
3158 // end of the 'anyOf' structure
3159 json.put_next_token(JSON_TOKEN_OBJECT_END);
3160 json.put_next_token(JSON_TOKEN_ARRAY_END);
3161 }
3162 }
3163
3164 void SubType::generate_json_schema_value_list(JSON_Tokenizer& json,
3165 bool allow_special_float,
3166 bool union_value_list)
3167 {
3168 for (size_t i = 0; i < parsed->size(); ++i) {
3169 SubTypeParse *parse = (*parsed)[i];
3170 if (parse->get_selection() == SubTypeParse::STP_SINGLE) {
3171 if (parse->Single()->get_valuetype() == Value::V_REFD) {
3172 Common::Assignment* ass = parse->Single()->get_reference()->get_refd_assignment();
3173 if (ass->get_asstype() == Common::Assignment::A_TYPE) {
3174 // it's a reference to another subtype, insert its value list here
3175 ass->get_Type()->get_sub_type()->generate_json_schema_value_list(json,
3176 allow_special_float, union_value_list);
3177 }
3178 }
3179 else {
3180 Ttcn::JsonOmitCombination omit_combo(parse->Single());
3181 do {
3182 parse->Single()->generate_json_value(json, allow_special_float,
3183 union_value_list, &omit_combo);
3184 } // only generate the first combination for the unions' "valueList" keyword
3185 while (!union_value_list && omit_combo.next());
3186 }
3187 }
3188 }
3189 }
3190
3191 bool SubType::generate_json_schema_number_ranges(JSON_Tokenizer& json, bool first /* = true */)
3192 {
3193 for (size_t i = 0; i < parsed->size(); ++i) {
3194 SubTypeParse *parse = (*parsed)[i];
3195 if (parse->get_selection() == SubTypeParse::STP_SINGLE) {
3196 if (parse->Single()->get_valuetype() == Value::V_REFD) {
3197 Common::Assignment* ass = parse->Single()->get_reference()->get_refd_assignment();
3198 if (ass->get_asstype() == Common::Assignment::A_TYPE) {
3199 // it's a reference to another subtype, insert its value ranges here
3200 first = ass->get_Type()->get_sub_type()->generate_json_schema_number_ranges(json, first);
3201 }
3202 }
3203 }
3204 else if (parse->get_selection() == SubTypeParse::STP_RANGE) {
3205 if (!first) {
3206 // the ranges are in an 'anyOf' structure, they need to be placed in an object
3207 json.put_next_token(JSON_TOKEN_OBJECT_END);
3208 json.put_next_token(JSON_TOKEN_OBJECT_START);
3209 }
3210 else {
3211 first = false;
3212 }
3213 // add the minimum and/or maximum values as numbers
3214 if (parse->Min() != NULL) {
3215 json.put_next_token(JSON_TOKEN_NAME, "minimum");
3216 parse->Min()->generate_json_value(json);
3217 json.put_next_token(JSON_TOKEN_NAME, "exclusiveMinimum");
3218 json.put_next_token(parse->MinExclusive() ? JSON_TOKEN_LITERAL_TRUE : JSON_TOKEN_LITERAL_FALSE);
3219 }
3220 if (parse->Max() != NULL) {
3221 json.put_next_token(JSON_TOKEN_NAME, "maximum");
3222 parse->Max()->generate_json_value(json);
3223 json.put_next_token(JSON_TOKEN_NAME, "exclusiveMaximum");
3224 json.put_next_token(parse->MaxExclusive() ? JSON_TOKEN_LITERAL_TRUE : JSON_TOKEN_LITERAL_FALSE);
3225 }
3226 }
3227 }
3228 return first;
3229 }
3230
3231 char* SubType::generate_json_schema_string_ranges(char* pattern_str)
3232 {
3233 for (size_t i = 0; i < parsed->size(); ++i) {
3234 SubTypeParse *parse = (*parsed)[i];
3235 if (parse->get_selection() == SubTypeParse::STP_SINGLE) {
3236 if (parse->Single()->get_valuetype() == Value::V_REFD) {
3237 Common::Assignment* ass = parse->Single()->get_reference()->get_refd_assignment();
3238 if (ass->get_asstype() == Common::Assignment::A_TYPE) {
3239 // it's a reference to another subtype, insert its string ranges here
3240 pattern_str = ass->get_Type()->get_sub_type()->generate_json_schema_string_ranges(pattern_str);
3241 }
3242 }
3243 }
3244 else if (parse->get_selection() == SubTypeParse::STP_RANGE) {
3245 // insert the string range into the pattern string
3246 string lower_str = (subtype == ST_CHARSTRING) ? parse->Min()->get_val_str() :
3247 ustring_to_uft8(parse->Min()->get_val_ustr());
3248 string upper_str = (subtype == ST_CHARSTRING) ? parse->Max()->get_val_str() :
3249 ustring_to_uft8(parse->Max()->get_val_ustr());
3250 pattern_str = mputprintf(pattern_str, "%s-%s", lower_str.c_str(), upper_str.c_str());
3251 }
3252 }
3253 return pattern_str;
3254 }
3255
3256 void SubType::generate_json_schema_float(JSON_Tokenizer& json)
3257 {
3258 bool has_nan = float_st->is_element(make_ttcn3float(REAL_NAN));
3259 bool has_pos_inf = float_st->is_element(make_ttcn3float(REAL_INFINITY));
3260 bool has_neg_inf = float_st->is_element(make_ttcn3float(-REAL_INFINITY));
3261 bool has_special = has_nan || has_pos_inf || has_neg_inf;
3262 bool has_number = false;
3263 for (size_t i = 0; i < parsed->size() && !has_number; ++i) {
3264 // go through the restrictions and check if at least one number is allowed
3265 SubTypeParse *parse = (*parsed)[i];
3266 switch (parse->get_selection()) {
3267 case SubTypeParse::STP_SINGLE: {
3268 Real r = parse->Single()->get_val_Real();
3269 if (r == r && r != REAL_INFINITY && r != -REAL_INFINITY) {
3270 // a single value other than NaN, INF and -INF is a number
3271 has_number = true;
3272 }
3273 break; }
3274 case SubTypeParse::STP_RANGE: {
3275 if (parse->Min() != NULL) {
3276 if (parse->Min()->get_val_Real() != REAL_INFINITY) {
3277 // a minimum value other than INF means a number is allowed
3278 has_number = true;
3279 }
3280 }
3281 if (parse->Max() != NULL) {
3282 // a maximum value other than -INF means a number is allowed
3283 if (parse->Max()->get_val_Real() != -REAL_INFINITY) {
3284 has_number = true;
3285 }
3286 }
3287 break; }
3288 default:
3289 break;
3290 }
3291 }
3292 if (has_number && has_special) {
3293 json.put_next_token(JSON_TOKEN_NAME, "anyOf");
3294 json.put_next_token(JSON_TOKEN_ARRAY_START);
3295 json.put_next_token(JSON_TOKEN_OBJECT_START);
3296 }
3297 if (has_number) {
3298 json.put_next_token(JSON_TOKEN_NAME, "type");
3299 json.put_next_token(JSON_TOKEN_STRING, "\"number\"");
3300 // generate the restrictions' schema elements here
3301 // (the 2nd parameter makes sure that NaN, INF and -INF are ignored)
3302 generate_json_schema(json, false);
3303 }
3304 if (has_number && has_special) {
3305 json.put_next_token(JSON_TOKEN_OBJECT_END);
3306 json.put_next_token(JSON_TOKEN_OBJECT_START);
3307 }
3308 if (has_special) {
3309 json.put_next_token(JSON_TOKEN_NAME, "enum");
3310 json.put_next_token(JSON_TOKEN_ARRAY_START);
3311 if (has_nan) {
3312 json.put_next_token(JSON_TOKEN_STRING, "\"not_a_number\"");
3313 }
3314 if (has_pos_inf) {
3315 json.put_next_token(JSON_TOKEN_STRING, "\"infinity\"");
3316 }
3317 if (has_neg_inf) {
3318 json.put_next_token(JSON_TOKEN_STRING, "\"-infinity\"");
3319 }
3320 json.put_next_token(JSON_TOKEN_ARRAY_END);
3321 }
3322 if (has_number && has_special) {
3323 json.put_next_token(JSON_TOKEN_OBJECT_END);
3324 json.put_next_token(JSON_TOKEN_ARRAY_END);
3325 }
3326 }
3327
3328 } // namespace Common
This page took 0.101504 seconds and 5 git commands to generate.