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