1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
9 #include "../common/dbgnew.hh"
10 #include "Identifier.hh"
14 #include "CompilerError.hh"
15 #include "Valuestuff.hh"
16 #include "ttcn3/TtcnTemplate.hh"
17 #include "ttcn3/Templatestuff.hh"
18 #include "ttcn3/PatternString.hh"
19 #include "Constraint.hh"
20 #include "../common/JSON_Tokenizer.hh"
21 #include "ttcn3/Ttcn2Json.hh"
27 /**************************
29 **************************/
31 SubTypeParse::SubTypeParse(Value
*p_single
)
32 : selection(STP_SINGLE
)
34 if (!p_single
) FATAL_ERROR("SubTypeParse::SubTypeParse()");
38 SubTypeParse::SubTypeParse(Value
*p_min
, bool p_min_exclusive
, Value
*p_max
, bool p_max_exclusive
)
39 : selection(STP_RANGE
)
42 range
.min_exclusive
= p_min_exclusive
;
44 range
.max_exclusive
= p_max_exclusive
;
47 SubTypeParse::SubTypeParse(Ttcn::LengthRestriction
*p_length
)
48 : selection(STP_LENGTH
)
50 if (!p_length
) FATAL_ERROR("SubTypeParse::SubTypeParse()");
54 SubTypeParse::SubTypeParse(Ttcn::PatternString
*p_pattern
)
55 : selection(STP_PATTERN
)
57 if (!p_pattern
) FATAL_ERROR("SubTypeParse::SubTypeParse()");
61 SubTypeParse::~SubTypeParse()
78 FATAL_ERROR("SubTypeParse::~SubTypeParse()");
82 Value
*SubTypeParse::Single() const
84 if (selection
!= STP_SINGLE
) FATAL_ERROR("SubTypeParse::Single()");
88 Value
*SubTypeParse::Min() const
90 if (selection
!= STP_RANGE
) FATAL_ERROR("SubTypeParse::Min()");
94 bool SubTypeParse::MinExclusive() const
96 if (selection
!= STP_RANGE
) FATAL_ERROR("SubTypeParse::MinExclusive()");
97 return range
.min_exclusive
;
100 Value
*SubTypeParse::Max() const
102 if (selection
!= STP_RANGE
) FATAL_ERROR("SubTypeParse::Max()");
106 bool SubTypeParse::MaxExclusive() const
108 if (selection
!= STP_RANGE
) FATAL_ERROR("SubTypeParse::MaxExclusive()");
109 return range
.max_exclusive
;
112 Ttcn::LengthRestriction
*SubTypeParse::Length() const
114 if (selection
!= STP_LENGTH
) FATAL_ERROR("SubTypeParse::Length()");
118 Ttcn::PatternString
*SubTypeParse::Pattern() const
120 if (selection
!= STP_PATTERN
) FATAL_ERROR("SubTypeParse::Pattern()");
124 /********************
125 class SubtypeConstraint
126 ********************/
128 SubtypeConstraint::SubtypeConstraint(subtype_t st
)
131 length_restriction
= NULL
;
152 octetstring_st
= NULL
;
155 charstring_st
= NULL
;
157 case ST_UNIVERSAL_CHARSTRING
:
158 universal_charstring_st
= NULL
;
175 FATAL_ERROR("SubtypeConstraint::SubtypeConstraint()");
179 void SubtypeConstraint::copy(const SubtypeConstraint
* other
)
181 if ((other
==NULL
) || (other
->subtype
!=subtype
)) FATAL_ERROR("SubtypeConstraint::copy()");
185 integer_st
= other
->integer_st
? new IntegerRangeListConstraint(*(other
->integer_st
)) : NULL
;
189 float_st
= other
->float_st
? new RealRangeListConstraint(*(other
->float_st
)) : NULL
;
193 boolean_st
= other
->boolean_st
? new BooleanListConstraint(*(other
->boolean_st
)) : NULL
;
197 verdict_st
= other
->verdict_st
? new VerdicttypeListConstraint(*(other
->verdict_st
)) : NULL
;
201 bitstring_st
= other
->bitstring_st
? new BitstringConstraint(*(other
->bitstring_st
)) : NULL
;
205 hexstring_st
= other
->hexstring_st
? new HexstringConstraint(*(other
->hexstring_st
)) : NULL
;
208 delete octetstring_st
;
209 octetstring_st
= other
->octetstring_st
? new OctetstringConstraint(*(other
->octetstring_st
)) : NULL
;
212 delete charstring_st
;
213 charstring_st
= other
->charstring_st
? new CharstringSubtypeTreeElement(*(other
->charstring_st
)) : NULL
;
215 case ST_UNIVERSAL_CHARSTRING
:
216 delete universal_charstring_st
;
217 universal_charstring_st
= other
->universal_charstring_st
? new UniversalCharstringSubtypeTreeElement(*(other
->universal_charstring_st
)) : NULL
;
228 value_st
= other
->value_st
? new ValueListConstraint(*(other
->value_st
)) : NULL
;
233 recof_st
= other
->recof_st
? new RecofConstraint(*(other
->recof_st
)) : NULL
;
236 FATAL_ERROR("SubtypeConstraint::copy()");
238 delete length_restriction
;
239 length_restriction
= other
->length_restriction
? new SizeRangeListConstraint(*(other
->length_restriction
)) : NULL
;
242 // used by get_asn_type_constraint() to store singleton objects and delete them on program exit
243 struct AsnTypeConstraintSingleton
245 SubtypeConstraint
*printablestring_stc
, *numericstring_stc
, *bmpstring_stc
;
246 AsnTypeConstraintSingleton():
247 printablestring_stc(NULL
), numericstring_stc(NULL
), bmpstring_stc(NULL
) {}
248 ~AsnTypeConstraintSingleton();
251 AsnTypeConstraintSingleton::~AsnTypeConstraintSingleton()
253 delete printablestring_stc
;
254 delete numericstring_stc
;
255 delete bmpstring_stc
;
258 SubtypeConstraint
* SubtypeConstraint::get_asn_type_constraint(Type
* type
)
260 static AsnTypeConstraintSingleton asn_tcs
;
261 static const char_limit_t
zero('0'), nine('9'),
262 bigA('A'), bigZ('Z'), smalla('a'), smallz('z');
263 static const universal_char_limit_t
uni_zero(0);
264 static const universal_char_limit_t
uni_ffff((1<<16)-1);
265 static const CharRangeListConstraint
numeric_string_char_range(
266 CharRangeListConstraint(zero
, nine
) +
267 CharRangeListConstraint(char_limit_t(' ')));
268 static const CharRangeListConstraint
printable_string_char_range(
269 CharRangeListConstraint(bigA
, bigZ
) +
270 CharRangeListConstraint(smalla
, smallz
) +
271 CharRangeListConstraint(zero
, nine
) +
272 CharRangeListConstraint(char_limit_t(' ')) +
273 CharRangeListConstraint(char_limit_t('\'')) +
274 CharRangeListConstraint(char_limit_t('(')) +
275 CharRangeListConstraint(char_limit_t(')')) +
276 CharRangeListConstraint(char_limit_t('+')) +
277 CharRangeListConstraint(char_limit_t(',')) +
278 CharRangeListConstraint(char_limit_t('-')) +
279 CharRangeListConstraint(char_limit_t('.')) +
280 CharRangeListConstraint(char_limit_t('/')) +
281 CharRangeListConstraint(char_limit_t(':')) +
282 CharRangeListConstraint(char_limit_t('=')) +
283 CharRangeListConstraint(char_limit_t('?')));
284 static const UniversalCharRangeListConstraint
bmp_string_char_range(
285 UniversalCharRangeListConstraint(uni_zero
, uni_ffff
));
287 switch (type
->get_typetype()) {
288 case Type::T_TELETEXSTRING
:
289 // TODO: based on ITU-T Recommendation T.61
291 case Type::T_VIDEOTEXSTRING
:
292 // TODO: based on ITU-T Recommendation T.100 and T.101
294 case Type::T_NUMERICSTRING
:
295 if (asn_tcs
.numericstring_stc
==NULL
) {
296 asn_tcs
.numericstring_stc
= new SubtypeConstraint(ST_CHARSTRING
);
297 asn_tcs
.numericstring_stc
->charstring_st
= new CharstringSubtypeTreeElement(numeric_string_char_range
, false);
299 return asn_tcs
.numericstring_stc
;
300 case Type::T_PRINTABLESTRING
:
301 if (asn_tcs
.printablestring_stc
==NULL
) {
302 asn_tcs
.printablestring_stc
= new SubtypeConstraint(ST_CHARSTRING
);
303 asn_tcs
.printablestring_stc
->charstring_st
= new CharstringSubtypeTreeElement(printable_string_char_range
, false);
305 return asn_tcs
.printablestring_stc
;
306 case Type::T_BMPSTRING
:
307 if (asn_tcs
.bmpstring_stc
==NULL
) {
308 asn_tcs
.bmpstring_stc
= new SubtypeConstraint(ST_UNIVERSAL_CHARSTRING
);
309 asn_tcs
.bmpstring_stc
->universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(bmp_string_char_range
, false);
311 return asn_tcs
.bmpstring_stc
;
317 SubtypeConstraint
* SubtypeConstraint::create_from_asn_value(Type
* type
, Value
* value
)
319 Value
* v
= value
->get_value_refd_last();
320 subtype_t st_t
= type
->get_subtype_type();
321 if ( (st_t
==ST_ERROR
) || (v
->get_valuetype()==Value::V_ERROR
) ) return NULL
;
322 SubtypeConstraint
* stc
= new SubtypeConstraint(st_t
);
323 switch (v
->get_valuetype()) {
325 if (st_t
!=ST_INTEGER
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
326 stc
->integer_st
= new IntegerRangeListConstraint(int_limit_t(*(v
->get_val_Int())));
328 case Value::V_REAL
: {
329 if (st_t
!=ST_FLOAT
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
330 ttcn3float r
= v
->get_val_Real();
331 if (r
!=r
) stc
->float_st
= new RealRangeListConstraint(true);
332 else stc
->float_st
= new RealRangeListConstraint(real_limit_t(r
));
335 if (st_t
!=ST_BOOLEAN
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
336 stc
->boolean_st
= new BooleanListConstraint(v
->get_val_bool());
340 if (v
->has_oid_error()) goto invalid_value
;
341 if (st_t
!=ST_OBJID
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
342 stc
->value_st
= new ValueListConstraint(v
);
345 if (st_t
!=ST_BITSTRING
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
346 stc
->bitstring_st
= new BitstringConstraint(v
->get_val_str());
349 if (st_t
!=ST_HEXSTRING
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
350 stc
->hexstring_st
= new HexstringConstraint(v
->get_val_str());
353 if (st_t
!=ST_OCTETSTRING
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
354 stc
->octetstring_st
= new OctetstringConstraint(v
->get_val_str());
357 if (st_t
!=ST_CHARSTRING
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
358 stc
->charstring_st
= new CharstringSubtypeTreeElement(StringValueConstraint
<string
>(v
->get_val_str()));
360 case Value::V_ISO2022STR
:
361 if (st_t
!=ST_CHARSTRING
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
362 stc
->charstring_st
= new CharstringSubtypeTreeElement(StringValueConstraint
<string
>(v
->get_val_iso2022str()));
364 case Value::V_CHARSYMS
:
366 if (st_t
!=ST_UNIVERSAL_CHARSTRING
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
367 stc
->universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(StringValueConstraint
<ustring
>(v
->get_val_ustr()));
370 case Value::V_NULL
: // FIXME: should go to ST_NULL
371 if (st_t
!=ST_ENUM
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
372 stc
->value_st
= new ValueListConstraint(v
);
374 case Value::V_CHOICE
:
375 case Value::V_OPENTYPE
: // FIXME?
376 if (st_t
!=ST_UNION
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
377 stc
->value_st
= new ValueListConstraint(v
);
380 if (st_t
!=ST_RECORD
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
381 stc
->value_st
= new ValueListConstraint(v
);
384 if (st_t
!=ST_SET
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
385 stc
->value_st
= new ValueListConstraint(v
);
388 if (st_t
!=ST_RECORDOF
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
389 stc
->recof_st
= new RecofConstraint(v
);
392 if (st_t
!=ST_SETOF
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
393 stc
->recof_st
= new RecofConstraint(v
);
404 SubtypeConstraint
* SubtypeConstraint::create_from_asn_charvalues(Type
* type
, Value
* value
)
406 Value
* v
= value
->get_value_refd_last();
407 subtype_t st_t
= type
->get_subtype_type();
408 if ( (st_t
==ST_ERROR
) || (v
->get_valuetype()==Value::V_ERROR
) ) return NULL
;
409 SubtypeConstraint
* stc
= new SubtypeConstraint(st_t
);
410 switch (v
->get_valuetype()) {
412 case Value::V_ISO2022STR
: {
413 if (st_t
!=ST_CHARSTRING
) FATAL_ERROR("SubtypeConstraint::create_from_asn_charvalues()");
414 CharRangeListConstraint charvalues
;
415 string val_str
= (v
->get_valuetype()==Value::V_CSTR
) ? v
->get_val_str() : v
->get_val_iso2022str();
416 for (size_t i
=0; i
<val_str
.size(); i
++) {
417 if (!char_limit_t::is_valid_value(val_str
[i
])) {
418 value
->error("Invalid char in string %s at index %lu",
419 value
->get_stringRepr().c_str(), (unsigned long)i
);
422 charvalues
= charvalues
+ CharRangeListConstraint(val_str
[i
]);
424 stc
->charstring_st
= new CharstringSubtypeTreeElement(charvalues
, true);
426 case Value::V_CHARSYMS
: {
428 if (st_t
!=ST_UNIVERSAL_CHARSTRING
) FATAL_ERROR("SubtypeConstraint::create_from_asn_charvalues()");
429 UniversalCharRangeListConstraint ucharvalues
;
430 ustring val_ustr
= v
->get_val_ustr();
431 for (size_t i
=0; i
<val_ustr
.size(); i
++) {
432 if (!universal_char_limit_t::is_valid_value(val_ustr
[i
])) {
433 value
->error("Invalid universal char in string %s at index %lu",
434 value
->get_stringRepr().c_str(), (unsigned long)i
);
437 ucharvalues
= ucharvalues
+ UniversalCharRangeListConstraint(val_ustr
[i
]);
439 stc
->universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(ucharvalues
, true);
442 // error was already reported
451 int_limit_t
SubtypeConstraint::get_int_limit(bool is_upper
, Location
* loc
)
453 int_limit_t default_limit
= is_upper
?
454 int_limit_t::maximum
:
455 ((subtype
==ST_INTEGER
) ? int_limit_t::minimum
: int_limit_t(int_val_t((Int
)0)));
459 if (integer_st
->is_empty()==TTRUE
) {
460 loc
->error("Cannot determine the value of %s: the parent subtype is an empty set.",
461 is_upper
?"MAX":"MIN");
462 return default_limit
;
464 return is_upper
? integer_st
->get_maximal() : integer_st
->get_minimal();
467 return default_limit
;
471 tribool tb
= bitstring_st
->get_size_limit(is_upper
, sl
);
472 if (tb
==TTRUE
) return sl
.to_int_limit();
475 return default_limit
;
479 tribool tb
= hexstring_st
->get_size_limit(is_upper
, sl
);
480 if (tb
==TTRUE
) return sl
.to_int_limit();
483 return default_limit
;
485 if (octetstring_st
) {
487 tribool tb
= octetstring_st
->get_size_limit(is_upper
, sl
);
488 if (tb
==TTRUE
) return sl
.to_int_limit();
491 return default_limit
;
495 tribool tb
= charstring_st
->get_size_limit(is_upper
, sl
);
498 loc
->error("Cannot determine the value of %s: the parent subtype does "
499 "not define a %simal size value", is_upper
?"MAX":"MIN", is_upper
?"max":"min");
502 loc
->warning("Cannot determine the value of %s from parent subtype %s",
503 is_upper
?"MAX":"MIN", to_string().c_str());
506 return sl
.to_int_limit();
508 FATAL_ERROR("SubtypeConstraint::get_int_limit()");
511 return default_limit
;
512 case ST_UNIVERSAL_CHARSTRING
:
513 if (universal_charstring_st
) {
515 tribool tb
= universal_charstring_st
->get_size_limit(is_upper
, sl
);
518 loc
->error("Cannot determine the value of %s: the parent subtype does "
519 "not define a %simal size value", is_upper
?"MAX":"MIN", is_upper
?"max":"min");
522 loc
->warning("Cannot determine the value of %s from parent subtype %s",
523 is_upper
?"MAX":"MIN", to_string().c_str());
526 return sl
.to_int_limit();
528 FATAL_ERROR("SubtypeConstraint::get_int_limit()");
531 return default_limit
;
536 tribool tb
= recof_st
->get_size_limit(is_upper
, sl
);
537 if (tb
==TTRUE
) return sl
.to_int_limit();
540 return default_limit
;
542 FATAL_ERROR("SubtypeConstraint::get_int_limit()");
544 loc
->error("Cannot determine the value of %s from parent subtype %s",
545 is_upper
?"MAX":"MIN", to_string().c_str());
546 return default_limit
;
549 SubtypeConstraint
* SubtypeConstraint::create_from_asn_range(
550 Value
* vmin
, bool min_exclusive
, Value
* vmax
, bool max_exclusive
,
551 Location
* loc
, subtype_t st_t
, SubtypeConstraint
* parent_subtype
)
554 case SubtypeConstraint::ST_INTEGER
: {
555 if (((vmin
!=NULL
) && (vmin
->get_valuetype()!=Value::V_INT
)) ||
556 ((vmax
!=NULL
) && (vmax
->get_valuetype()!=Value::V_INT
))) return NULL
;
558 int_limit_t min_limit
;
560 min_limit
= int_limit_t(*(vmin
->get_val_Int()));
561 } else { // MIN was used
562 if (parent_subtype
) {
563 min_limit
= parent_subtype
->get_int_limit(false, loc
);
565 min_limit
= int_limit_t::minimum
;
570 if (min_limit
==int_limit_t::minimum
) {
571 loc
->error("invalid lower boundary, -infinity cannot be excluded from an INTEGER value range constraint");
574 min_limit
= min_limit
.next();
578 int_limit_t max_limit
;
580 max_limit
= int_limit_t(*(vmax
->get_val_Int()));
581 } else { // MAX was used
582 if (parent_subtype
) {
583 max_limit
= parent_subtype
->get_int_limit(true, loc
);
585 max_limit
= int_limit_t::maximum
;
590 if (max_limit
==int_limit_t::maximum
) {
591 loc
->error("invalid upper boundary, infinity cannot be excluded from an INTEGER value range constraint");
594 max_limit
= max_limit
.previous();
597 if (max_limit
<min_limit
) {
598 loc
->error("lower boundary is bigger than upper boundary in INTEGER value range constraint");
601 SubtypeConstraint
* stc
= new SubtypeConstraint(st_t
);
602 stc
->integer_st
= new IntegerRangeListConstraint(min_limit
, max_limit
);
606 if (((vmin
!=NULL
) && (vmin
->get_valuetype()!=Value::V_REAL
)) ||
607 ((vmax
!=NULL
) && (vmax
->get_valuetype()!=Value::V_REAL
))) return NULL
;
608 if ((vmin
!=NULL
) && (vmin
->get_val_Real()!=vmin
->get_val_Real())) {
609 loc
->error("lower boundary cannot be NOT-A-NUMBER in REAL value range constraint");
612 if ((vmax
!=NULL
) && (vmax
->get_val_Real()!=vmax
->get_val_Real())) {
613 loc
->error("upper boundary cannot be NOT-A-NUMBER in REAL value range constraint");
617 if (parent_subtype
&& (parent_subtype
->subtype
!=ST_FLOAT
)) FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
618 real_limit_t min_limit
;
620 min_limit
= real_limit_t(vmin
->get_val_Real());
621 } else { // MIN was used
622 if (parent_subtype
&& parent_subtype
->float_st
) {
623 if (parent_subtype
->float_st
->is_range_empty()==TTRUE
) {
624 loc
->error("Cannot determine the value of MIN: the parent subtype has no range");
625 min_limit
= real_limit_t::minimum
;
627 min_limit
= parent_subtype
->float_st
->get_minimal();
630 min_limit
= real_limit_t::minimum
;
635 min_limit
= min_limit
.next();
638 real_limit_t max_limit
;
640 max_limit
= real_limit_t(vmax
->get_val_Real());
641 } else { // MAX was used
642 if (parent_subtype
&& parent_subtype
->float_st
) {
643 if (parent_subtype
->float_st
->is_range_empty()==TTRUE
) {
644 loc
->error("Cannot determine the value of MAX: the parent subtype has no range");
645 max_limit
= real_limit_t::maximum
;
647 max_limit
= parent_subtype
->float_st
->get_maximal();
650 max_limit
= real_limit_t::maximum
;
655 max_limit
= max_limit
.previous();
657 if (max_limit
<min_limit
) {
658 loc
->error("lower boundary is bigger than upper boundary in REAL value range constraint");
661 SubtypeConstraint
* stc
= new SubtypeConstraint(st_t
);
662 stc
->float_st
= new RealRangeListConstraint(min_limit
, max_limit
);
665 case ST_CHARSTRING
: {
666 if (((vmin
!=NULL
) && (vmin
->get_valuetype()!=Value::V_CSTR
)) ||
667 ((vmax
!=NULL
) && (vmax
->get_valuetype()!=Value::V_CSTR
))) return NULL
;
668 if (vmin
&& (vmin
->get_val_str().size()!=1)) {
669 vmin
->error("lower boundary of string value range constraint must be a single element string");
672 if (vmax
&& (vmax
->get_val_str().size()!=1)) {
673 vmax
->error("upper boundary of string value range constraint must be a single element string");
676 if (vmin
&& !char_limit_t::is_valid_value(*vmin
->get_val_str().c_str())) {
677 vmin
->error("lower boundary of string value range constraint is an invalid char");
680 if (vmax
&& !char_limit_t::is_valid_value(*vmax
->get_val_str().c_str())) {
681 vmax
->error("upper boundary of string value range constraint is an invalid char");
685 if (parent_subtype
&& (parent_subtype
->subtype
!=ST_CHARSTRING
)) FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
687 char_limit_t min_limit
;
689 min_limit
= char_limit_t(*vmin
->get_val_str().c_str());
690 } else { // MIN was used
691 if (parent_subtype
&& parent_subtype
->charstring_st
) {
692 tribool tb
= parent_subtype
->charstring_st
->get_alphabet_limit(false, min_limit
);
695 loc
->error("Cannot determine the value of MIN: the parent subtype does not define a minimal char value");
696 min_limit
= char_limit_t::minimum
;
699 loc
->warning("Cannot determine the value of MIN, using the minimal char value of the type");
700 min_limit
= char_limit_t::minimum
;
703 // min_limit was set to the correct value
706 FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
709 min_limit
= char_limit_t::minimum
;
714 if (min_limit
==char_limit_t::maximum
) {
715 loc
->error("exclusive lower boundary is not a legal character");
718 min_limit
= min_limit
.next();
721 char_limit_t max_limit
;
723 max_limit
= char_limit_t(*vmax
->get_val_str().c_str());
724 } else { // MAX was used
725 if (parent_subtype
&& parent_subtype
->charstring_st
) {
726 tribool tb
= parent_subtype
->charstring_st
->get_alphabet_limit(true, max_limit
);
729 loc
->error("Cannot determine the value of MAX: the parent subtype does not define a maximal char value");
730 max_limit
= char_limit_t::maximum
;
733 loc
->warning("Cannot determine the value of MAX, using the maximal char value of the type");
734 max_limit
= char_limit_t::maximum
;
737 // max_limit was set to the correct value
740 FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
743 max_limit
= char_limit_t::maximum
;
748 if (max_limit
==char_limit_t::minimum
) {
749 loc
->error("exclusive upper boundary is not a legal character");
752 max_limit
= max_limit
.previous();
754 if (max_limit
<min_limit
) {
755 loc
->error("lower boundary is bigger than upper boundary in string value range constraint");
758 SubtypeConstraint
* stc
= new SubtypeConstraint(st_t
);
759 stc
->charstring_st
= new CharstringSubtypeTreeElement(CharRangeListConstraint(min_limit
,max_limit
), true);
762 case ST_UNIVERSAL_CHARSTRING
: {
763 if (((vmin
!=NULL
) && (vmin
->get_valuetype()!=Value::V_USTR
)) ||
764 ((vmax
!=NULL
) && (vmax
->get_valuetype()!=Value::V_USTR
))) return NULL
;
765 if (vmin
&& (vmin
->get_val_ustr().size()!=1)) {
766 vmin
->error("lower boundary of string value range constraint must be a single element string");
769 if (vmax
&& (vmax
->get_val_ustr().size()!=1)) {
770 vmax
->error("upper boundary of string value range constraint must be a single element string");
773 if (vmin
&& !universal_char_limit_t::is_valid_value(*vmin
->get_val_ustr().u_str())) {
774 vmin
->error("lower boundary of string value range constraint is an invalid universal char");
777 if (vmax
&& !universal_char_limit_t::is_valid_value(*vmax
->get_val_ustr().u_str())) {
778 vmax
->error("upper boundary of string value range constraint is an invalid universal char");
782 if (parent_subtype
&& (parent_subtype
->subtype
!=ST_UNIVERSAL_CHARSTRING
)) FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
783 universal_char_limit_t min_limit
;
785 min_limit
= universal_char_limit_t(*vmin
->get_val_ustr().u_str());
786 } else { // MIN was used
787 if (parent_subtype
&& parent_subtype
->universal_charstring_st
) {
788 tribool tb
= parent_subtype
->universal_charstring_st
->get_alphabet_limit(false, min_limit
);
791 loc
->error("Cannot determine the value of MIN: the parent subtype does not define a minimal char value");
792 min_limit
= universal_char_limit_t::minimum
;
795 loc
->warning("Cannot determine the value of MIN, using the minimal char value of the type");
796 min_limit
= universal_char_limit_t::minimum
;
799 // min_limit was set to the correct value
802 FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
805 min_limit
= universal_char_limit_t::minimum
;
810 if (min_limit
==universal_char_limit_t::maximum
) {
811 loc
->error("exclusive lower boundary is not a legal character");
814 min_limit
= min_limit
.next();
817 universal_char_limit_t max_limit
;
819 max_limit
= universal_char_limit_t(*vmax
->get_val_ustr().u_str());
820 } else { // MAX was used
821 if (parent_subtype
&& parent_subtype
->universal_charstring_st
) {
822 tribool tb
= parent_subtype
->universal_charstring_st
->get_alphabet_limit(true, max_limit
);
825 loc
->error("Cannot determine the value of MAX: the parent subtype does not define a maximal char value");
826 max_limit
= universal_char_limit_t::maximum
;
829 loc
->warning("Cannot determine the value of MAX, using the maximal char value of the type");
830 max_limit
= universal_char_limit_t::maximum
;
833 // max_limit was set to the correct value
836 FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
839 max_limit
= universal_char_limit_t::maximum
;
844 if (max_limit
==universal_char_limit_t::minimum
) {
845 loc
->error("exclusive upper boundary is not a legal character");
848 max_limit
= max_limit
.previous();
850 if (max_limit
<min_limit
) {
851 loc
->error("lower boundary is bigger than upper boundary in string value range constraint");
854 SubtypeConstraint
* stc
= new SubtypeConstraint(st_t
);
855 stc
->universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharRangeListConstraint(min_limit
,max_limit
), true);
859 FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
864 SubtypeConstraint
* SubtypeConstraint::create_from_contained_subtype(SubtypeConstraint
* contained_stc
, bool char_context
, Location
* loc
)
866 if (contained_stc
==NULL
) return NULL
;
867 SubtypeConstraint
* rv_stc
= NULL
;
869 switch (contained_stc
->get_subtypetype()) {
871 if (contained_stc
->charstring_st
==NULL
) {
872 rv_stc
= new SubtypeConstraint(contained_stc
->get_subtypetype()); // full set
874 if (contained_stc
->charstring_st
->is_valid_range()) {
875 rv_stc
= new SubtypeConstraint(contained_stc
->get_subtypetype());
876 rv_stc
->copy(contained_stc
);
877 rv_stc
->charstring_st
->set_char_context(true);
879 loc
->error("The type of the contained subtype constraint cannot be used in a permitted alphabet constraint");
883 case ST_UNIVERSAL_CHARSTRING
:
884 if (contained_stc
->universal_charstring_st
==NULL
) {
885 rv_stc
= new SubtypeConstraint(contained_stc
->get_subtypetype()); // full set
887 if (contained_stc
->universal_charstring_st
->is_valid_range()) {
888 rv_stc
= new SubtypeConstraint(contained_stc
->get_subtypetype());
889 rv_stc
->copy(contained_stc
);
890 rv_stc
->universal_charstring_st
->set_char_context(true);
892 loc
->error("The type of the contained subtype constraint cannot be used in a permitted alphabet constraint");
897 // error was already reported
901 rv_stc
= new SubtypeConstraint(contained_stc
->get_subtypetype());
902 rv_stc
->copy(contained_stc
);
907 SubtypeConstraint
* SubtypeConstraint::create_asn_size_constraint(
908 SubtypeConstraint
* integer_stc
, bool char_context
, Type
* type
, Location
* loc
)
910 if (integer_stc
==NULL
) return NULL
;
911 // convert IntegerRangeListConstraint to SizeRangeListConstraint
912 if (integer_stc
->subtype
!=ST_INTEGER
) FATAL_ERROR("SubtypeConstraint::create_asn_size_constraint()");
913 SizeRangeListConstraint
size_constraint(size_limit_t::minimum
, size_limit_t::maximum
);
914 if (integer_stc
->integer_st
) {
915 static const int_val_t
zero((Int
)0);
916 static const int_limit_t
ilt0(zero
);
917 IntegerRangeListConstraint
valid_range(ilt0
, int_limit_t::maximum
);
918 if (integer_stc
->integer_st
->is_subset(valid_range
)==TFALSE
) {
919 loc
->error("Range %s is not a valid range for a size constraint", integer_stc
->to_string().c_str());
921 bool success
= convert_int_to_size(*(integer_stc
->integer_st
), size_constraint
);
923 loc
->error("One or more INTEGER values of range %s are too large to be used in a size constraint", integer_stc
->to_string().c_str());
927 subtype_t st_t
= type
->get_subtype_type();
928 if (st_t
==ST_ERROR
) return NULL
;
929 SubtypeConstraint
* stc
= new SubtypeConstraint(st_t
);
932 stc
->length_restriction
= new SizeRangeListConstraint(size_constraint
); // FIXME? : is this Ok if not a top level constraint?
937 stc
->bitstring_st
= new BitstringConstraint(size_constraint
);
940 stc
->hexstring_st
= new HexstringConstraint(size_constraint
);
943 stc
->octetstring_st
= new OctetstringConstraint(size_constraint
);
947 if (size_constraint
.is_equal(SizeRangeListConstraint(size_limit_t(1)))==TFALSE
) {
948 loc
->error("Only SIZE(1) constraint can be used inside a permitted alphabet constraint");
952 // SIZE(1) is allowed in char context, it means ALL
954 stc
->charstring_st
= new CharstringSubtypeTreeElement(size_constraint
);
957 case ST_UNIVERSAL_CHARSTRING
:
959 if (size_constraint
.is_equal(SizeRangeListConstraint(size_limit_t(1)))==TFALSE
) {
960 loc
->error("Only SIZE(1) constraint can be used inside a permitted alphabet constraint");
964 // SIZE(1) is allowed in char context, it means ALL
966 stc
->universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(size_constraint
);
971 stc
->recof_st
= new RecofConstraint(size_constraint
);
974 loc
->error("Size constraint is not allowed for type `%s'", type
->get_typename().c_str());
981 SubtypeConstraint
* SubtypeConstraint::create_permitted_alphabet_constraint(
982 SubtypeConstraint
* stc
, bool char_context
, Type
* type
, Location
* loc
)
985 loc
->error("Permitted alphabet constraint not allowed inside a permitted alphabet constraint");
988 subtype_t st_t
= type
->get_subtype_type();
991 case ST_UNIVERSAL_CHARSTRING
: {
992 if (stc
==NULL
) return NULL
; // error was reported there
993 if (st_t
!=stc
->get_subtypetype()) FATAL_ERROR("SubtypeConstraint::create_permitted_alphabet_constraint()");
994 SubtypeConstraint
* rv_stc
= new SubtypeConstraint(st_t
);
995 if (st_t
==ST_CHARSTRING
) {
996 if (stc
->charstring_st
) {
997 rv_stc
->charstring_st
= new CharstringSubtypeTreeElement(*(stc
->charstring_st
));
998 rv_stc
->charstring_st
->set_char_context(false);
1001 if (stc
->universal_charstring_st
) {
1002 rv_stc
->universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(*(stc
->universal_charstring_st
));
1003 rv_stc
->universal_charstring_st
->set_char_context(false);
1009 // error already reported
1012 loc
->error("Permitted alphabet constraint is not allowed for type `%s'", type
->get_typename().c_str());
1018 void SubtypeConstraint::set_to_error()
1032 case ST_VERDICTTYPE
:
1036 delete bitstring_st
;
1039 delete hexstring_st
;
1041 case ST_OCTETSTRING
:
1042 delete octetstring_st
;
1045 delete charstring_st
;
1047 case ST_UNIVERSAL_CHARSTRING
:
1048 delete universal_charstring_st
;
1065 FATAL_ERROR("SubtypeConstraint::set_to_error()");
1068 delete length_restriction
;
1069 length_restriction
= NULL
;
1072 string
SubtypeConstraint::to_string() const
1076 return string("<error>");
1078 return (integer_st
==NULL
) ? string() : integer_st
->to_string();
1080 return (float_st
==NULL
) ? string() : float_st
->to_string();
1082 return (boolean_st
==NULL
) ? string() : boolean_st
->to_string();
1083 case ST_VERDICTTYPE
:
1084 return (verdict_st
==NULL
) ? string() : verdict_st
->to_string();
1086 return (bitstring_st
==NULL
) ? string() : bitstring_st
->to_string();
1088 return (hexstring_st
==NULL
) ? string() : hexstring_st
->to_string();
1089 case ST_OCTETSTRING
:
1090 return (octetstring_st
==NULL
) ? string() : octetstring_st
->to_string();
1092 return (charstring_st
==NULL
) ? string() : charstring_st
->to_string();
1093 case ST_UNIVERSAL_CHARSTRING
:
1094 return (universal_charstring_st
==NULL
) ? string() : universal_charstring_st
->to_string();
1103 return (value_st
==NULL
) ? string() : value_st
->to_string();
1106 return (recof_st
==NULL
) ? string() : recof_st
->to_string();
1108 FATAL_ERROR("SubtypeConstraint::to_string()");
1112 bool SubtypeConstraint::is_compatible(const SubtypeConstraint
*p_st
) const
1114 if (p_st
==NULL
) return true; // the other type has no subtype restriction
1115 if ( (subtype
==ST_ERROR
) || (p_st
->subtype
==ST_ERROR
) ) return true;
1116 if (subtype
!=p_st
->subtype
) FATAL_ERROR("SubtypeConstraint::is_compatible()");
1117 // if the resulting set.is_empty()==TUNKNOWN then remain silent
1120 if ((integer_st
==NULL
) || (p_st
->integer_st
==NULL
)) return true;
1121 return ((*integer_st
**(p_st
->integer_st
)).is_empty()!=TTRUE
);
1123 if ((float_st
==NULL
) || (p_st
->float_st
==NULL
)) return true;
1124 return ((*float_st
**(p_st
->float_st
)).is_empty()!=TTRUE
);
1126 if ((boolean_st
==NULL
) || (p_st
->boolean_st
==NULL
)) return true;
1127 return ((*boolean_st
**(p_st
->boolean_st
)).is_empty()!=TTRUE
);
1128 case ST_VERDICTTYPE
:
1129 if ((verdict_st
==NULL
) || (p_st
->verdict_st
==NULL
)) return true;
1130 return ((*verdict_st
**(p_st
->verdict_st
)).is_empty()!=TTRUE
);
1132 if ((bitstring_st
==NULL
) || (p_st
->bitstring_st
==NULL
)) return true;
1133 return ((*bitstring_st
**(p_st
->bitstring_st
)).is_empty()!=TTRUE
);
1135 if ((hexstring_st
==NULL
) || (p_st
->hexstring_st
==NULL
)) return true;
1136 return ((*hexstring_st
**(p_st
->hexstring_st
)).is_empty()!=TTRUE
);
1137 case ST_OCTETSTRING
:
1138 if ((octetstring_st
==NULL
) || (p_st
->octetstring_st
==NULL
)) return true;
1139 return ((*octetstring_st
**(p_st
->octetstring_st
)).is_empty()!=TTRUE
);
1140 case ST_CHARSTRING
: {
1141 if ((charstring_st
==NULL
) || (p_st
->charstring_st
==NULL
)) return true;
1142 CharstringSubtypeTreeElement
* cc
= new CharstringSubtypeTreeElement(
1143 CharstringSubtypeTreeElement::ET_INTERSECTION
,
1144 new CharstringSubtypeTreeElement(*charstring_st
),
1145 new CharstringSubtypeTreeElement(*(p_st
->charstring_st
))
1147 bool rv
= (cc
->is_empty()!=TTRUE
);
1151 case ST_UNIVERSAL_CHARSTRING
: {
1152 if ((universal_charstring_st
==NULL
) || (p_st
->universal_charstring_st
==NULL
)) return true;
1153 UniversalCharstringSubtypeTreeElement
* ucc
= new UniversalCharstringSubtypeTreeElement(
1154 UniversalCharstringSubtypeTreeElement::ET_INTERSECTION
,
1155 new UniversalCharstringSubtypeTreeElement(*universal_charstring_st
),
1156 new UniversalCharstringSubtypeTreeElement(*(p_st
->universal_charstring_st
))
1158 bool rv
= (ucc
->is_empty()!=TTRUE
);
1170 if ((value_st
==NULL
) || (p_st
->value_st
==NULL
)) return true;
1171 return ((*value_st
**(p_st
->value_st
)).is_empty()!=TTRUE
);
1174 if ((recof_st
==NULL
) || (p_st
->recof_st
==NULL
)) return true;
1175 return ((*recof_st
**(p_st
->recof_st
)).is_empty()!=TTRUE
);
1177 FATAL_ERROR("SubtypeConstraint::is_compatible()");
1182 bool SubtypeConstraint::is_compatible_with_elem() const
1184 if (subtype
==ST_ERROR
) return true;
1186 case ST_BITSTRING
: {
1187 static BitstringConstraint
str_elem(size_limit_t(1));
1188 if (bitstring_st
==NULL
) return true;
1189 return ((*bitstring_st
*str_elem
).is_empty()!=TTRUE
);
1191 case ST_HEXSTRING
: {
1192 static HexstringConstraint
str_elem(size_limit_t(1));
1193 if (hexstring_st
==NULL
) return true;
1194 return ((*hexstring_st
*str_elem
).is_empty()!=TTRUE
);
1196 case ST_OCTETSTRING
: {
1197 static OctetstringConstraint
str_elem(size_limit_t(1));
1198 if (octetstring_st
==NULL
) return true;
1199 return ((*octetstring_st
*str_elem
).is_empty()!=TTRUE
);
1201 case ST_CHARSTRING
: {
1202 size_limit_t t
= size_limit_t(1);
1203 SizeRangeListConstraint temp
= SizeRangeListConstraint(t
);
1204 static CharstringSubtypeTreeElement
str_elem(temp
);
1205 if (charstring_st
==NULL
) return true;
1206 CharstringSubtypeTreeElement
* cc
= new CharstringSubtypeTreeElement(
1207 CharstringSubtypeTreeElement::ET_INTERSECTION
,
1208 new CharstringSubtypeTreeElement(*charstring_st
),
1209 new CharstringSubtypeTreeElement(str_elem
)
1211 bool rv
= (cc
->is_empty()!=TTRUE
);
1215 case ST_UNIVERSAL_CHARSTRING
: {
1216 size_limit_t t
= size_limit_t(1);
1217 SizeRangeListConstraint temp
= SizeRangeListConstraint(t
);
1218 static UniversalCharstringSubtypeTreeElement
str_elem(temp
);
1219 if (universal_charstring_st
==NULL
) return true;
1220 UniversalCharstringSubtypeTreeElement
* ucc
= new UniversalCharstringSubtypeTreeElement(
1221 UniversalCharstringSubtypeTreeElement::ET_INTERSECTION
,
1222 new UniversalCharstringSubtypeTreeElement(*universal_charstring_st
),
1223 new UniversalCharstringSubtypeTreeElement(str_elem
)
1225 bool rv
= (ucc
->is_empty()!=TTRUE
);
1230 FATAL_ERROR("SubtypeConstraint::is_compatible_with_elem()");
1235 bool SubtypeConstraint::is_length_compatible(const SubtypeConstraint
*p_st
) const
1237 if (p_st
==NULL
) FATAL_ERROR("SubtypeConstraint::is_length_compatible()");
1238 if ((subtype
==ST_ERROR
) || (p_st
->subtype
==ST_ERROR
)) return true;
1239 if (subtype
!= ST_RECORDOF
&& subtype
!= ST_SETOF
&&
1240 p_st
->subtype
!= ST_RECORDOF
&& p_st
->subtype
!= ST_SETOF
)
1241 FATAL_ERROR("SubtypeConstraint::is_length_compatible()");
1242 if (length_restriction
==NULL
|| p_st
->length_restriction
==NULL
) return true;
1243 return ((*length_restriction
* *(p_st
->length_restriction
)).is_empty()!=TTRUE
);
1246 bool SubtypeConstraint::is_upper_limit_infinity() const
1248 if (ST_INTEGER
== subtype
&& integer_st
) {
1249 return integer_st
->is_upper_limit_infinity();
1251 if (ST_FLOAT
== subtype
&& float_st
) {
1252 return float_st
->is_upper_limit_infinity();
1257 bool SubtypeConstraint::is_lower_limit_infinity() const
1259 if (ST_INTEGER
== subtype
&& integer_st
) {
1260 return integer_st
->is_lower_limit_infinity();
1263 if (ST_FLOAT
== subtype
&& float_st
) {
1264 return float_st
->is_lower_limit_infinity();
1270 void SubtypeConstraint::except(const SubtypeConstraint
* other
)
1272 if (other
==NULL
) FATAL_ERROR("SubtypeConstraint::except()");
1273 if (subtype
!=other
->subtype
) FATAL_ERROR("SubtypeConstraint::except()");
1276 if (other
->integer_st
==NULL
) {
1277 if (integer_st
==NULL
) {
1278 integer_st
= new IntegerRangeListConstraint();
1280 *integer_st
= IntegerRangeListConstraint();
1283 if (integer_st
==NULL
) {
1284 integer_st
= new IntegerRangeListConstraint(~*(other
->integer_st
));
1286 *integer_st
= *integer_st
- *(other
->integer_st
);
1291 if (other
->float_st
==NULL
) {
1292 if (float_st
==NULL
) {
1293 float_st
= new RealRangeListConstraint();
1295 *float_st
= RealRangeListConstraint();
1298 if (float_st
==NULL
) {
1299 float_st
= new RealRangeListConstraint(~*(other
->float_st
));
1301 *float_st
= *float_st
- *(other
->float_st
);
1306 if (other
->boolean_st
==NULL
) {
1307 if (boolean_st
==NULL
) {
1308 boolean_st
= new BooleanListConstraint();
1310 *boolean_st
= BooleanListConstraint();
1313 if (boolean_st
==NULL
) {
1314 boolean_st
= new BooleanListConstraint(~*(other
->boolean_st
));
1316 *boolean_st
= *boolean_st
- *(other
->boolean_st
);
1320 case ST_VERDICTTYPE
:
1321 if (other
->verdict_st
==NULL
) {
1322 if (verdict_st
==NULL
) {
1323 verdict_st
= new VerdicttypeListConstraint();
1325 *verdict_st
= VerdicttypeListConstraint();
1328 if (verdict_st
==NULL
) {
1329 verdict_st
= new VerdicttypeListConstraint(~*(other
->verdict_st
));
1331 *verdict_st
= *verdict_st
- *(other
->verdict_st
);
1336 if (other
->bitstring_st
==NULL
) {
1337 if (bitstring_st
==NULL
) {
1338 bitstring_st
= new BitstringConstraint();
1340 *bitstring_st
= BitstringConstraint();
1343 if (bitstring_st
==NULL
) {
1344 bitstring_st
= new BitstringConstraint(~*(other
->bitstring_st
));
1346 *bitstring_st
= *bitstring_st
- *(other
->bitstring_st
);
1351 if (other
->hexstring_st
==NULL
) {
1352 if (hexstring_st
==NULL
) {
1353 hexstring_st
= new HexstringConstraint();
1355 *hexstring_st
= HexstringConstraint();
1358 if (hexstring_st
==NULL
) {
1359 hexstring_st
= new HexstringConstraint(~*(other
->hexstring_st
));
1361 *hexstring_st
= *hexstring_st
- *(other
->hexstring_st
);
1365 case ST_OCTETSTRING
:
1366 if (other
->octetstring_st
==NULL
) {
1367 if (octetstring_st
==NULL
) {
1368 octetstring_st
= new OctetstringConstraint();
1370 *octetstring_st
= OctetstringConstraint();
1373 if (octetstring_st
==NULL
) {
1374 octetstring_st
= new OctetstringConstraint(~*(other
->octetstring_st
));
1376 *octetstring_st
= *octetstring_st
- *(other
->octetstring_st
);
1381 if (other
->charstring_st
==NULL
) {
1382 if (charstring_st
==NULL
) {
1383 charstring_st
= new CharstringSubtypeTreeElement();
1385 *charstring_st
= CharstringSubtypeTreeElement();
1388 if (charstring_st
==NULL
) {
1389 CharstringSubtypeTreeElement
* call_st
= new CharstringSubtypeTreeElement();
1391 charstring_st
= new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_EXCEPT
,
1392 call_st
, new CharstringSubtypeTreeElement(*(other
->charstring_st
)));
1394 charstring_st
= new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_EXCEPT
,
1395 charstring_st
, new CharstringSubtypeTreeElement(*(other
->charstring_st
)));
1399 case ST_UNIVERSAL_CHARSTRING
:
1400 if (other
->universal_charstring_st
==NULL
) {
1401 if (universal_charstring_st
==NULL
) {
1402 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement();
1404 *universal_charstring_st
= UniversalCharstringSubtypeTreeElement();
1407 if (universal_charstring_st
==NULL
) {
1408 UniversalCharstringSubtypeTreeElement
* ucall_st
= new UniversalCharstringSubtypeTreeElement();
1409 ucall_st
->set_all();
1410 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_EXCEPT
,
1411 ucall_st
, new UniversalCharstringSubtypeTreeElement(*(other
->universal_charstring_st
)));
1413 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_EXCEPT
,
1414 universal_charstring_st
, new UniversalCharstringSubtypeTreeElement(*(other
->universal_charstring_st
)));
1426 if (other
->value_st
==NULL
) {
1427 if (value_st
==NULL
) {
1428 value_st
= new ValueListConstraint();
1430 *value_st
= ValueListConstraint();
1433 if (value_st
==NULL
) {
1434 value_st
= new ValueListConstraint(~*(other
->value_st
));
1436 *value_st
= *value_st
- *(other
->value_st
);
1442 if (other
->recof_st
==NULL
) {
1443 if (recof_st
==NULL
) {
1444 recof_st
= new RecofConstraint();
1446 *recof_st
= RecofConstraint();
1449 if (recof_st
==NULL
) {
1450 recof_st
= new RecofConstraint(~*(other
->recof_st
));
1452 *recof_st
= *recof_st
- *(other
->recof_st
);
1457 FATAL_ERROR("SubtypeConstraint::except()");
1459 if (other
->length_restriction
==NULL
) {
1460 if (length_restriction
==NULL
) {
1461 length_restriction
= new SizeRangeListConstraint();
1463 *length_restriction
= SizeRangeListConstraint();
1466 if (length_restriction
==NULL
) {
1467 length_restriction
= new SizeRangeListConstraint(~*(other
->length_restriction
));
1469 *length_restriction
= *length_restriction
- *(other
->length_restriction
);
1474 void SubtypeConstraint::union_(const SubtypeConstraint
* other
)
1476 if (other
==NULL
) FATAL_ERROR("SubtypeConstraint::union_()");
1477 if (subtype
!=other
->subtype
) FATAL_ERROR("SubtypeConstraint::union_()");
1480 if (integer_st
==NULL
) break;
1481 if (other
->integer_st
==NULL
) { delete integer_st
; integer_st
= NULL
; break; }
1482 *integer_st
= *integer_st
+ *(other
->integer_st
);
1485 if (float_st
==NULL
) break;
1486 if (other
->float_st
==NULL
) { delete float_st
; float_st
= NULL
; break; }
1487 *float_st
= *float_st
+ *(other
->float_st
);
1490 if (boolean_st
==NULL
) break;
1491 if (other
->boolean_st
==NULL
) { delete boolean_st
; boolean_st
= NULL
; break; }
1492 *boolean_st
= *boolean_st
+ *(other
->boolean_st
);
1494 case ST_VERDICTTYPE
:
1495 if (verdict_st
==NULL
) break;
1496 if (other
->verdict_st
==NULL
) { delete verdict_st
; verdict_st
= NULL
; break; }
1497 *verdict_st
= *verdict_st
+ *(other
->verdict_st
);
1500 if (bitstring_st
==NULL
) break;
1501 if (other
->bitstring_st
==NULL
) { delete bitstring_st
; bitstring_st
= NULL
; break; }
1502 *bitstring_st
= *bitstring_st
+ *(other
->bitstring_st
);
1505 if (hexstring_st
==NULL
) break;
1506 if (other
->hexstring_st
==NULL
) { delete hexstring_st
; hexstring_st
= NULL
; break; }
1507 *hexstring_st
= *hexstring_st
+ *(other
->hexstring_st
);
1509 case ST_OCTETSTRING
:
1510 if (octetstring_st
==NULL
) break;
1511 if (other
->octetstring_st
==NULL
) { delete octetstring_st
; octetstring_st
= NULL
; break; }
1512 *octetstring_st
= *octetstring_st
+ *(other
->octetstring_st
);
1515 if (charstring_st
==NULL
) break;
1516 if (other
->charstring_st
==NULL
) { delete charstring_st
; charstring_st
= NULL
; break; }
1517 charstring_st
= new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_UNION
,
1518 charstring_st
, new CharstringSubtypeTreeElement(*(other
->charstring_st
)));
1520 case ST_UNIVERSAL_CHARSTRING
:
1521 if (universal_charstring_st
==NULL
) break;
1522 if (other
->universal_charstring_st
==NULL
) { delete universal_charstring_st
; universal_charstring_st
= NULL
; break; }
1523 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_UNION
,
1524 universal_charstring_st
, new UniversalCharstringSubtypeTreeElement(*(other
->universal_charstring_st
)));
1534 if (value_st
==NULL
) break;
1535 if (other
->value_st
==NULL
) { delete value_st
; value_st
= NULL
; break; }
1536 *value_st
= *value_st
+ *(other
->value_st
);
1540 if (recof_st
==NULL
) break;
1541 if (other
->recof_st
==NULL
) { delete recof_st
; recof_st
= NULL
; break; }
1542 *recof_st
= *recof_st
+ *(other
->recof_st
);
1545 FATAL_ERROR("SubtypeConstraint::union_()");
1547 if (length_restriction
!=NULL
) {
1548 if (other
->length_restriction
==NULL
) {
1549 delete length_restriction
;
1550 length_restriction
= NULL
;
1552 *length_restriction
= *length_restriction
+ *(other
->length_restriction
);
1557 void SubtypeConstraint::intersection(const SubtypeConstraint
* other
)
1559 if (other
==NULL
) FATAL_ERROR("SubtypeConstraint::intersection()");
1560 if (subtype
!=other
->subtype
) FATAL_ERROR("SubtypeConstraint::intersection()");
1563 if (other
->integer_st
!=NULL
) {
1564 if (integer_st
==NULL
) {
1565 integer_st
= new IntegerRangeListConstraint(*(other
->integer_st
));
1567 *integer_st
= *integer_st
* *(other
->integer_st
);
1572 if (other
->float_st
!=NULL
) {
1573 if (float_st
==NULL
) {
1574 float_st
= new RealRangeListConstraint(*(other
->float_st
));
1576 *float_st
= *float_st
* *(other
->float_st
);
1581 if (other
->boolean_st
!=NULL
) {
1582 if (boolean_st
==NULL
) {
1583 boolean_st
= new BooleanListConstraint(*(other
->boolean_st
));
1585 *boolean_st
= *boolean_st
* *(other
->boolean_st
);
1589 case ST_VERDICTTYPE
:
1590 if (other
->verdict_st
!=NULL
) {
1591 if (verdict_st
==NULL
) {
1592 verdict_st
= new VerdicttypeListConstraint(*(other
->verdict_st
));
1594 *verdict_st
= *verdict_st
* *(other
->verdict_st
);
1599 if (other
->bitstring_st
!=NULL
) {
1600 if (bitstring_st
==NULL
) {
1601 bitstring_st
= new BitstringConstraint(*(other
->bitstring_st
));
1603 *bitstring_st
= *bitstring_st
* *(other
->bitstring_st
);
1608 if (other
->hexstring_st
!=NULL
) {
1609 if (hexstring_st
==NULL
) {
1610 hexstring_st
= new HexstringConstraint(*(other
->hexstring_st
));
1612 *hexstring_st
= *hexstring_st
* *(other
->hexstring_st
);
1616 case ST_OCTETSTRING
:
1617 if (other
->octetstring_st
!=NULL
) {
1618 if (octetstring_st
==NULL
) {
1619 octetstring_st
= new OctetstringConstraint(*(other
->octetstring_st
));
1621 *octetstring_st
= *octetstring_st
* *(other
->octetstring_st
);
1626 if (other
->charstring_st
!=NULL
) {
1627 if (charstring_st
==NULL
) {
1628 charstring_st
= new CharstringSubtypeTreeElement(*(other
->charstring_st
));
1630 charstring_st
= new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_INTERSECTION
,
1631 charstring_st
, new CharstringSubtypeTreeElement(*(other
->charstring_st
)));
1635 case ST_UNIVERSAL_CHARSTRING
:
1636 if (other
->universal_charstring_st
!=NULL
) {
1637 if (universal_charstring_st
==NULL
) {
1638 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(*(other
->universal_charstring_st
));
1640 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_INTERSECTION
,
1641 universal_charstring_st
, new UniversalCharstringSubtypeTreeElement(*(other
->universal_charstring_st
)));
1653 if (other
->value_st
!=NULL
) {
1654 if (value_st
==NULL
) {
1655 value_st
= new ValueListConstraint(*(other
->value_st
));
1657 *value_st
= *value_st
* *(other
->value_st
);
1663 if (other
->recof_st
!=NULL
) {
1664 if (recof_st
==NULL
) {
1665 recof_st
= new RecofConstraint(*(other
->recof_st
));
1667 *recof_st
= *recof_st
* *(other
->recof_st
);
1672 FATAL_ERROR("SubtypeConstraint::intersection()");
1674 if (other
->length_restriction
!=NULL
) {
1675 if (length_restriction
==NULL
) {
1676 length_restriction
= new SizeRangeListConstraint(*(other
->length_restriction
));
1678 *length_restriction
= *length_restriction
* *(other
->length_restriction
);
1683 tribool
SubtypeConstraint::is_subset(const SubtypeConstraint
* other
) const
1685 if (other
==NULL
) return TTRUE
;
1686 if (other
->subtype
!=subtype
) FATAL_ERROR("SubtypeConstraint::is_subset()");
1689 if (other
->integer_st
==NULL
) return TTRUE
;
1690 return integer_st
? integer_st
->is_subset(*(other
->integer_st
)) : TTRUE
;
1692 if (other
->float_st
==NULL
) return TTRUE
;
1693 return float_st
? float_st
->is_subset(*(other
->float_st
)) : TTRUE
;
1695 if (other
->boolean_st
==NULL
) return TTRUE
;
1696 return boolean_st
? boolean_st
->is_subset(*(other
->boolean_st
)) : TTRUE
;
1697 case ST_VERDICTTYPE
:
1698 if (other
->verdict_st
==NULL
) return TTRUE
;
1699 return verdict_st
? verdict_st
->is_subset(*(other
->verdict_st
)) : TTRUE
;
1701 if (other
->bitstring_st
==NULL
) return TTRUE
;
1702 return bitstring_st
? bitstring_st
->is_subset(*(other
->bitstring_st
)) : TTRUE
;
1704 if (other
->hexstring_st
==NULL
) return TTRUE
;
1705 return hexstring_st
? hexstring_st
->is_subset(*(other
->hexstring_st
)) : TTRUE
;
1706 case ST_OCTETSTRING
:
1707 if (other
->octetstring_st
==NULL
) return TTRUE
;
1708 return octetstring_st
? octetstring_st
->is_subset(*(other
->octetstring_st
)) : TTRUE
;
1710 if (other
->charstring_st
==NULL
) return TTRUE
;
1711 return charstring_st
? charstring_st
->is_subset(other
->charstring_st
) : TTRUE
;
1712 case ST_UNIVERSAL_CHARSTRING
:
1713 if (other
->universal_charstring_st
==NULL
) return TTRUE
;
1714 return universal_charstring_st
? universal_charstring_st
->is_subset(other
->universal_charstring_st
) : TTRUE
;
1723 if (other
->value_st
==NULL
) return TTRUE
;
1724 return value_st
? value_st
->is_subset(*(other
->value_st
)) : TTRUE
;
1727 if (other
->recof_st
==NULL
) return TTRUE
;
1728 return recof_st
? recof_st
->is_subset(*(other
->recof_st
)) : TTRUE
;
1730 FATAL_ERROR("SubtypeConstraint::is_subset()");
1735 /********************
1737 ********************/
1739 SubType::SubType(subtype_t st
, Type
*p_my_owner
, SubType
* p_parent_subtype
,
1740 vector
<SubTypeParse
> *p_parsed
, Constraints
* p_asn_constraints
)
1741 : SubtypeConstraint(st
), my_owner(p_my_owner
), parent_subtype(p_parent_subtype
)
1742 , parsed(p_parsed
), asn_constraints(p_asn_constraints
)
1743 , root(0), extendable(false), extension(0), checked(STC_NO
)
1746 if (p_my_owner
==NULL
) FATAL_ERROR("SubType::SubType()");
1754 void SubType::chk_this_value(Value
*value
)
1756 if (checked
==STC_NO
) FATAL_ERROR("SubType::chk_this_value()");
1757 if ((checked
==STC_CHECKING
) || (subtype
==ST_ERROR
)) return;
1758 Value
*val
= value
->get_value_refd_last();
1759 bool is_invalid
= false;
1760 switch (val
->get_valuetype()) {
1762 if (subtype
!=ST_INTEGER
) FATAL_ERROR("SubType::chk_this_value()");
1763 is_invalid
= (integer_st
!=NULL
) && !integer_st
->is_element(int_limit_t(*(val
->get_val_Int())));
1766 if (subtype
!=ST_FLOAT
) FATAL_ERROR("SubType::chk_this_value()");
1767 is_invalid
= (float_st
!=NULL
) && !float_st
->is_element(val
->get_val_Real());
1770 if (subtype
!=ST_BOOLEAN
) FATAL_ERROR("SubType::chk_this_value()");
1771 is_invalid
= (boolean_st
!=NULL
) && !boolean_st
->is_element(val
->get_val_bool());
1773 case Value::V_VERDICT
: {
1774 if (subtype
!=ST_VERDICTTYPE
) FATAL_ERROR("SubType::chk_this_value()");
1775 VerdicttypeListConstraint::verdicttype_constraint_t vtc
;
1776 switch (val
->get_val_verdict()) {
1777 case Value::Verdict_NONE
: vtc
= VerdicttypeListConstraint::VC_NONE
; break;
1778 case Value::Verdict_PASS
: vtc
= VerdicttypeListConstraint::VC_PASS
; break;
1779 case Value::Verdict_INCONC
: vtc
= VerdicttypeListConstraint::VC_INCONC
; break;
1780 case Value::Verdict_FAIL
: vtc
= VerdicttypeListConstraint::VC_FAIL
; break;
1781 case Value::Verdict_ERROR
: vtc
= VerdicttypeListConstraint::VC_ERROR
; break;
1782 default: FATAL_ERROR("SubType::chk_this_value()");
1784 is_invalid
= (verdict_st
!=NULL
) && !verdict_st
->is_element(vtc
);
1787 if (subtype
!=ST_BITSTRING
) FATAL_ERROR("SubType::chk_this_value()");
1788 is_invalid
= (bitstring_st
!=NULL
) && !bitstring_st
->is_element(val
->get_val_str());
1791 if (subtype
!=ST_HEXSTRING
) FATAL_ERROR("SubType::chk_this_value()");
1792 is_invalid
= (hexstring_st
!=NULL
) && !hexstring_st
->is_element(val
->get_val_str());
1795 if (subtype
!=ST_OCTETSTRING
) FATAL_ERROR("SubType::chk_this_value()");
1796 is_invalid
= (octetstring_st
!=NULL
) && !octetstring_st
->is_element(val
->get_val_str());
1799 case Value::V_ISO2022STR
:
1800 if (subtype
!=ST_CHARSTRING
) FATAL_ERROR("SubType::chk_this_value()");
1801 is_invalid
= (charstring_st
!=NULL
) && !charstring_st
->is_element(val
->get_val_str());
1804 case Value::V_CHARSYMS
:
1805 if (subtype
!=ST_UNIVERSAL_CHARSTRING
) FATAL_ERROR("SubType::chk_this_value()");
1806 is_invalid
= (universal_charstring_st
!=NULL
) && !universal_charstring_st
->is_element(val
->get_val_ustr());
1808 case Value::V_SEQOF
:
1809 if (subtype
!=ST_RECORDOF
) FATAL_ERROR("SubType::chk_this_value()");
1810 if (value
->is_unfoldable()) return;
1811 is_invalid
= (recof_st
!=NULL
) && !recof_st
->is_element(val
);
1813 case Value::V_SETOF
:
1814 if (subtype
!=ST_SETOF
) FATAL_ERROR("SubType::chk_this_value()");
1815 if (value
->is_unfoldable()) return;
1816 is_invalid
= (recof_st
!=NULL
) && !recof_st
->is_element(val
);
1820 if (subtype
!=ST_OBJID
) FATAL_ERROR("SubType::chk_this_value()");
1821 if (value
->is_unfoldable()) return;
1822 is_invalid
= (value_st
!=NULL
) && !value_st
->is_element(val
);
1825 case Value::V_NULL
: // FIXME: should go to ST_NULL
1826 if (subtype
!=ST_ENUM
) FATAL_ERROR("SubType::chk_this_value()");
1827 if (value
->is_unfoldable()) return;
1828 is_invalid
= (value_st
!=NULL
) && !value_st
->is_element(val
);
1830 case Value::V_CHOICE
:
1831 case Value::V_OPENTYPE
: // FIXME?
1832 if (subtype
!=ST_UNION
) FATAL_ERROR("SubType::chk_this_value()");
1833 if (value
->is_unfoldable()) return;
1834 is_invalid
= (value_st
!=NULL
) && !value_st
->is_element(val
);
1837 if (subtype
!=ST_RECORD
) FATAL_ERROR("SubType::chk_this_value()");
1838 if (value
->is_unfoldable()) return;
1839 is_invalid
= (value_st
!=NULL
) && !value_st
->is_element(val
);
1842 if (subtype
!=ST_SET
) FATAL_ERROR("SubType::chk_this_value()");
1843 if (value
->is_unfoldable()) return;
1844 is_invalid
= (value_st
!=NULL
) && !value_st
->is_element(val
);
1846 case Value::V_FUNCTION
:
1847 if (subtype
!=ST_FUNCTION
) FATAL_ERROR("SubType::chk_this_value()");
1848 if (value
->is_unfoldable()) return;
1849 is_invalid
= (value_st
!=NULL
) && !value_st
->is_element(val
);
1851 case Value::V_ALTSTEP
:
1852 if (subtype
!=ST_ALTSTEP
) FATAL_ERROR("SubType::chk_this_value()");
1853 if (value
->is_unfoldable()) return;
1854 is_invalid
= (value_st
!=NULL
) && !value_st
->is_element(val
);
1856 case Value::V_TESTCASE
:
1857 if (subtype
!=ST_TESTCASE
) FATAL_ERROR("SubType::chk_this_value()");
1858 if (value
->is_unfoldable()) return;
1859 is_invalid
= (value_st
!=NULL
) && !value_st
->is_element(val
);
1861 case Value::V_ERROR
:
1867 value
->error("%s is not a valid value for type `%s' which has subtype %s",
1868 val
->get_stringRepr().c_str(),
1869 my_owner
->get_typename().c_str(),
1870 to_string().c_str());
1875 void SubType::chk_this_template_generic(Template
*templ
)
1877 if (checked
==STC_NO
) FATAL_ERROR("SubType::chk_this_template_generic()");
1878 if ((checked
==STC_CHECKING
) || (subtype
==ST_ERROR
)) return;
1879 templ
= templ
->get_template_refd_last();
1880 switch (templ
->get_templatetype()) {
1881 case Ttcn::Template::OMIT_VALUE
:
1882 case Ttcn::Template::ANY_OR_OMIT
:
1883 case Ttcn::Template::TEMPLATE_ERROR
:
1884 case Ttcn::Template::ANY_VALUE
:
1886 case Ttcn::Template::VALUE_LIST
:
1887 case Ttcn::Template::COMPLEMENTED_LIST
:
1888 /* Should be canonical before */
1890 case Ttcn::Template::SPECIFIC_VALUE
:
1891 /* SPECIFIC_VALUE must be already checked in Type::chk_this_template() */
1893 case Ttcn::Template::TEMPLATE_REFD
:
1894 /* unfoldable reference: cannot be checked at compile time */
1896 case Ttcn::Template::TEMPLATE_INVOKE
:
1897 /* should be already checked in Type::chk_this_template() */
1900 chk_this_template(templ
);
1903 chk_this_template_length_restriction(templ
);
1907 void SubType::chk_this_template(Template
*templ
)
1909 switch (templ
->get_templatetype()) {
1910 case Template::TEMPLATE_LIST
:
1911 if ( (length_restriction
!=NULL
) && !length_restriction
->is_empty() ) {
1912 size_t nof_comp_woaon
= templ
->get_nof_comps_not_anyornone();
1913 if (!templ
->temps_contains_anyornone_symbol() &&
1914 nof_comp_woaon
< length_restriction
->get_minimal().get_size()) {
1915 templ
->error("At least %s elements must be present in the list",
1916 Int2string((Int
)(length_restriction
->get_minimal().get_size())).c_str());
1918 } else if ( !length_restriction
->get_maximal().get_infinity() && (nof_comp_woaon
> length_restriction
->get_maximal().get_size()) ) {
1919 templ
->error("There must not be more than %s elements in the list",
1920 Int2string((Int
)(length_restriction
->get_maximal().get_size())).c_str());
1925 /* Simply break. We don't know how many elements are there.
1926 SUPERSET_MATCH/SUBSET_MATCH is not possible to be an
1927 INDEXED_TEMPLATE_LIST. */
1928 case Template::INDEXED_TEMPLATE_LIST
:
1930 case Template::NAMED_TEMPLATE_LIST
:
1932 case Template::VALUE_RANGE
:
1933 /* Should be canonical before */
1935 case Template::ALL_FROM
:
1936 case Template::VALUE_LIST_ALL_FROM
:
1938 case Template::SUPERSET_MATCH
:
1939 case Template::SUBSET_MATCH
:
1940 if (subtype
!=ST_SETOF
){
1941 templ
->error("'subset' template matching mechanism can be used "
1942 "only with 'set of' types");
1945 for (size_t i
=0;i
<templ
->get_nof_comps();i
++)
1946 chk_this_template_generic(templ
->get_temp_byIndex(i
));
1948 case Template::BSTR_PATTERN
:
1949 chk_this_template_pattern("bitstring", templ
);
1951 case Template::HSTR_PATTERN
:
1952 chk_this_template_pattern("hexstring", templ
);
1954 case Template::OSTR_PATTERN
:
1955 chk_this_template_pattern("octetstring", templ
);
1957 case Template::CSTR_PATTERN
:
1958 chk_this_template_pattern("charstring", templ
);
1960 case Template::USTR_PATTERN
:
1961 chk_this_template_pattern("universal charstring", templ
);
1963 case Template::TEMPLATE_ERROR
:
1966 FATAL_ERROR("SubType::chk_this_template()");
1971 void SubType::chk_this_template_length_restriction(Template
*templ
)
1973 if (!templ
->is_length_restricted()) return;
1974 // if there is a length restriction on the template then check if
1975 // the intersection of the two restrictions is not empty
1976 size_limit_t
tmpl_min_len(size_limit_t(0));
1977 size_limit_t
tmpl_max_len(size_limit_t::INFINITE_SIZE
);
1978 Ttcn::LengthRestriction
*lr
=templ
->get_length_restriction();
1979 lr
->chk(Type::EXPECTED_DYNAMIC_VALUE
);
1980 if (!lr
->get_is_range()) { //Template's lr is single
1981 Value
*tmp_val
=lr
->get_single_value();
1982 if (tmp_val
->get_valuetype()!=Value::V_INT
) return;
1983 Int templ_len
= tmp_val
->get_val_Int()->get_val();
1984 tmpl_min_len
= tmpl_max_len
= size_limit_t((size_t)templ_len
);
1985 } else { //Template's lr is range
1986 Value
*tmp_lower
=lr
->get_lower_value();
1987 if (tmp_lower
->get_valuetype()!=Value::V_INT
) return;
1988 Int templ_lower
= tmp_lower
->get_val_Int()->get_val();
1989 tmpl_min_len
= size_limit_t((size_t)templ_lower
);
1990 Value
*tmp_upper
=lr
->get_upper_value();
1991 if (tmp_upper
&& tmp_upper
->get_valuetype()!=Value::V_INT
) return;
1992 if (tmp_upper
) tmpl_max_len
= size_limit_t((size_t)tmp_upper
->get_val_Int()->get_val());
1995 bool is_err
= false;
1998 if (bitstring_st
!=NULL
) {
1999 BitstringConstraint bc
= *bitstring_st
* BitstringConstraint(tmpl_min_len
,tmpl_max_len
);
2000 if (bc
.is_empty()==TTRUE
) is_err
= true;
2004 if (hexstring_st
!=NULL
) {
2005 HexstringConstraint hc
= *hexstring_st
* HexstringConstraint(tmpl_min_len
,tmpl_max_len
);
2006 if (hc
.is_empty()==TTRUE
) is_err
= true;
2009 case ST_OCTETSTRING
:
2010 if (octetstring_st
!=NULL
) {
2011 OctetstringConstraint oc
= *octetstring_st
* OctetstringConstraint(tmpl_min_len
,tmpl_max_len
);
2012 if (oc
.is_empty()==TTRUE
) is_err
= true;
2016 if (charstring_st
!=NULL
) {
2017 CharstringSubtypeTreeElement
* cc
= new CharstringSubtypeTreeElement(
2018 CharstringSubtypeTreeElement::ET_INTERSECTION
,
2019 new CharstringSubtypeTreeElement(*charstring_st
),
2020 new CharstringSubtypeTreeElement(SizeRangeListConstraint(tmpl_min_len
,tmpl_max_len
))
2022 if (cc
->is_empty()==TTRUE
) is_err
= true;
2026 case ST_UNIVERSAL_CHARSTRING
:
2027 if (universal_charstring_st
!=NULL
) {
2028 UniversalCharstringSubtypeTreeElement
* ucc
= new UniversalCharstringSubtypeTreeElement(
2029 UniversalCharstringSubtypeTreeElement::ET_INTERSECTION
,
2030 new UniversalCharstringSubtypeTreeElement(*universal_charstring_st
),
2031 new UniversalCharstringSubtypeTreeElement(SizeRangeListConstraint(tmpl_min_len
,tmpl_max_len
))
2033 if (ucc
->is_empty()==TTRUE
) is_err
= true;
2039 if (recof_st
!=NULL
) {
2040 RecofConstraint rc
= *recof_st
* RecofConstraint(tmpl_min_len
,tmpl_max_len
);
2041 if (rc
.is_empty()==TTRUE
) is_err
= true;
2048 templ
->error("Template's length restriction %s is outside of the type's subtype constraint %s",
2049 SizeRangeListConstraint(tmpl_min_len
,tmpl_max_len
).to_string().c_str(), to_string().c_str());
2053 void SubType::chk_this_template_pattern(const char *patt_type
, Template
*templ
)
2055 Template::templatetype_t temptype
= templ
->get_templatetype();
2056 if ((temptype
==Template::BSTR_PATTERN
&& subtype
!=ST_BITSTRING
) ||
2057 (temptype
==Template::HSTR_PATTERN
&& subtype
!=ST_HEXSTRING
) ||
2058 (temptype
==Template::OSTR_PATTERN
&& subtype
!=ST_OCTETSTRING
) ||
2059 (temptype
==Template::CSTR_PATTERN
&& subtype
!=ST_CHARSTRING
) ||
2060 (temptype
==Template::USTR_PATTERN
&& subtype
!=ST_UNIVERSAL_CHARSTRING
))
2062 templ
->error("Template is incompatible with subtype");
2065 if ( (length_restriction
!=NULL
) && !length_restriction
->is_empty() ) {
2066 Int patt_min_len
= static_cast<Int
>(templ
->get_min_length_of_pattern());
2067 if (patt_min_len
< (Int
)(length_restriction
->get_minimal().get_size()) &&
2068 !templ
->pattern_contains_anyornone_symbol()) {
2069 templ
->error("At least %s string elements must be present in the %s",
2070 Int2string((Int
)(length_restriction
->get_minimal().get_size())).c_str(), patt_type
);
2071 } else if ( !length_restriction
->get_maximal().get_infinity() && (patt_min_len
> (Int
)(length_restriction
->get_maximal().get_size())) ) {
2072 templ
->error("There must not be more than %s string elements in the %s",
2073 Int2string((Int
)(length_restriction
->get_maximal().get_size())).c_str(), patt_type
);
2078 void SubType::add_ttcn_value(Value
*v
)
2080 if (value_st
==NULL
) value_st
= new ValueListConstraint(v
);
2081 else *value_st
= *value_st
+ ValueListConstraint(v
);
2084 void SubType::add_ttcn_recof(Value
*v
)
2086 if (recof_st
==NULL
) recof_st
= new RecofConstraint(v
);
2087 else *recof_st
= *recof_st
+ RecofConstraint(v
);
2090 bool SubType::add_ttcn_type_list_subtype(SubType
* p_st
)
2094 if (p_st
->integer_st
==NULL
) return false;
2095 if (integer_st
==NULL
) integer_st
= new IntegerRangeListConstraint(*(p_st
->integer_st
));
2096 else *integer_st
= *integer_st
+ *(p_st
->integer_st
);
2099 if (p_st
->float_st
==NULL
) return false;
2100 if (float_st
==NULL
) float_st
= new RealRangeListConstraint(*(p_st
->float_st
));
2101 else *float_st
= *float_st
+ *(p_st
->float_st
);
2104 if (p_st
->boolean_st
==NULL
) return false;
2105 if (boolean_st
==NULL
) boolean_st
= new BooleanListConstraint(*(p_st
->boolean_st
));
2106 else *boolean_st
= *boolean_st
+ *(p_st
->boolean_st
);
2108 case ST_VERDICTTYPE
:
2109 if (p_st
->verdict_st
==NULL
) return false;
2110 if (verdict_st
==NULL
) verdict_st
= new VerdicttypeListConstraint(*(p_st
->verdict_st
));
2111 else *verdict_st
= *verdict_st
+ *(p_st
->verdict_st
);
2114 if (p_st
->bitstring_st
==NULL
) return false;
2115 if (bitstring_st
==NULL
) bitstring_st
= new BitstringConstraint(*(p_st
->bitstring_st
));
2116 else *bitstring_st
= *bitstring_st
+ *(p_st
->bitstring_st
);
2119 if (p_st
->hexstring_st
==NULL
) return false;
2120 if (hexstring_st
==NULL
) hexstring_st
= new HexstringConstraint(*(p_st
->hexstring_st
));
2121 else *hexstring_st
= *hexstring_st
+ *(p_st
->hexstring_st
);
2123 case ST_OCTETSTRING
:
2124 if (p_st
->octetstring_st
==NULL
) return false;
2125 if (octetstring_st
==NULL
) octetstring_st
= new OctetstringConstraint(*(p_st
->octetstring_st
));
2126 else *octetstring_st
= *octetstring_st
+ *(p_st
->octetstring_st
);
2129 if (p_st
->charstring_st
==NULL
) return false;
2130 if (charstring_st
==NULL
) {
2131 charstring_st
= new CharstringSubtypeTreeElement(*(p_st
->charstring_st
));
2133 charstring_st
= new CharstringSubtypeTreeElement(
2134 CharstringSubtypeTreeElement::ET_UNION
,
2136 new CharstringSubtypeTreeElement(*(p_st
->charstring_st
)));
2139 case ST_UNIVERSAL_CHARSTRING
:
2140 if (p_st
->universal_charstring_st
==NULL
) return false;
2141 if (universal_charstring_st
==NULL
) {
2142 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(*(p_st
->universal_charstring_st
));
2144 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(
2145 UniversalCharstringSubtypeTreeElement::ET_UNION
,
2146 universal_charstring_st
,
2147 new UniversalCharstringSubtypeTreeElement(*(p_st
->universal_charstring_st
)));
2158 if (p_st
->value_st
==NULL
) return false;
2159 if (value_st
==NULL
) value_st
= new ValueListConstraint(*(p_st
->value_st
));
2160 else *value_st
= *value_st
+ *(p_st
->value_st
);
2164 if (p_st
->recof_st
==NULL
) return false;
2165 if (recof_st
==NULL
) recof_st
= new RecofConstraint(*(p_st
->recof_st
));
2166 else *recof_st
= *recof_st
+ *(p_st
->recof_st
);
2169 FATAL_ERROR("SubType::add_ttcn_type_list_subtype()");
2175 bool SubType::add_parent_subtype(SubType
* st
)
2177 if (st
==NULL
) FATAL_ERROR("SubType::add_parent_subtype()");
2178 if (my_parents
.has_key(st
)) return true; // it was already successfully added -> ignore
2179 ReferenceChain
refch(my_owner
, "While checking circular type references in subtype definitions");
2180 refch
.add(my_owner
->get_fullname()); // current type
2181 // recursive check for all parents of referenced type
2182 if (!st
->chk_recursion(refch
)) return false;
2183 // if no recursion was detected then add the referenced type as parent
2184 my_parents
.add(st
,NULL
);
2188 bool SubType::chk_recursion(ReferenceChain
& refch
)
2190 if (!refch
.add(my_owner
->get_fullname())) return false; // try the referenced type
2191 for (size_t i
= 0; i
< my_parents
.size(); i
++) {
2193 if (!my_parents
.get_nth_key(i
)->chk_recursion(refch
)) return false;
2199 bool SubType::add_ttcn_single(Value
*val
, size_t restriction_index
)
2201 val
->set_my_scope(my_owner
->get_my_scope());
2202 val
->set_my_governor(my_owner
);
2203 val
->set_fullname(my_owner
->get_fullname()+".<single_restriction_"+Int2string(restriction_index
) + ">");
2204 my_owner
->chk_this_value_ref(val
);
2206 // check if this is type reference, if not then fall through
2207 if (val
->get_valuetype()==Value::V_REFD
) {
2208 Reference
* ref
= val
->get_reference();
2209 Assignment
*ass
= ref
->get_refd_assignment();
2210 if (ass
==NULL
) return false; // defintion was not found, error was reported
2211 if (ass
->get_asstype()==Assignment::A_TYPE
) {
2212 Type
* t
= ass
->get_Type();
2214 if (t
->get_typetype()==Type::T_ERROR
) return false;
2215 // if there were subreferences then get the referenced field's type
2216 if (ref
->get_subrefs()) {
2217 t
= t
->get_field_type(ref
->get_subrefs(), Type::EXPECTED_CONSTANT
);
2218 if ( (t
==NULL
) || (t
->get_typetype()==Type::T_ERROR
) ) return false;
2220 if (t
->get_typetype()==Type::T_ERROR
) return false;
2222 if (!t
->is_identical(my_owner
)) {
2223 val
->error("Reference `%s' must refer to a type which has the same root type as this type",
2224 val
->get_reference()->get_dispname().c_str());
2227 // check subtype of referenced type
2228 SubType
* t_st
= t
->get_sub_type();
2230 val
->error("Type referenced by `%s' does not have a subtype",
2231 val
->get_reference()->get_dispname().c_str());
2235 // check circular subtype reference
2236 if (!add_parent_subtype(t_st
)) return false;
2238 if (t_st
->get_subtypetype()==ST_ERROR
) return false;
2239 if (t_st
->get_subtypetype()!=subtype
) FATAL_ERROR("SubType::add_ttcn_single()");
2240 // add the subtype as union
2241 bool added
= add_ttcn_type_list_subtype(t_st
);
2243 val
->error("Type referenced by `%s' does not have a subtype",
2244 val
->get_reference()->get_dispname().c_str());
2250 my_owner
->chk_this_value(val
, 0, Type::EXPECTED_CONSTANT
,
2251 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
2253 Value
*v
=val
->get_value_refd_last();
2255 switch (v
->get_valuetype()) {
2257 if (subtype
!=ST_INTEGER
) FATAL_ERROR("SubType::add_ttcn_single()");
2258 if (integer_st
==NULL
) integer_st
= new IntegerRangeListConstraint(int_limit_t(*(v
->get_val_Int())));
2259 else *integer_st
= *integer_st
+ IntegerRangeListConstraint(int_limit_t(*(v
->get_val_Int())));
2261 case Value::V_REAL
: {
2262 if (subtype
!=ST_FLOAT
) FATAL_ERROR("SubType::add_ttcn_single()");
2263 ttcn3float r
= v
->get_val_Real();
2265 if (float_st
==NULL
) float_st
= new RealRangeListConstraint(true);
2266 else *float_st
= *float_st
+ RealRangeListConstraint(true);
2268 if (float_st
==NULL
) float_st
= new RealRangeListConstraint(real_limit_t(r
));
2269 else *float_st
= *float_st
+ RealRangeListConstraint(real_limit_t(r
));
2273 if (subtype
!=ST_BOOLEAN
) FATAL_ERROR("SubType::add_ttcn_single()");
2274 if (boolean_st
==NULL
) boolean_st
= new BooleanListConstraint(v
->get_val_bool());
2275 else *boolean_st
= *boolean_st
+ BooleanListConstraint(v
->get_val_bool());
2277 case Value::V_VERDICT
: {
2278 if (subtype
!=ST_VERDICTTYPE
) FATAL_ERROR("SubType::add_ttcn_single()");
2279 VerdicttypeListConstraint::verdicttype_constraint_t vtc
;
2280 switch (v
->get_val_verdict()) {
2281 case Value::Verdict_NONE
: vtc
= VerdicttypeListConstraint::VC_NONE
; break;
2282 case Value::Verdict_PASS
: vtc
= VerdicttypeListConstraint::VC_PASS
; break;
2283 case Value::Verdict_INCONC
: vtc
= VerdicttypeListConstraint::VC_INCONC
; break;
2284 case Value::Verdict_FAIL
: vtc
= VerdicttypeListConstraint::VC_FAIL
; break;
2285 case Value::Verdict_ERROR
: vtc
= VerdicttypeListConstraint::VC_ERROR
; break;
2286 default: FATAL_ERROR("SubType::add_ttcn_single()");
2288 if (verdict_st
==NULL
) verdict_st
= new VerdicttypeListConstraint(vtc
);
2289 else *verdict_st
= *verdict_st
+ VerdicttypeListConstraint(vtc
);
2292 if (v
->has_oid_error()) return false;
2293 if (subtype
!=ST_OBJID
) FATAL_ERROR("SubType::add_ttcn_single()");
2294 if (value_st
==NULL
) value_st
= new ValueListConstraint(v
);
2295 else *value_st
= *value_st
+ ValueListConstraint(v
);
2298 if (subtype
!=ST_BITSTRING
) FATAL_ERROR("SubType::add_ttcn_single()");
2299 if (bitstring_st
==NULL
) bitstring_st
= new BitstringConstraint(v
->get_val_str());
2300 else *bitstring_st
= *bitstring_st
+ BitstringConstraint(v
->get_val_str());
2303 if (subtype
!=ST_HEXSTRING
) FATAL_ERROR("SubType::add_ttcn_single()");
2304 if (hexstring_st
==NULL
) hexstring_st
= new HexstringConstraint(v
->get_val_str());
2305 else *hexstring_st
= *hexstring_st
+ HexstringConstraint(v
->get_val_str());
2308 if (subtype
!=ST_OCTETSTRING
) FATAL_ERROR("SubType::add_ttcn_single()");
2309 if (octetstring_st
==NULL
) octetstring_st
= new OctetstringConstraint(v
->get_val_str());
2310 else *octetstring_st
= *octetstring_st
+ OctetstringConstraint(v
->get_val_str());
2312 case Value::V_CSTR
: {
2313 if (subtype
!=ST_CHARSTRING
) FATAL_ERROR("SubType::add_ttcn_single()");
2314 CharstringSubtypeTreeElement
* cst_elem
= new CharstringSubtypeTreeElement(StringValueConstraint
<string
>(v
->get_val_str()));
2315 if (charstring_st
==NULL
) charstring_st
= cst_elem
;
2316 else charstring_st
= new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_UNION
, charstring_st
, cst_elem
);
2318 case Value::V_USTR
: {
2319 if (subtype
!=ST_UNIVERSAL_CHARSTRING
) FATAL_ERROR("SubType::add_ttcn_single()");
2320 UniversalCharstringSubtypeTreeElement
* ucst_elem
= new UniversalCharstringSubtypeTreeElement(StringValueConstraint
<ustring
>(v
->get_val_ustr()));
2321 if (universal_charstring_st
==NULL
) universal_charstring_st
= ucst_elem
;
2322 else universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_UNION
, universal_charstring_st
, ucst_elem
);
2325 case Value::V_NULL
: // FIXME: should go to ST_NULL
2326 if (subtype
!=ST_ENUM
) FATAL_ERROR("SubType::add_ttcn_single()");
2329 case Value::V_CHOICE
:
2330 if (subtype
!=ST_UNION
) FATAL_ERROR("SubType::add_ttcn_single()");
2334 if (subtype
!=ST_RECORD
) FATAL_ERROR("SubType::add_ttcn_single()");
2338 if (subtype
!=ST_SET
) FATAL_ERROR("SubType::add_ttcn_single()");
2341 case Value::V_FUNCTION
:
2342 if (subtype
!=ST_FUNCTION
) FATAL_ERROR("SubType::add_ttcn_single()");
2345 case Value::V_ALTSTEP
:
2346 if (subtype
!=ST_ALTSTEP
) FATAL_ERROR("SubType::add_ttcn_single()");
2349 case Value::V_TESTCASE
:
2350 if (subtype
!=ST_TESTCASE
) FATAL_ERROR("SubType::add_ttcn_single()");
2353 case Value::V_SEQOF
:
2354 if (subtype
!=ST_RECORDOF
) FATAL_ERROR("SubType::add_ttcn_single()");
2357 case Value::V_SETOF
:
2358 if (subtype
!=ST_SETOF
) FATAL_ERROR("SubType::add_ttcn_single()");
2361 case Value::V_ERROR
:
2369 bool SubType::add_ttcn_range(Value
*min
, bool min_exclusive
,
2370 Value
*max
, bool max_exclusive
, size_t restriction_index
, bool has_other
)
2376 case ST_UNIVERSAL_CHARSTRING
:
2379 my_owner
->error("Range subtyping is not allowed for type `%s'",
2380 my_owner
->get_typename().c_str());
2385 if (min
==NULL
) vmin
=NULL
;
2387 min
->set_my_scope(my_owner
->get_my_scope());
2388 min
->set_fullname(my_owner
->get_fullname()+".<range_restriction_"+Int2string(restriction_index
)+"_lower>");
2389 my_owner
->chk_this_value_ref(min
);
2390 my_owner
->chk_this_value(min
, 0, Type::EXPECTED_CONSTANT
,
2391 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
2392 vmin
=min
->get_value_refd_last();
2394 if (max
==NULL
) vmax
=NULL
;
2396 max
->set_my_scope(my_owner
->get_my_scope());
2397 max
->set_fullname(my_owner
->get_fullname()+".<range_restriction_"+Int2string(restriction_index
)+"_upper>");
2398 my_owner
->chk_this_value_ref(max
);
2399 my_owner
->chk_this_value(max
, 0, Type::EXPECTED_CONSTANT
,
2400 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
2401 vmax
=max
->get_value_refd_last();
2404 if ( (vmin
!=NULL
) && (vmax
!=NULL
) && (vmin
->get_valuetype()!=vmax
->get_valuetype()) ) return false;
2408 if (((vmin
!=NULL
) && (vmin
->get_valuetype()!=Value::V_INT
)) ||
2409 ((vmax
!=NULL
) && (vmax
->get_valuetype()!=Value::V_INT
))) return false;
2410 int_limit_t min_limit
= (vmin
!=NULL
) ? int_limit_t(*(vmin
->get_val_Int())) : int_limit_t::minimum
;
2411 if (min_exclusive
) {
2412 if (min_limit
==int_limit_t::minimum
) {
2413 my_owner
->error("invalid lower boundary, -infinity cannot be excluded from an integer subtype range");
2416 if (min_limit
==int_limit_t::maximum
) {
2417 my_owner
->error("!infinity is not a valid lower boundary");
2420 min_limit
= min_limit
.next();
2423 int_limit_t max_limit
= (vmax
!=NULL
) ? int_limit_t(*(vmax
->get_val_Int())) : int_limit_t::maximum
;
2424 if (max_exclusive
) {
2425 if (max_limit
==int_limit_t::maximum
) {
2426 my_owner
->error("invalid upper boundary, infinity cannot be excluded from an integer subtype range");
2429 if (max_limit
==int_limit_t::minimum
) {
2430 my_owner
->error("!-infinity is not a valid upper boundary");
2433 max_limit
= max_limit
.previous();
2436 if (max_limit
<min_limit
) {
2437 my_owner
->error("lower boundary is bigger than upper boundary in integer subtype range");
2440 if (integer_st
==NULL
) integer_st
= new IntegerRangeListConstraint(min_limit
, max_limit
);
2441 else *integer_st
= *integer_st
+ IntegerRangeListConstraint(min_limit
, max_limit
);
2444 if (((vmin
!=NULL
) && (vmin
->get_valuetype()!=Value::V_REAL
)) ||
2445 ((vmax
!=NULL
) && (vmax
->get_valuetype()!=Value::V_REAL
))) return false;
2446 if ((vmin
!=NULL
) && (vmin
->get_val_Real()!=vmin
->get_val_Real())) {
2447 my_owner
->error("lower boundary cannot be not_a_number in float subtype range");
2450 if ((vmax
!=NULL
) && (vmax
->get_val_Real()!=vmax
->get_val_Real())) {
2451 my_owner
->error("upper boundary cannot be not_a_number in float subtype range");
2454 real_limit_t min_limit
= (vmin
!=NULL
) ? real_limit_t(vmin
->get_val_Real()) : real_limit_t::minimum
;
2455 if (min_exclusive
) {
2456 if (min_limit
==real_limit_t::maximum
) {
2457 my_owner
->error("!infinity is not a valid lower boundary");
2460 min_limit
= min_limit
.next();
2462 real_limit_t max_limit
= (vmax
!=NULL
) ? real_limit_t(vmax
->get_val_Real()) : real_limit_t::maximum
;
2463 if (max_exclusive
) {
2464 if (max_limit
==real_limit_t::minimum
) {
2465 my_owner
->error("!-infinity is not a valid upper boundary");
2468 max_limit
= max_limit
.previous();
2470 if (max_limit
<min_limit
) {
2471 my_owner
->error("lower boundary is bigger than upper boundary in float subtype range");
2474 if (float_st
==NULL
) float_st
= new RealRangeListConstraint(min_limit
, max_limit
);
2475 else *float_st
= *float_st
+ RealRangeListConstraint(min_limit
, max_limit
);
2477 case ST_CHARSTRING
: {
2478 if (((vmin
!=NULL
) && (vmin
->get_valuetype()!=Value::V_CSTR
)) ||
2479 ((vmax
!=NULL
) && (vmax
->get_valuetype()!=Value::V_CSTR
))) return false;
2480 if ((vmin
==NULL
)&&(vmax
==NULL
)) {
2481 my_owner
->error("a range subtype of a charstring cannot be (-infinity..infinity)");
2485 my_owner
->error("lower boundary of a charstring subtype range cannot be -infinity");
2489 my_owner
->error("upper boundary of a charstring subtype range cannot be infinity");
2492 if (vmin
->get_val_str().size()!=1) {
2493 min
->error("lower boundary of charstring subtype range must be a single element string");
2496 if (vmax
->get_val_str().size()!=1) {
2497 max
->error("upper boundary of charstring subtype range must be a single element string");
2500 if (!char_limit_t::is_valid_value(*vmin
->get_val_str().c_str())) {
2501 min
->error("lower boundary of charstring subtype range is an invalid char");
2504 if (!char_limit_t::is_valid_value(*vmax
->get_val_str().c_str())) {
2505 max
->error("upper boundary of charstring subtype range is an invalid char");
2508 char_limit_t
min_limit(*vmin
->get_val_str().c_str()), max_limit(*vmax
->get_val_str().c_str());
2509 if (min_exclusive
) {
2510 if (min_limit
==char_limit_t::maximum
) {
2511 min
->error("exclusive lower boundary is not a legal charstring character");
2514 min_limit
= min_limit
.next();
2516 if (max_exclusive
) {
2517 if (max_limit
==char_limit_t::minimum
) {
2518 max
->error("exclusive upper boundary is not a legal charstring character");
2521 max_limit
= max_limit
.previous();
2523 if (max_limit
<min_limit
) {
2524 my_owner
->error("lower boundary is bigger than upper boundary in charstring subtype range");
2527 if (charstring_st
==NULL
) charstring_st
= new CharstringSubtypeTreeElement(CharRangeListConstraint(min_limit
,max_limit
), false);
2529 if (!has_other
) { // union in char context can be done only with range constraints
2530 charstring_st
->set_char_context(true);
2531 charstring_st
= new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_UNION
,
2533 new CharstringSubtypeTreeElement(CharRangeListConstraint(min_limit
,max_limit
), true));
2534 charstring_st
->set_char_context(false);
2536 // ignore it, error reported elsewhere
2541 case ST_UNIVERSAL_CHARSTRING
: {
2542 if (((vmin
!=NULL
) && (vmin
->get_valuetype()!=Value::V_USTR
)) ||
2543 ((vmax
!=NULL
) && (vmax
->get_valuetype()!=Value::V_USTR
))) return false;
2544 if ((vmin
==NULL
)&&(vmax
==NULL
)) {
2545 my_owner
->error("a range subtype of a universal charstring cannot be (-infinity..infinity)");
2549 my_owner
->error("lower boundary of a universal charstring subtype range cannot be -infinity");
2553 my_owner
->error("upper boundary of a universal charstring subtype range cannot be infinity");
2556 if (vmin
->get_val_ustr().size()!=1) {
2557 min
->error("lower boundary of universal charstring subtype range must be a single element string");
2560 if (vmax
->get_val_ustr().size()!=1) {
2561 max
->error("upper boundary of universal charstring subtype range must be a single element string");
2564 if (!universal_char_limit_t::is_valid_value(*vmin
->get_val_ustr().u_str())) {
2565 min
->error("lower boundary of universal charstring subtype range is an invalid char");
2568 if (!universal_char_limit_t::is_valid_value(*vmax
->get_val_ustr().u_str())) {
2569 max
->error("upper boundary of universal charstring subtype range is an invalid char");
2572 universal_char_limit_t
min_limit(*vmin
->get_val_ustr().u_str()), max_limit(*vmax
->get_val_ustr().u_str());
2573 if (min_exclusive
) {
2574 if (min_limit
==universal_char_limit_t::maximum
) {
2575 min
->error("exclusive lower boundary is not a legal universal charstring character");
2578 min_limit
= min_limit
.next();
2580 if (max_exclusive
) {
2581 if (max_limit
==universal_char_limit_t::minimum
) {
2582 max
->error("exclusive upper boundary is not a legal universal charstring character");
2585 max_limit
= max_limit
.previous();
2587 if (max_limit
<min_limit
) {
2588 my_owner
->error("lower boundary is bigger than upper boundary in universal charstring subtype range");
2592 if (universal_charstring_st
==NULL
) universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharRangeListConstraint(min_limit
,max_limit
), false);
2594 if (!has_other
) { // union in char context can be done only with range constraints
2595 universal_charstring_st
->set_char_context(true);
2596 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_UNION
,
2597 universal_charstring_st
,
2598 new UniversalCharstringSubtypeTreeElement(UniversalCharRangeListConstraint(min_limit
,max_limit
), true));
2599 universal_charstring_st
->set_char_context(false);
2601 // ignore it, error reported elsewhere
2607 FATAL_ERROR("SubType::add_ttcn_range()");
2612 bool SubType::set_ttcn_length(const size_limit_t
& min
, const size_limit_t
& max
)
2615 case ST_BITSTRING
: {
2616 if (bitstring_st
==NULL
) bitstring_st
= new BitstringConstraint(min
,max
);
2617 else *bitstring_st
= *bitstring_st
* BitstringConstraint(min
,max
);
2619 case ST_HEXSTRING
: {
2620 if (hexstring_st
==NULL
) hexstring_st
= new HexstringConstraint(min
,max
);
2621 else *hexstring_st
= *hexstring_st
* HexstringConstraint(min
,max
);
2623 case ST_OCTETSTRING
: {
2624 if (octetstring_st
==NULL
) octetstring_st
= new OctetstringConstraint(min
,max
);
2625 else *octetstring_st
= *octetstring_st
* OctetstringConstraint(min
,max
);
2627 case ST_CHARSTRING
: {
2628 CharstringSubtypeTreeElement
* cst_elem
= new CharstringSubtypeTreeElement(SizeRangeListConstraint(min
,max
));
2629 if (charstring_st
==NULL
) {
2630 charstring_st
= cst_elem
;
2632 charstring_st
= new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_INTERSECTION
, charstring_st
, cst_elem
);
2635 case ST_UNIVERSAL_CHARSTRING
: {
2636 UniversalCharstringSubtypeTreeElement
* ucst_elem
= new UniversalCharstringSubtypeTreeElement(SizeRangeListConstraint(min
,max
));
2637 if (universal_charstring_st
==NULL
) {
2638 universal_charstring_st
= ucst_elem
;
2640 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_INTERSECTION
, universal_charstring_st
, ucst_elem
);
2645 if (recof_st
==NULL
) recof_st
= new RecofConstraint(min
,max
);
2646 else *recof_st
= *recof_st
* RecofConstraint(min
,max
);
2649 my_owner
->error("Length subtyping is not allowed for type `%s'",
2650 my_owner
->get_typename().c_str());
2653 if (length_restriction
==NULL
) length_restriction
= new SizeRangeListConstraint(min
,max
);
2654 else *length_restriction
= *length_restriction
* SizeRangeListConstraint(min
,max
);
2658 void SubType::chk_boundary_valid(Value
* boundary
, Int max_value
, const char* boundary_name
)
2660 const int_val_t
*int_val
= boundary
->get_val_Int();
2661 if (*int_val
> int_val_t(max_value
)) {
2662 boundary
->error("The %s should be less than `%s' instead of `%s'",
2664 int_val_t(max_value
).t_str().c_str(),
2665 int_val
->t_str().c_str());
2666 boundary
->set_valuetype(Value::V_ERROR
);
2670 bool SubType::add_ttcn_length(Ttcn::LengthRestriction
*lr
, size_t restriction_index
)
2673 lr
->append_stringRepr(s
);
2674 Value
*lower
=NULL
,*upper
=NULL
;
2675 lr
->set_my_scope(my_owner
->get_my_scope());
2676 lr
->set_fullname(my_owner
->get_fullname()+".<length_restriction_"+Int2string(restriction_index
)+">");
2677 lr
->chk(Type::EXPECTED_CONSTANT
);
2678 lower
= lr
->get_is_range() ? lr
->get_lower_value() : lr
->get_single_value();
2679 if (!lower
->get_my_scope()) FATAL_ERROR("no scope");
2680 if (lower
->get_valuetype() != Value::V_INT
) return false;
2681 if (lr
->get_is_range()) {
2682 upper
= lr
->get_upper_value();
2683 if (upper
) {//HAS_UPPER
2684 if (upper
->get_valuetype()!=Value::V_INT
) return false;
2685 if (!upper
->get_my_scope()) upper
->set_my_scope(my_owner
->get_my_scope());
2686 chk_boundary_valid(upper
, INT_MAX
, "upper boundary");
2687 if (upper
->get_valuetype()!=Value::V_INT
) return false;
2688 return set_ttcn_length(size_limit_t((size_t)lower
->get_val_Int()->get_val()),
2689 size_limit_t((size_t)upper
->get_val_Int()->get_val()));
2691 chk_boundary_valid(lower
, INT_MAX
, "lower boundary");
2692 if (lower
->get_valuetype()!=Value::V_INT
) return false;
2693 return set_ttcn_length(size_limit_t((size_t)lower
->get_val_Int()->get_val()),
2694 size_limit_t(size_limit_t::INFINITE_SIZE
));
2698 chk_boundary_valid(lower
, INT_MAX
, "length restriction value");
2699 if (lower
->get_valuetype()!=Value::V_INT
) return false;
2700 return set_ttcn_length(size_limit_t((size_t)lower
->get_val_Int()->get_val()),
2701 size_limit_t((size_t)lower
->get_val_Int()->get_val()));
2705 bool SubType::add_ttcn_pattern(Ttcn::PatternString
* pattern
, size_t restriction_index
)
2707 pattern
->set_my_scope(my_owner
->get_my_scope());
2708 pattern
->set_fullname(my_owner
->get_fullname()+".<pattern_restriction_"+Int2string(restriction_index
) + ">");
2710 case ST_CHARSTRING
: {
2711 Error_Context
cntxt(my_owner
, "In character string pattern");
2712 pattern
->chk_refs(Type::EXPECTED_CONSTANT
);
2713 pattern
->join_strings();
2714 if (!pattern
->has_refs()) { // if chk_refs didn't remove all references then ignore
2715 pattern
->chk_pattern();
2716 CharstringSubtypeTreeElement
* cst_elem
= new CharstringSubtypeTreeElement(StringPatternConstraint(pattern
));
2717 if (charstring_st
==NULL
) {
2718 charstring_st
= cst_elem
;
2720 charstring_st
= new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_INTERSECTION
, charstring_st
, cst_elem
);
2724 case ST_UNIVERSAL_CHARSTRING
: {
2725 Error_Context
cntxt(my_owner
, "In universal string pattern");
2726 pattern
->set_pattern_type(Ttcn::PatternString::USTR_PATTERN
);
2727 pattern
->chk_refs(Type::EXPECTED_CONSTANT
);
2728 pattern
->join_strings();
2729 if (!pattern
->has_refs()) { // if chk_refs didn't remove all references then ignore
2730 pattern
->chk_pattern();
2731 UniversalCharstringSubtypeTreeElement
* ucst_elem
= new UniversalCharstringSubtypeTreeElement(StringPatternConstraint(pattern
));
2732 if (universal_charstring_st
==NULL
) {
2733 universal_charstring_st
= ucst_elem
;
2735 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_INTERSECTION
, universal_charstring_st
, ucst_elem
);
2740 my_owner
->error("Pattern subtyping of type `%s' is not allowed", my_owner
->get_typename().c_str());
2746 void SubType::print_full_warning() const
2748 my_owner
->warning("The subtype of type `%s' is a full set, "
2749 "it does not constrain the root type.", my_owner
->get_typename().c_str());
2754 if ((checked
!=STC_NO
) || (subtype
==ST_ERROR
)) FATAL_ERROR("SubType::chk()");
2755 checked
= STC_CHECKING
;
2757 // check for circular subtype reference
2758 if (parent_subtype
&& !add_parent_subtype(parent_subtype
)) {
2764 if (parsed
) { // has TTCN-3 subtype constraint
2765 size_t added_count
= 0;
2766 bool has_single
= false, has_range
= false,
2767 has_length
= false, has_pattern
= false;
2768 for (size_t i
= 0; i
< parsed
->size(); i
++) {
2770 SubTypeParse
*parse
= (*parsed
)[i
];
2771 switch (parse
->get_selection()) {
2772 case SubTypeParse::STP_SINGLE
:
2774 added
= add_ttcn_single(parse
->Single(),i
);
2776 case SubTypeParse::STP_RANGE
:
2778 added
= add_ttcn_range(parse
->Min(), parse
->MinExclusive(),
2779 parse
->Max(), parse
->MaxExclusive(), i
,
2780 has_single
|| has_length
|| has_pattern
);
2782 case SubTypeParse::STP_LENGTH
:
2784 added
= add_ttcn_length(parse
->Length(),i
);
2786 case SubTypeParse::STP_PATTERN
:
2788 added
= add_ttcn_pattern(parse
->Pattern(),i
);
2791 FATAL_ERROR("SubType::chk(): invalid SubTypeParse selection");
2793 if (added
) added_count
++;
2797 case ST_UNIVERSAL_CHARSTRING
:
2798 if (has_single
&& has_range
) {
2800 "Mixing of value list and range subtyping is not allowed for type `%s'",
2801 my_owner
->get_typename().c_str());
2808 // in other cases mixing of different restrictions (which are legal for
2809 // this type) is properly regulated by the TTCN-3 BNF itself
2812 if (added_count
<parsed
->size()) {
2817 if (subtype
==ST_ERROR
) { checked
= STC_YES
; return; }
2819 if (parent_subtype
) {
2820 if (is_subset(parent_subtype
->get_root())==TFALSE
) {
2821 my_owner
->error("The subtype restriction is not a subset of the restriction on the parent type. "
2822 "Subtype %s is not subset of subtype %s", to_string().c_str(), parent_subtype
->get_root()->to_string().c_str());
2827 intersection(parent_subtype
->get_root());
2829 } else if (asn_constraints
) { // has ASN.1 subtype constraint
2830 SubtypeConstraint
* asn_parent_subtype
= NULL
;
2831 if (parent_subtype
) {
2832 // the type constraint of the ASN.1 type is already in the parent_subtype,
2833 // don't add it multiple times
2834 asn_parent_subtype
= parent_subtype
->get_root();
2836 asn_parent_subtype
= get_asn_type_constraint(my_owner
);
2838 asn_constraints
->chk(asn_parent_subtype
);
2839 root
= asn_constraints
->get_subtype();
2840 extendable
= asn_constraints
->is_extendable();
2841 extension
= asn_constraints
->get_extension();
2842 // the TTCN-3 subtype will be the union of the root and extension parts
2843 // the ETSI ES 201 873-7 V4.1.2 (2009-07) document says to "ignore any extension markers"
2844 // but titan now works this way :)
2845 if (root
) copy(root
);
2846 if (extension
) union_(extension
);
2847 } else { // no constraints on this type -> this is an alias type, just copy the subtype from the other
2848 if (parent_subtype
) {
2849 root
= parent_subtype
->root
;
2850 extendable
= parent_subtype
->extendable
;
2851 extension
= parent_subtype
->extension
;
2852 copy(parent_subtype
);
2854 SubtypeConstraint
* asn_parent_subtype
= get_asn_type_constraint(my_owner
);
2855 if (asn_parent_subtype
) copy(asn_parent_subtype
);
2859 // check if subtype is valid: it must not be an empty set (is_empty==TTRUE)
2860 // issue warning if subtype is given but is full set (is_full==TTRUE)
2861 // ignore cases of TUNKNOWN when compiler can't figure out if the aggregate
2862 // set is empty or full
2865 if (integer_st
!=NULL
) {
2866 if (integer_st
->is_empty()==TTRUE
) goto empty_error
;
2867 if (integer_st
->is_full()==TTRUE
) {
2868 print_full_warning();
2875 if (float_st
!=NULL
) {
2876 if (float_st
->is_empty()==TTRUE
) goto empty_error
;
2877 if (float_st
->is_full()==TTRUE
) {
2878 print_full_warning();
2885 if (boolean_st
!=NULL
) {
2886 if (boolean_st
->is_empty()==TTRUE
) goto empty_error
;
2887 if (boolean_st
->is_full()==TTRUE
) {
2888 print_full_warning();
2894 case ST_VERDICTTYPE
:
2895 if (verdict_st
!=NULL
) {
2896 if (verdict_st
->is_empty()==TTRUE
) goto empty_error
;
2897 if (verdict_st
->is_full()==TTRUE
) {
2898 print_full_warning();
2905 if (bitstring_st
!=NULL
) {
2906 if (bitstring_st
->is_empty()==TTRUE
) goto empty_error
;
2907 if (bitstring_st
->is_full()==TTRUE
) {
2908 print_full_warning();
2909 delete bitstring_st
;
2910 bitstring_st
= NULL
;
2915 if (hexstring_st
!=NULL
) {
2916 if (hexstring_st
->is_empty()==TTRUE
) goto empty_error
;
2917 if (hexstring_st
->is_full()==TTRUE
) {
2918 print_full_warning();
2919 delete hexstring_st
;
2920 hexstring_st
= NULL
;
2924 case ST_OCTETSTRING
:
2925 if (octetstring_st
!=NULL
) {
2926 if (octetstring_st
->is_empty()==TTRUE
) goto empty_error
;
2927 if (octetstring_st
->is_full()==TTRUE
) {
2928 print_full_warning();
2929 delete octetstring_st
;
2930 octetstring_st
= NULL
;
2935 if (charstring_st
!=NULL
) {
2936 if (charstring_st
->is_empty()==TTRUE
) goto empty_error
;
2937 if (charstring_st
->is_full()==TTRUE
) {
2938 print_full_warning();
2939 delete charstring_st
;
2940 charstring_st
= NULL
;
2944 case ST_UNIVERSAL_CHARSTRING
:
2945 if (universal_charstring_st
!=NULL
) {
2946 if (universal_charstring_st
->is_empty()==TTRUE
) goto empty_error
;
2947 if (universal_charstring_st
->is_full()==TTRUE
) {
2948 print_full_warning();
2949 delete universal_charstring_st
;
2950 universal_charstring_st
= NULL
;
2962 if (value_st
!=NULL
) {
2963 if (value_st
->is_empty()==TTRUE
) goto empty_error
;
2964 if (value_st
->is_full()==TTRUE
) {
2965 print_full_warning();
2973 if (recof_st
!=NULL
) {
2974 if (recof_st
->is_empty()==TTRUE
) goto empty_error
;
2975 if (recof_st
->is_full()==TTRUE
) {
2976 print_full_warning();
2983 FATAL_ERROR("SubType::chk()");
2985 if ((length_restriction
!=NULL
) && (length_restriction
->is_full()==TTRUE
)) {
2986 delete length_restriction
;
2987 length_restriction
= NULL
;
2993 my_owner
->error("The subtype is an empty set");
2999 void SubType::dump(unsigned level
) const
3001 string str
= to_string();
3002 if (str
.size()>0) DEBUG(level
, "restriction(s): %s", str
.c_str());
3005 Int
SubType::get_length_restriction() const
3007 if (checked
!=STC_YES
) FATAL_ERROR("SubType::get_length_restriction()");
3008 if (parsed
==NULL
) return -1; // only own length restriction counts
3009 if (length_restriction
==NULL
) return -1;
3010 if (length_restriction
->is_empty()) return -1;
3011 return ( (length_restriction
->get_minimal()==length_restriction
->get_maximal()) ?
3012 (Int
)(length_restriction
->get_minimal().get_size()) :
3016 bool SubType::zero_length_allowed() const
3018 if (checked
!=STC_YES
) FATAL_ERROR("SubType::zero_length_allowed()");
3019 if (parsed
==NULL
) return true; // only own length restriction counts
3020 if (length_restriction
==NULL
) return true;
3021 return length_restriction
->is_element(size_limit_t(0));
3024 string
SubType::to_string() const
3027 string
ret_val(root
->to_string());
3028 if (extendable
) ret_val
+= ", ...";
3031 ret_val
+= extension
->to_string();
3035 return SubtypeConstraint::to_string();
3038 ////////////////////////////////////////////////////////////////////////////////
3040 void SubType::generate_code(output_struct
&)
3042 if (checked
!=STC_YES
) FATAL_ERROR("SubType::generate_code()");
3045 void SubType::generate_json_schema(JSON_Tokenizer
& json
,
3046 bool allow_special_float
/* = true */)
3048 bool has_value_list
= false;
3049 size_t nof_ranges
= 0;
3050 for (size_t i
= 0; i
< parsed
->size(); ++i
) {
3051 SubTypeParse
*parse
= (*parsed
)[i
];
3052 switch (parse
->get_selection()) {
3053 case SubTypeParse::STP_SINGLE
:
3054 // single values will be added later, all at once
3055 has_value_list
= true;
3057 case SubTypeParse::STP_RANGE
:
3060 case SubTypeParse::STP_LENGTH
: {
3061 Ttcn::LengthRestriction
* len_res
= parse
->Length();
3062 Value
* min_val
= len_res
->get_is_range() ? len_res
->get_lower_value() :
3063 len_res
->get_single_value();
3064 Value
* max_val
= len_res
->get_is_range() ? len_res
->get_upper_value() :
3065 len_res
->get_single_value();
3066 const char* json_min
= NULL
;
3067 const char* json_max
= NULL
;
3071 // use minItems and maxItems for record of/set of
3072 json_min
= "minItems";
3073 json_max
= "maxItems";
3077 case ST_OCTETSTRING
:
3079 case ST_UNIVERSAL_CHARSTRING
:
3080 // use minLength and maxLength for string types
3081 json_min
= "minLength";
3082 json_max
= "maxLength";
3085 FATAL_ERROR("SubType::generate_json_schema - length %d", subtype
);
3087 json
.put_next_token(JSON_TOKEN_NAME
, json_min
);
3088 min_val
->generate_json_value(json
);
3089 if (max_val
!= NULL
) {
3090 json
.put_next_token(JSON_TOKEN_NAME
, json_max
);
3091 max_val
->generate_json_value(json
);
3094 case SubTypeParse::STP_PATTERN
: {
3095 json
.put_next_token(JSON_TOKEN_NAME
, "pattern");
3096 char* json_pattern
= parse
->Pattern()->convert_to_json();
3097 json
.put_next_token(JSON_TOKEN_STRING
, json_pattern
);
3105 bool need_anyOf
= (subtype
== ST_INTEGER
|| subtype
== ST_FLOAT
) &&
3106 (nof_ranges
+ (has_value_list
? 1 : 0) > 1);
3108 // there are multiple value range/value list restrictions,
3109 // they need to be grouped in an 'anyOf' structure
3110 json
.put_next_token(JSON_TOKEN_NAME
, "anyOf");
3111 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
3112 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
3114 if (has_value_list
) {
3115 // generate the value list into an enum
3116 json
.put_next_token(JSON_TOKEN_NAME
, "enum");
3117 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
3118 generate_json_schema_value_list(json
, allow_special_float
, false);
3119 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
3120 if (my_owner
->has_as_value_union()) {
3121 // the original value list cannot always be recreated from the generated
3122 // JSON value list in case of "as value" unions (because there are no field
3124 // the list needs to be regenerated with field names (as if it was a regular
3125 // union) under a new keyword (valueList)
3126 json
.put_next_token(JSON_TOKEN_NAME
, "valueList");
3127 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
3128 generate_json_schema_value_list(json
, allow_special_float
, true);
3129 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
3132 if (need_anyOf
&& has_value_list
) {
3133 // end of the value list and beginning of the first value range
3134 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
3135 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
3137 if (nof_ranges
> 0) {
3141 generate_json_schema_number_ranges(json
);
3144 case ST_UNIVERSAL_CHARSTRING
: {
3145 // merge all string range restrictions into one JSON schema pattern
3146 char* pattern_str
= mcopystrn("\"^[", 3);
3147 pattern_str
= generate_json_schema_string_ranges(pattern_str
);
3148 pattern_str
= mputstrn(pattern_str
, "]*$\"", 4);
3149 json
.put_next_token(JSON_TOKEN_NAME
, "pattern");
3150 json
.put_next_token(JSON_TOKEN_STRING
, pattern_str
);
3154 FATAL_ERROR("SubType::generate_json_schema - range %d", subtype
);
3158 // end of the 'anyOf' structure
3159 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
3160 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
3164 void SubType::generate_json_schema_value_list(JSON_Tokenizer
& json
,
3165 bool allow_special_float
,
3166 bool union_value_list
)
3168 for (size_t i
= 0; i
< parsed
->size(); ++i
) {
3169 SubTypeParse
*parse
= (*parsed
)[i
];
3170 if (parse
->get_selection() == SubTypeParse::STP_SINGLE
) {
3171 if (parse
->Single()->get_valuetype() == Value::V_REFD
) {
3172 Common::Assignment
* ass
= parse
->Single()->get_reference()->get_refd_assignment();
3173 if (ass
->get_asstype() == Common::Assignment::A_TYPE
) {
3174 // it's a reference to another subtype, insert its value list here
3175 ass
->get_Type()->get_sub_type()->generate_json_schema_value_list(json
,
3176 allow_special_float
, union_value_list
);
3180 Ttcn::JsonOmitCombination
omit_combo(parse
->Single());
3182 parse
->Single()->generate_json_value(json
, allow_special_float
,
3183 union_value_list
, &omit_combo
);
3184 } // only generate the first combination for the unions' "valueList" keyword
3185 while (!union_value_list
&& omit_combo
.next());
3191 bool SubType::generate_json_schema_number_ranges(JSON_Tokenizer
& json
, bool first
/* = true */)
3193 for (size_t i
= 0; i
< parsed
->size(); ++i
) {
3194 SubTypeParse
*parse
= (*parsed
)[i
];
3195 if (parse
->get_selection() == SubTypeParse::STP_SINGLE
) {
3196 if (parse
->Single()->get_valuetype() == Value::V_REFD
) {
3197 Common::Assignment
* ass
= parse
->Single()->get_reference()->get_refd_assignment();
3198 if (ass
->get_asstype() == Common::Assignment::A_TYPE
) {
3199 // it's a reference to another subtype, insert its value ranges here
3200 first
= ass
->get_Type()->get_sub_type()->generate_json_schema_number_ranges(json
, first
);
3204 else if (parse
->get_selection() == SubTypeParse::STP_RANGE
) {
3206 // the ranges are in an 'anyOf' structure, they need to be placed in an object
3207 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
3208 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
3213 // add the minimum and/or maximum values as numbers
3214 if (parse
->Min() != NULL
) {
3215 json
.put_next_token(JSON_TOKEN_NAME
, "minimum");
3216 parse
->Min()->generate_json_value(json
);
3217 json
.put_next_token(JSON_TOKEN_NAME
, "exclusiveMinimum");
3218 json
.put_next_token(parse
->MinExclusive() ? JSON_TOKEN_LITERAL_TRUE
: JSON_TOKEN_LITERAL_FALSE
);
3220 if (parse
->Max() != NULL
) {
3221 json
.put_next_token(JSON_TOKEN_NAME
, "maximum");
3222 parse
->Max()->generate_json_value(json
);
3223 json
.put_next_token(JSON_TOKEN_NAME
, "exclusiveMaximum");
3224 json
.put_next_token(parse
->MaxExclusive() ? JSON_TOKEN_LITERAL_TRUE
: JSON_TOKEN_LITERAL_FALSE
);
3231 char* SubType::generate_json_schema_string_ranges(char* pattern_str
)
3233 for (size_t i
= 0; i
< parsed
->size(); ++i
) {
3234 SubTypeParse
*parse
= (*parsed
)[i
];
3235 if (parse
->get_selection() == SubTypeParse::STP_SINGLE
) {
3236 if (parse
->Single()->get_valuetype() == Value::V_REFD
) {
3237 Common::Assignment
* ass
= parse
->Single()->get_reference()->get_refd_assignment();
3238 if (ass
->get_asstype() == Common::Assignment::A_TYPE
) {
3239 // it's a reference to another subtype, insert its string ranges here
3240 pattern_str
= ass
->get_Type()->get_sub_type()->generate_json_schema_string_ranges(pattern_str
);
3244 else if (parse
->get_selection() == SubTypeParse::STP_RANGE
) {
3245 // insert the string range into the pattern string
3246 string lower_str
= (subtype
== ST_CHARSTRING
) ? parse
->Min()->get_val_str() :
3247 ustring_to_uft8(parse
->Min()->get_val_ustr());
3248 string upper_str
= (subtype
== ST_CHARSTRING
) ? parse
->Max()->get_val_str() :
3249 ustring_to_uft8(parse
->Max()->get_val_ustr());
3250 pattern_str
= mputprintf(pattern_str
, "%s-%s", lower_str
.c_str(), upper_str
.c_str());
3256 void SubType::generate_json_schema_float(JSON_Tokenizer
& json
)
3258 bool has_nan
= float_st
->is_element(make_ttcn3float(REAL_NAN
));
3259 bool has_pos_inf
= float_st
->is_element(make_ttcn3float(REAL_INFINITY
));
3260 bool has_neg_inf
= float_st
->is_element(make_ttcn3float(-REAL_INFINITY
));
3261 bool has_special
= has_nan
|| has_pos_inf
|| has_neg_inf
;
3262 bool has_number
= false;
3263 for (size_t i
= 0; i
< parsed
->size() && !has_number
; ++i
) {
3264 // go through the restrictions and check if at least one number is allowed
3265 SubTypeParse
*parse
= (*parsed
)[i
];
3266 switch (parse
->get_selection()) {
3267 case SubTypeParse::STP_SINGLE
: {
3268 Real r
= parse
->Single()->get_val_Real();
3269 if (r
== r
&& r
!= REAL_INFINITY
&& r
!= -REAL_INFINITY
) {
3270 // a single value other than NaN, INF and -INF is a number
3274 case SubTypeParse::STP_RANGE
: {
3275 if (parse
->Min() != NULL
) {
3276 if (parse
->Min()->get_val_Real() != REAL_INFINITY
) {
3277 // a minimum value other than INF means a number is allowed
3281 if (parse
->Max() != NULL
) {
3282 // a maximum value other than -INF means a number is allowed
3283 if (parse
->Max()->get_val_Real() != -REAL_INFINITY
) {
3292 if (has_number
&& has_special
) {
3293 json
.put_next_token(JSON_TOKEN_NAME
, "anyOf");
3294 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
3295 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
3298 json
.put_next_token(JSON_TOKEN_NAME
, "type");
3299 json
.put_next_token(JSON_TOKEN_STRING
, "\"number\"");
3300 // generate the restrictions' schema elements here
3301 // (the 2nd parameter makes sure that NaN, INF and -INF are ignored)
3302 generate_json_schema(json
, false);
3304 if (has_number
&& has_special
) {
3305 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
3306 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
3309 json
.put_next_token(JSON_TOKEN_NAME
, "enum");
3310 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
3312 json
.put_next_token(JSON_TOKEN_STRING
, "\"not_a_number\"");
3315 json
.put_next_token(JSON_TOKEN_STRING
, "\"infinity\"");
3318 json
.put_next_token(JSON_TOKEN_STRING
, "\"-infinity\"");
3320 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
3322 if (has_number
&& has_special
) {
3323 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
3324 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
3328 } // namespace Common