1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
19 * Szabo, Janos Zoltan – initial implementation
22 * Zalanyi, Balazs Andor
24 ******************************************************************************/
26 #include "../common/dbgnew.hh"
27 #include "Identifier.hh"
31 #include "CompilerError.hh"
32 #include "Valuestuff.hh"
33 #include "ttcn3/TtcnTemplate.hh"
34 #include "ttcn3/Templatestuff.hh"
35 #include "ttcn3/PatternString.hh"
36 #include "Constraint.hh"
37 #include "../common/JSON_Tokenizer.hh"
38 #include "ttcn3/Ttcn2Json.hh"
44 /**************************
46 **************************/
48 SubTypeParse::SubTypeParse(Value
*p_single
)
49 : selection(STP_SINGLE
)
51 if (!p_single
) FATAL_ERROR("SubTypeParse::SubTypeParse()");
55 SubTypeParse::SubTypeParse(Value
*p_min
, bool p_min_exclusive
, Value
*p_max
, bool p_max_exclusive
)
56 : selection(STP_RANGE
)
59 range
.min_exclusive
= p_min_exclusive
;
61 range
.max_exclusive
= p_max_exclusive
;
64 SubTypeParse::SubTypeParse(Ttcn::LengthRestriction
*p_length
)
65 : selection(STP_LENGTH
)
67 if (!p_length
) FATAL_ERROR("SubTypeParse::SubTypeParse()");
71 SubTypeParse::SubTypeParse(Ttcn::PatternString
*p_pattern
)
72 : selection(STP_PATTERN
)
74 if (!p_pattern
) FATAL_ERROR("SubTypeParse::SubTypeParse()");
78 SubTypeParse::~SubTypeParse()
95 FATAL_ERROR("SubTypeParse::~SubTypeParse()");
99 Value
*SubTypeParse::Single() const
101 if (selection
!= STP_SINGLE
) FATAL_ERROR("SubTypeParse::Single()");
105 Value
*SubTypeParse::Min() const
107 if (selection
!= STP_RANGE
) FATAL_ERROR("SubTypeParse::Min()");
111 bool SubTypeParse::MinExclusive() const
113 if (selection
!= STP_RANGE
) FATAL_ERROR("SubTypeParse::MinExclusive()");
114 return range
.min_exclusive
;
117 Value
*SubTypeParse::Max() const
119 if (selection
!= STP_RANGE
) FATAL_ERROR("SubTypeParse::Max()");
123 bool SubTypeParse::MaxExclusive() const
125 if (selection
!= STP_RANGE
) FATAL_ERROR("SubTypeParse::MaxExclusive()");
126 return range
.max_exclusive
;
129 Ttcn::LengthRestriction
*SubTypeParse::Length() const
131 if (selection
!= STP_LENGTH
) FATAL_ERROR("SubTypeParse::Length()");
135 Ttcn::PatternString
*SubTypeParse::Pattern() const
137 if (selection
!= STP_PATTERN
) FATAL_ERROR("SubTypeParse::Pattern()");
141 /********************
142 class SubtypeConstraint
143 ********************/
145 SubtypeConstraint::SubtypeConstraint(subtype_t st
)
148 length_restriction
= NULL
;
169 octetstring_st
= NULL
;
172 charstring_st
= NULL
;
174 case ST_UNIVERSAL_CHARSTRING
:
175 universal_charstring_st
= NULL
;
192 FATAL_ERROR("SubtypeConstraint::SubtypeConstraint()");
196 void SubtypeConstraint::copy(const SubtypeConstraint
* other
)
198 if ((other
==NULL
) || (other
->subtype
!=subtype
)) FATAL_ERROR("SubtypeConstraint::copy()");
202 integer_st
= other
->integer_st
? new IntegerRangeListConstraint(*(other
->integer_st
)) : NULL
;
206 float_st
= other
->float_st
? new RealRangeListConstraint(*(other
->float_st
)) : NULL
;
210 boolean_st
= other
->boolean_st
? new BooleanListConstraint(*(other
->boolean_st
)) : NULL
;
214 verdict_st
= other
->verdict_st
? new VerdicttypeListConstraint(*(other
->verdict_st
)) : NULL
;
218 bitstring_st
= other
->bitstring_st
? new BitstringConstraint(*(other
->bitstring_st
)) : NULL
;
222 hexstring_st
= other
->hexstring_st
? new HexstringConstraint(*(other
->hexstring_st
)) : NULL
;
225 delete octetstring_st
;
226 octetstring_st
= other
->octetstring_st
? new OctetstringConstraint(*(other
->octetstring_st
)) : NULL
;
229 delete charstring_st
;
230 charstring_st
= other
->charstring_st
? new CharstringSubtypeTreeElement(*(other
->charstring_st
)) : NULL
;
232 case ST_UNIVERSAL_CHARSTRING
:
233 delete universal_charstring_st
;
234 universal_charstring_st
= other
->universal_charstring_st
? new UniversalCharstringSubtypeTreeElement(*(other
->universal_charstring_st
)) : NULL
;
245 value_st
= other
->value_st
? new ValueListConstraint(*(other
->value_st
)) : NULL
;
250 recof_st
= other
->recof_st
? new RecofConstraint(*(other
->recof_st
)) : NULL
;
253 FATAL_ERROR("SubtypeConstraint::copy()");
255 delete length_restriction
;
256 length_restriction
= other
->length_restriction
? new SizeRangeListConstraint(*(other
->length_restriction
)) : NULL
;
259 // used by get_asn_type_constraint() to store singleton objects and delete them on program exit
260 struct AsnTypeConstraintSingleton
262 SubtypeConstraint
*printablestring_stc
, *numericstring_stc
, *bmpstring_stc
;
263 AsnTypeConstraintSingleton():
264 printablestring_stc(NULL
), numericstring_stc(NULL
), bmpstring_stc(NULL
) {}
265 ~AsnTypeConstraintSingleton();
268 AsnTypeConstraintSingleton::~AsnTypeConstraintSingleton()
270 delete printablestring_stc
;
271 delete numericstring_stc
;
272 delete bmpstring_stc
;
275 SubtypeConstraint
* SubtypeConstraint::get_asn_type_constraint(Type
* type
)
277 static AsnTypeConstraintSingleton asn_tcs
;
278 static const char_limit_t
zero('0'), nine('9'),
279 bigA('A'), bigZ('Z'), smalla('a'), smallz('z');
280 static const universal_char_limit_t
uni_zero(0);
281 static const universal_char_limit_t
uni_ffff((1<<16)-1);
282 static const CharRangeListConstraint
numeric_string_char_range(
283 CharRangeListConstraint(zero
, nine
) +
284 CharRangeListConstraint(char_limit_t(' ')));
285 static const CharRangeListConstraint
printable_string_char_range(
286 CharRangeListConstraint(bigA
, bigZ
) +
287 CharRangeListConstraint(smalla
, smallz
) +
288 CharRangeListConstraint(zero
, nine
) +
289 CharRangeListConstraint(char_limit_t(' ')) +
290 CharRangeListConstraint(char_limit_t('\'')) +
291 CharRangeListConstraint(char_limit_t('(')) +
292 CharRangeListConstraint(char_limit_t(')')) +
293 CharRangeListConstraint(char_limit_t('+')) +
294 CharRangeListConstraint(char_limit_t(',')) +
295 CharRangeListConstraint(char_limit_t('-')) +
296 CharRangeListConstraint(char_limit_t('.')) +
297 CharRangeListConstraint(char_limit_t('/')) +
298 CharRangeListConstraint(char_limit_t(':')) +
299 CharRangeListConstraint(char_limit_t('=')) +
300 CharRangeListConstraint(char_limit_t('?')));
301 static const UniversalCharRangeListConstraint
bmp_string_char_range(
302 UniversalCharRangeListConstraint(uni_zero
, uni_ffff
));
304 switch (type
->get_typetype()) {
305 case Type::T_TELETEXSTRING
:
306 // TODO: based on ITU-T Recommendation T.61
308 case Type::T_VIDEOTEXSTRING
:
309 // TODO: based on ITU-T Recommendation T.100 and T.101
311 case Type::T_NUMERICSTRING
:
312 if (asn_tcs
.numericstring_stc
==NULL
) {
313 asn_tcs
.numericstring_stc
= new SubtypeConstraint(ST_CHARSTRING
);
314 asn_tcs
.numericstring_stc
->charstring_st
= new CharstringSubtypeTreeElement(numeric_string_char_range
, false);
316 return asn_tcs
.numericstring_stc
;
317 case Type::T_PRINTABLESTRING
:
318 if (asn_tcs
.printablestring_stc
==NULL
) {
319 asn_tcs
.printablestring_stc
= new SubtypeConstraint(ST_CHARSTRING
);
320 asn_tcs
.printablestring_stc
->charstring_st
= new CharstringSubtypeTreeElement(printable_string_char_range
, false);
322 return asn_tcs
.printablestring_stc
;
323 case Type::T_BMPSTRING
:
324 if (asn_tcs
.bmpstring_stc
==NULL
) {
325 asn_tcs
.bmpstring_stc
= new SubtypeConstraint(ST_UNIVERSAL_CHARSTRING
);
326 asn_tcs
.bmpstring_stc
->universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(bmp_string_char_range
, false);
328 return asn_tcs
.bmpstring_stc
;
334 SubtypeConstraint
* SubtypeConstraint::create_from_asn_value(Type
* type
, Value
* value
)
336 Value
* v
= value
->get_value_refd_last();
337 subtype_t st_t
= type
->get_subtype_type();
338 if ( (st_t
==ST_ERROR
) || (v
->get_valuetype()==Value::V_ERROR
) ) return NULL
;
339 SubtypeConstraint
* stc
= new SubtypeConstraint(st_t
);
340 switch (v
->get_valuetype()) {
342 if (st_t
!=ST_INTEGER
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
343 stc
->integer_st
= new IntegerRangeListConstraint(int_limit_t(*(v
->get_val_Int())));
345 case Value::V_REAL
: {
346 if (st_t
!=ST_FLOAT
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
347 ttcn3float r
= v
->get_val_Real();
348 if (r
!=r
) stc
->float_st
= new RealRangeListConstraint(true);
349 else stc
->float_st
= new RealRangeListConstraint(real_limit_t(r
));
352 if (st_t
!=ST_BOOLEAN
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
353 stc
->boolean_st
= new BooleanListConstraint(v
->get_val_bool());
357 if (v
->has_oid_error()) goto invalid_value
;
358 if (st_t
!=ST_OBJID
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
359 stc
->value_st
= new ValueListConstraint(v
);
362 if (st_t
!=ST_BITSTRING
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
363 stc
->bitstring_st
= new BitstringConstraint(v
->get_val_str());
366 if (st_t
!=ST_HEXSTRING
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
367 stc
->hexstring_st
= new HexstringConstraint(v
->get_val_str());
370 if (st_t
!=ST_OCTETSTRING
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
371 stc
->octetstring_st
= new OctetstringConstraint(v
->get_val_str());
374 if (st_t
!=ST_CHARSTRING
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
375 stc
->charstring_st
= new CharstringSubtypeTreeElement(StringValueConstraint
<string
>(v
->get_val_str()));
377 case Value::V_ISO2022STR
:
378 if (st_t
!=ST_CHARSTRING
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
379 stc
->charstring_st
= new CharstringSubtypeTreeElement(StringValueConstraint
<string
>(v
->get_val_iso2022str()));
381 case Value::V_CHARSYMS
:
383 if (st_t
!=ST_UNIVERSAL_CHARSTRING
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
384 stc
->universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(StringValueConstraint
<ustring
>(v
->get_val_ustr()));
387 case Value::V_NULL
: // FIXME: should go to ST_NULL
388 if (st_t
!=ST_ENUM
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
389 stc
->value_st
= new ValueListConstraint(v
);
391 case Value::V_CHOICE
:
392 case Value::V_OPENTYPE
: // FIXME?
393 if (st_t
!=ST_UNION
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
394 stc
->value_st
= new ValueListConstraint(v
);
397 if (st_t
!=ST_RECORD
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
398 stc
->value_st
= new ValueListConstraint(v
);
401 if (st_t
!=ST_SET
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
402 stc
->value_st
= new ValueListConstraint(v
);
405 if (st_t
!=ST_RECORDOF
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
406 stc
->recof_st
= new RecofConstraint(v
);
409 if (st_t
!=ST_SETOF
) FATAL_ERROR("SubtypeConstraint::create_from_asn_value()");
410 stc
->recof_st
= new RecofConstraint(v
);
421 SubtypeConstraint
* SubtypeConstraint::create_from_asn_charvalues(Type
* type
, Value
* value
)
423 Value
* v
= value
->get_value_refd_last();
424 subtype_t st_t
= type
->get_subtype_type();
425 if ( (st_t
==ST_ERROR
) || (v
->get_valuetype()==Value::V_ERROR
) ) return NULL
;
426 SubtypeConstraint
* stc
= new SubtypeConstraint(st_t
);
427 switch (v
->get_valuetype()) {
429 case Value::V_ISO2022STR
: {
430 if (st_t
!=ST_CHARSTRING
) FATAL_ERROR("SubtypeConstraint::create_from_asn_charvalues()");
431 CharRangeListConstraint charvalues
;
432 string val_str
= (v
->get_valuetype()==Value::V_CSTR
) ? v
->get_val_str() : v
->get_val_iso2022str();
433 for (size_t i
=0; i
<val_str
.size(); i
++) {
434 if (!char_limit_t::is_valid_value(val_str
[i
])) {
435 value
->error("Invalid char in string %s at index %lu",
436 value
->get_stringRepr().c_str(), (unsigned long)i
);
439 charvalues
= charvalues
+ CharRangeListConstraint(val_str
[i
]);
441 stc
->charstring_st
= new CharstringSubtypeTreeElement(charvalues
, true);
443 case Value::V_CHARSYMS
: {
445 if (st_t
!=ST_UNIVERSAL_CHARSTRING
) FATAL_ERROR("SubtypeConstraint::create_from_asn_charvalues()");
446 UniversalCharRangeListConstraint ucharvalues
;
447 ustring val_ustr
= v
->get_val_ustr();
448 for (size_t i
=0; i
<val_ustr
.size(); i
++) {
449 if (!universal_char_limit_t::is_valid_value(val_ustr
[i
])) {
450 value
->error("Invalid universal char in string %s at index %lu",
451 value
->get_stringRepr().c_str(), (unsigned long)i
);
454 ucharvalues
= ucharvalues
+ UniversalCharRangeListConstraint(val_ustr
[i
]);
456 stc
->universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(ucharvalues
, true);
459 // error was already reported
468 int_limit_t
SubtypeConstraint::get_int_limit(bool is_upper
, Location
* loc
)
470 int_limit_t default_limit
= is_upper
?
471 int_limit_t::maximum
:
472 ((subtype
==ST_INTEGER
) ? int_limit_t::minimum
: int_limit_t(int_val_t((Int
)0)));
476 if (integer_st
->is_empty()==TTRUE
) {
477 loc
->error("Cannot determine the value of %s: the parent subtype is an empty set.",
478 is_upper
?"MAX":"MIN");
479 return default_limit
;
481 return is_upper
? integer_st
->get_maximal() : integer_st
->get_minimal();
484 return default_limit
;
488 tribool tb
= bitstring_st
->get_size_limit(is_upper
, sl
);
489 if (tb
==TTRUE
) return sl
.to_int_limit();
492 return default_limit
;
496 tribool tb
= hexstring_st
->get_size_limit(is_upper
, sl
);
497 if (tb
==TTRUE
) return sl
.to_int_limit();
500 return default_limit
;
502 if (octetstring_st
) {
504 tribool tb
= octetstring_st
->get_size_limit(is_upper
, sl
);
505 if (tb
==TTRUE
) return sl
.to_int_limit();
508 return default_limit
;
512 tribool tb
= charstring_st
->get_size_limit(is_upper
, sl
);
515 loc
->error("Cannot determine the value of %s: the parent subtype does "
516 "not define a %simal size value", is_upper
?"MAX":"MIN", is_upper
?"max":"min");
519 loc
->warning("Cannot determine the value of %s from parent subtype %s",
520 is_upper
?"MAX":"MIN", to_string().c_str());
523 return sl
.to_int_limit();
525 FATAL_ERROR("SubtypeConstraint::get_int_limit()");
528 return default_limit
;
529 case ST_UNIVERSAL_CHARSTRING
:
530 if (universal_charstring_st
) {
532 tribool tb
= universal_charstring_st
->get_size_limit(is_upper
, sl
);
535 loc
->error("Cannot determine the value of %s: the parent subtype does "
536 "not define a %simal size value", is_upper
?"MAX":"MIN", is_upper
?"max":"min");
539 loc
->warning("Cannot determine the value of %s from parent subtype %s",
540 is_upper
?"MAX":"MIN", to_string().c_str());
543 return sl
.to_int_limit();
545 FATAL_ERROR("SubtypeConstraint::get_int_limit()");
548 return default_limit
;
553 tribool tb
= recof_st
->get_size_limit(is_upper
, sl
);
554 if (tb
==TTRUE
) return sl
.to_int_limit();
557 return default_limit
;
559 FATAL_ERROR("SubtypeConstraint::get_int_limit()");
561 loc
->error("Cannot determine the value of %s from parent subtype %s",
562 is_upper
?"MAX":"MIN", to_string().c_str());
563 return default_limit
;
566 SubtypeConstraint
* SubtypeConstraint::create_from_asn_range(
567 Value
* vmin
, bool min_exclusive
, Value
* vmax
, bool max_exclusive
,
568 Location
* loc
, subtype_t st_t
, SubtypeConstraint
* parent_subtype
)
571 case SubtypeConstraint::ST_INTEGER
: {
572 if (((vmin
!=NULL
) && (vmin
->get_valuetype()!=Value::V_INT
)) ||
573 ((vmax
!=NULL
) && (vmax
->get_valuetype()!=Value::V_INT
))) return NULL
;
575 int_limit_t min_limit
;
577 min_limit
= int_limit_t(*(vmin
->get_val_Int()));
578 } else { // MIN was used
579 if (parent_subtype
) {
580 min_limit
= parent_subtype
->get_int_limit(false, loc
);
582 min_limit
= int_limit_t::minimum
;
587 if (min_limit
==int_limit_t::minimum
) {
588 loc
->error("invalid lower boundary, -infinity cannot be excluded from an INTEGER value range constraint");
591 min_limit
= min_limit
.next();
595 int_limit_t max_limit
;
597 max_limit
= int_limit_t(*(vmax
->get_val_Int()));
598 } else { // MAX was used
599 if (parent_subtype
) {
600 max_limit
= parent_subtype
->get_int_limit(true, loc
);
602 max_limit
= int_limit_t::maximum
;
607 if (max_limit
==int_limit_t::maximum
) {
608 loc
->error("invalid upper boundary, infinity cannot be excluded from an INTEGER value range constraint");
611 max_limit
= max_limit
.previous();
614 if (max_limit
<min_limit
) {
615 loc
->error("lower boundary is bigger than upper boundary in INTEGER value range constraint");
618 SubtypeConstraint
* stc
= new SubtypeConstraint(st_t
);
619 stc
->integer_st
= new IntegerRangeListConstraint(min_limit
, max_limit
);
623 if (((vmin
!=NULL
) && (vmin
->get_valuetype()!=Value::V_REAL
)) ||
624 ((vmax
!=NULL
) && (vmax
->get_valuetype()!=Value::V_REAL
))) return NULL
;
625 if ((vmin
!=NULL
) && (vmin
->get_val_Real()!=vmin
->get_val_Real())) {
626 loc
->error("lower boundary cannot be NOT-A-NUMBER in REAL value range constraint");
629 if ((vmax
!=NULL
) && (vmax
->get_val_Real()!=vmax
->get_val_Real())) {
630 loc
->error("upper boundary cannot be NOT-A-NUMBER in REAL value range constraint");
634 if (parent_subtype
&& (parent_subtype
->subtype
!=ST_FLOAT
)) FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
635 real_limit_t min_limit
;
637 min_limit
= real_limit_t(vmin
->get_val_Real());
638 } else { // MIN was used
639 if (parent_subtype
&& parent_subtype
->float_st
) {
640 if (parent_subtype
->float_st
->is_range_empty()==TTRUE
) {
641 loc
->error("Cannot determine the value of MIN: the parent subtype has no range");
642 min_limit
= real_limit_t::minimum
;
644 min_limit
= parent_subtype
->float_st
->get_minimal();
647 min_limit
= real_limit_t::minimum
;
652 min_limit
= min_limit
.next();
655 real_limit_t max_limit
;
657 max_limit
= real_limit_t(vmax
->get_val_Real());
658 } else { // MAX was used
659 if (parent_subtype
&& parent_subtype
->float_st
) {
660 if (parent_subtype
->float_st
->is_range_empty()==TTRUE
) {
661 loc
->error("Cannot determine the value of MAX: the parent subtype has no range");
662 max_limit
= real_limit_t::maximum
;
664 max_limit
= parent_subtype
->float_st
->get_maximal();
667 max_limit
= real_limit_t::maximum
;
672 max_limit
= max_limit
.previous();
674 if (max_limit
<min_limit
) {
675 loc
->error("lower boundary is bigger than upper boundary in REAL value range constraint");
678 SubtypeConstraint
* stc
= new SubtypeConstraint(st_t
);
679 stc
->float_st
= new RealRangeListConstraint(min_limit
, max_limit
);
682 case ST_CHARSTRING
: {
683 if (((vmin
!=NULL
) && (vmin
->get_valuetype()!=Value::V_CSTR
)) ||
684 ((vmax
!=NULL
) && (vmax
->get_valuetype()!=Value::V_CSTR
))) return NULL
;
685 if (vmin
&& (vmin
->get_val_str().size()!=1)) {
686 vmin
->error("lower boundary of string value range constraint must be a single element string");
689 if (vmax
&& (vmax
->get_val_str().size()!=1)) {
690 vmax
->error("upper boundary of string value range constraint must be a single element string");
693 if (vmin
&& !char_limit_t::is_valid_value(*vmin
->get_val_str().c_str())) {
694 vmin
->error("lower boundary of string value range constraint is an invalid char");
697 if (vmax
&& !char_limit_t::is_valid_value(*vmax
->get_val_str().c_str())) {
698 vmax
->error("upper boundary of string value range constraint is an invalid char");
702 if (parent_subtype
&& (parent_subtype
->subtype
!=ST_CHARSTRING
)) FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
704 char_limit_t min_limit
;
706 min_limit
= char_limit_t(*vmin
->get_val_str().c_str());
707 } else { // MIN was used
708 if (parent_subtype
&& parent_subtype
->charstring_st
) {
709 tribool tb
= parent_subtype
->charstring_st
->get_alphabet_limit(false, min_limit
);
712 loc
->error("Cannot determine the value of MIN: the parent subtype does not define a minimal char value");
713 min_limit
= char_limit_t::minimum
;
716 loc
->warning("Cannot determine the value of MIN, using the minimal char value of the type");
717 min_limit
= char_limit_t::minimum
;
720 // min_limit was set to the correct value
723 FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
726 min_limit
= char_limit_t::minimum
;
731 if (min_limit
==char_limit_t::maximum
) {
732 loc
->error("exclusive lower boundary is not a legal character");
735 min_limit
= min_limit
.next();
738 char_limit_t max_limit
;
740 max_limit
= char_limit_t(*vmax
->get_val_str().c_str());
741 } else { // MAX was used
742 if (parent_subtype
&& parent_subtype
->charstring_st
) {
743 tribool tb
= parent_subtype
->charstring_st
->get_alphabet_limit(true, max_limit
);
746 loc
->error("Cannot determine the value of MAX: the parent subtype does not define a maximal char value");
747 max_limit
= char_limit_t::maximum
;
750 loc
->warning("Cannot determine the value of MAX, using the maximal char value of the type");
751 max_limit
= char_limit_t::maximum
;
754 // max_limit was set to the correct value
757 FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
760 max_limit
= char_limit_t::maximum
;
765 if (max_limit
==char_limit_t::minimum
) {
766 loc
->error("exclusive upper boundary is not a legal character");
769 max_limit
= max_limit
.previous();
771 if (max_limit
<min_limit
) {
772 loc
->error("lower boundary is bigger than upper boundary in string value range constraint");
775 SubtypeConstraint
* stc
= new SubtypeConstraint(st_t
);
776 stc
->charstring_st
= new CharstringSubtypeTreeElement(CharRangeListConstraint(min_limit
,max_limit
), true);
779 case ST_UNIVERSAL_CHARSTRING
: {
780 if (((vmin
!=NULL
) && (vmin
->get_valuetype()!=Value::V_USTR
)) ||
781 ((vmax
!=NULL
) && (vmax
->get_valuetype()!=Value::V_USTR
))) return NULL
;
782 if (vmin
&& (vmin
->get_val_ustr().size()!=1)) {
783 vmin
->error("lower boundary of string value range constraint must be a single element string");
786 if (vmax
&& (vmax
->get_val_ustr().size()!=1)) {
787 vmax
->error("upper boundary of string value range constraint must be a single element string");
790 if (vmin
&& !universal_char_limit_t::is_valid_value(*vmin
->get_val_ustr().u_str())) {
791 vmin
->error("lower boundary of string value range constraint is an invalid universal char");
794 if (vmax
&& !universal_char_limit_t::is_valid_value(*vmax
->get_val_ustr().u_str())) {
795 vmax
->error("upper boundary of string value range constraint is an invalid universal char");
799 if (parent_subtype
&& (parent_subtype
->subtype
!=ST_UNIVERSAL_CHARSTRING
)) FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
800 universal_char_limit_t min_limit
;
802 min_limit
= universal_char_limit_t(*vmin
->get_val_ustr().u_str());
803 } else { // MIN was used
804 if (parent_subtype
&& parent_subtype
->universal_charstring_st
) {
805 tribool tb
= parent_subtype
->universal_charstring_st
->get_alphabet_limit(false, min_limit
);
808 loc
->error("Cannot determine the value of MIN: the parent subtype does not define a minimal char value");
809 min_limit
= universal_char_limit_t::minimum
;
812 loc
->warning("Cannot determine the value of MIN, using the minimal char value of the type");
813 min_limit
= universal_char_limit_t::minimum
;
816 // min_limit was set to the correct value
819 FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
822 min_limit
= universal_char_limit_t::minimum
;
827 if (min_limit
==universal_char_limit_t::maximum
) {
828 loc
->error("exclusive lower boundary is not a legal character");
831 min_limit
= min_limit
.next();
834 universal_char_limit_t max_limit
;
836 max_limit
= universal_char_limit_t(*vmax
->get_val_ustr().u_str());
837 } else { // MAX was used
838 if (parent_subtype
&& parent_subtype
->universal_charstring_st
) {
839 tribool tb
= parent_subtype
->universal_charstring_st
->get_alphabet_limit(true, max_limit
);
842 loc
->error("Cannot determine the value of MAX: the parent subtype does not define a maximal char value");
843 max_limit
= universal_char_limit_t::maximum
;
846 loc
->warning("Cannot determine the value of MAX, using the maximal char value of the type");
847 max_limit
= universal_char_limit_t::maximum
;
850 // max_limit was set to the correct value
853 FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
856 max_limit
= universal_char_limit_t::maximum
;
861 if (max_limit
==universal_char_limit_t::minimum
) {
862 loc
->error("exclusive upper boundary is not a legal character");
865 max_limit
= max_limit
.previous();
867 if (max_limit
<min_limit
) {
868 loc
->error("lower boundary is bigger than upper boundary in string value range constraint");
871 SubtypeConstraint
* stc
= new SubtypeConstraint(st_t
);
872 stc
->universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharRangeListConstraint(min_limit
,max_limit
), true);
876 FATAL_ERROR("SubtypeConstraint::create_from_asn_range()");
881 SubtypeConstraint
* SubtypeConstraint::create_from_contained_subtype(SubtypeConstraint
* contained_stc
, bool char_context
, Location
* loc
)
883 if (contained_stc
==NULL
) return NULL
;
884 SubtypeConstraint
* rv_stc
= NULL
;
886 switch (contained_stc
->get_subtypetype()) {
888 if (contained_stc
->charstring_st
==NULL
) {
889 rv_stc
= new SubtypeConstraint(contained_stc
->get_subtypetype()); // full set
891 if (contained_stc
->charstring_st
->is_valid_range()) {
892 rv_stc
= new SubtypeConstraint(contained_stc
->get_subtypetype());
893 rv_stc
->copy(contained_stc
);
894 rv_stc
->charstring_st
->set_char_context(true);
896 loc
->error("The type of the contained subtype constraint cannot be used in a permitted alphabet constraint");
900 case ST_UNIVERSAL_CHARSTRING
:
901 if (contained_stc
->universal_charstring_st
==NULL
) {
902 rv_stc
= new SubtypeConstraint(contained_stc
->get_subtypetype()); // full set
904 if (contained_stc
->universal_charstring_st
->is_valid_range()) {
905 rv_stc
= new SubtypeConstraint(contained_stc
->get_subtypetype());
906 rv_stc
->copy(contained_stc
);
907 rv_stc
->universal_charstring_st
->set_char_context(true);
909 loc
->error("The type of the contained subtype constraint cannot be used in a permitted alphabet constraint");
914 // error was already reported
918 rv_stc
= new SubtypeConstraint(contained_stc
->get_subtypetype());
919 rv_stc
->copy(contained_stc
);
924 SubtypeConstraint
* SubtypeConstraint::create_asn_size_constraint(
925 SubtypeConstraint
* integer_stc
, bool char_context
, Type
* type
, Location
* loc
)
927 if (integer_stc
==NULL
) return NULL
;
928 // convert IntegerRangeListConstraint to SizeRangeListConstraint
929 if (integer_stc
->subtype
!=ST_INTEGER
) FATAL_ERROR("SubtypeConstraint::create_asn_size_constraint()");
930 SizeRangeListConstraint
size_constraint(size_limit_t::minimum
, size_limit_t::maximum
);
931 if (integer_stc
->integer_st
) {
932 static const int_val_t
zero((Int
)0);
933 static const int_limit_t
ilt0(zero
);
934 IntegerRangeListConstraint
valid_range(ilt0
, int_limit_t::maximum
);
935 if (integer_stc
->integer_st
->is_subset(valid_range
)==TFALSE
) {
936 loc
->error("Range %s is not a valid range for a size constraint", integer_stc
->to_string().c_str());
938 bool success
= convert_int_to_size(*(integer_stc
->integer_st
), size_constraint
);
940 loc
->error("One or more INTEGER values of range %s are too large to be used in a size constraint", integer_stc
->to_string().c_str());
944 subtype_t st_t
= type
->get_subtype_type();
945 if (st_t
==ST_ERROR
) return NULL
;
946 SubtypeConstraint
* stc
= new SubtypeConstraint(st_t
);
949 stc
->length_restriction
= new SizeRangeListConstraint(size_constraint
); // FIXME? : is this Ok if not a top level constraint?
954 stc
->bitstring_st
= new BitstringConstraint(size_constraint
);
957 stc
->hexstring_st
= new HexstringConstraint(size_constraint
);
960 stc
->octetstring_st
= new OctetstringConstraint(size_constraint
);
964 if (size_constraint
.is_equal(SizeRangeListConstraint(size_limit_t(1)))==TFALSE
) {
965 loc
->error("Only SIZE(1) constraint can be used inside a permitted alphabet constraint");
969 // SIZE(1) is allowed in char context, it means ALL
971 stc
->charstring_st
= new CharstringSubtypeTreeElement(size_constraint
);
974 case ST_UNIVERSAL_CHARSTRING
:
976 if (size_constraint
.is_equal(SizeRangeListConstraint(size_limit_t(1)))==TFALSE
) {
977 loc
->error("Only SIZE(1) constraint can be used inside a permitted alphabet constraint");
981 // SIZE(1) is allowed in char context, it means ALL
983 stc
->universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(size_constraint
);
988 stc
->recof_st
= new RecofConstraint(size_constraint
);
991 loc
->error("Size constraint is not allowed for type `%s'", type
->get_typename().c_str());
998 SubtypeConstraint
* SubtypeConstraint::create_permitted_alphabet_constraint(
999 SubtypeConstraint
* stc
, bool char_context
, Type
* type
, Location
* loc
)
1002 loc
->error("Permitted alphabet constraint not allowed inside a permitted alphabet constraint");
1005 subtype_t st_t
= type
->get_subtype_type();
1008 case ST_UNIVERSAL_CHARSTRING
: {
1009 if (stc
==NULL
) return NULL
; // error was reported there
1010 if (st_t
!=stc
->get_subtypetype()) FATAL_ERROR("SubtypeConstraint::create_permitted_alphabet_constraint()");
1011 SubtypeConstraint
* rv_stc
= new SubtypeConstraint(st_t
);
1012 if (st_t
==ST_CHARSTRING
) {
1013 if (stc
->charstring_st
) {
1014 rv_stc
->charstring_st
= new CharstringSubtypeTreeElement(*(stc
->charstring_st
));
1015 rv_stc
->charstring_st
->set_char_context(false);
1018 if (stc
->universal_charstring_st
) {
1019 rv_stc
->universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(*(stc
->universal_charstring_st
));
1020 rv_stc
->universal_charstring_st
->set_char_context(false);
1026 // error already reported
1029 loc
->error("Permitted alphabet constraint is not allowed for type `%s'", type
->get_typename().c_str());
1035 void SubtypeConstraint::set_to_error()
1049 case ST_VERDICTTYPE
:
1053 delete bitstring_st
;
1056 delete hexstring_st
;
1058 case ST_OCTETSTRING
:
1059 delete octetstring_st
;
1062 delete charstring_st
;
1064 case ST_UNIVERSAL_CHARSTRING
:
1065 delete universal_charstring_st
;
1082 FATAL_ERROR("SubtypeConstraint::set_to_error()");
1085 delete length_restriction
;
1086 length_restriction
= NULL
;
1089 string
SubtypeConstraint::to_string() const
1093 return string("<error>");
1095 return (integer_st
==NULL
) ? string() : integer_st
->to_string();
1097 return (float_st
==NULL
) ? string() : float_st
->to_string();
1099 return (boolean_st
==NULL
) ? string() : boolean_st
->to_string();
1100 case ST_VERDICTTYPE
:
1101 return (verdict_st
==NULL
) ? string() : verdict_st
->to_string();
1103 return (bitstring_st
==NULL
) ? string() : bitstring_st
->to_string();
1105 return (hexstring_st
==NULL
) ? string() : hexstring_st
->to_string();
1106 case ST_OCTETSTRING
:
1107 return (octetstring_st
==NULL
) ? string() : octetstring_st
->to_string();
1109 return (charstring_st
==NULL
) ? string() : charstring_st
->to_string();
1110 case ST_UNIVERSAL_CHARSTRING
:
1111 return (universal_charstring_st
==NULL
) ? string() : universal_charstring_st
->to_string();
1120 return (value_st
==NULL
) ? string() : value_st
->to_string();
1123 return (recof_st
==NULL
) ? string() : recof_st
->to_string();
1125 FATAL_ERROR("SubtypeConstraint::to_string()");
1129 bool SubtypeConstraint::is_compatible(const SubtypeConstraint
*p_st
) const
1131 if (p_st
==NULL
) return true; // the other type has no subtype restriction
1132 if ( (subtype
==ST_ERROR
) || (p_st
->subtype
==ST_ERROR
) ) return true;
1133 if (subtype
!=p_st
->subtype
) FATAL_ERROR("SubtypeConstraint::is_compatible()");
1134 // if the resulting set.is_empty()==TUNKNOWN then remain silent
1137 if ((integer_st
==NULL
) || (p_st
->integer_st
==NULL
)) return true;
1138 return ((*integer_st
**(p_st
->integer_st
)).is_empty()!=TTRUE
);
1140 if ((float_st
==NULL
) || (p_st
->float_st
==NULL
)) return true;
1141 return ((*float_st
**(p_st
->float_st
)).is_empty()!=TTRUE
);
1143 if ((boolean_st
==NULL
) || (p_st
->boolean_st
==NULL
)) return true;
1144 return ((*boolean_st
**(p_st
->boolean_st
)).is_empty()!=TTRUE
);
1145 case ST_VERDICTTYPE
:
1146 if ((verdict_st
==NULL
) || (p_st
->verdict_st
==NULL
)) return true;
1147 return ((*verdict_st
**(p_st
->verdict_st
)).is_empty()!=TTRUE
);
1149 if ((bitstring_st
==NULL
) || (p_st
->bitstring_st
==NULL
)) return true;
1150 return ((*bitstring_st
**(p_st
->bitstring_st
)).is_empty()!=TTRUE
);
1152 if ((hexstring_st
==NULL
) || (p_st
->hexstring_st
==NULL
)) return true;
1153 return ((*hexstring_st
**(p_st
->hexstring_st
)).is_empty()!=TTRUE
);
1154 case ST_OCTETSTRING
:
1155 if ((octetstring_st
==NULL
) || (p_st
->octetstring_st
==NULL
)) return true;
1156 return ((*octetstring_st
**(p_st
->octetstring_st
)).is_empty()!=TTRUE
);
1157 case ST_CHARSTRING
: {
1158 if ((charstring_st
==NULL
) || (p_st
->charstring_st
==NULL
)) return true;
1159 CharstringSubtypeTreeElement
* cc
= new CharstringSubtypeTreeElement(
1160 CharstringSubtypeTreeElement::ET_INTERSECTION
,
1161 new CharstringSubtypeTreeElement(*charstring_st
),
1162 new CharstringSubtypeTreeElement(*(p_st
->charstring_st
))
1164 bool rv
= (cc
->is_empty()!=TTRUE
);
1168 case ST_UNIVERSAL_CHARSTRING
: {
1169 if ((universal_charstring_st
==NULL
) || (p_st
->universal_charstring_st
==NULL
)) return true;
1170 UniversalCharstringSubtypeTreeElement
* ucc
= new UniversalCharstringSubtypeTreeElement(
1171 UniversalCharstringSubtypeTreeElement::ET_INTERSECTION
,
1172 new UniversalCharstringSubtypeTreeElement(*universal_charstring_st
),
1173 new UniversalCharstringSubtypeTreeElement(*(p_st
->universal_charstring_st
))
1175 bool rv
= (ucc
->is_empty()!=TTRUE
);
1187 if ((value_st
==NULL
) || (p_st
->value_st
==NULL
)) return true;
1188 return ((*value_st
**(p_st
->value_st
)).is_empty()!=TTRUE
);
1191 if ((recof_st
==NULL
) || (p_st
->recof_st
==NULL
)) return true;
1192 return ((*recof_st
**(p_st
->recof_st
)).is_empty()!=TTRUE
);
1194 FATAL_ERROR("SubtypeConstraint::is_compatible()");
1199 bool SubtypeConstraint::is_compatible_with_elem() const
1201 if (subtype
==ST_ERROR
) return true;
1203 case ST_BITSTRING
: {
1204 static BitstringConstraint
str_elem(size_limit_t(1));
1205 if (bitstring_st
==NULL
) return true;
1206 return ((*bitstring_st
*str_elem
).is_empty()!=TTRUE
);
1208 case ST_HEXSTRING
: {
1209 static HexstringConstraint
str_elem(size_limit_t(1));
1210 if (hexstring_st
==NULL
) return true;
1211 return ((*hexstring_st
*str_elem
).is_empty()!=TTRUE
);
1213 case ST_OCTETSTRING
: {
1214 static OctetstringConstraint
str_elem(size_limit_t(1));
1215 if (octetstring_st
==NULL
) return true;
1216 return ((*octetstring_st
*str_elem
).is_empty()!=TTRUE
);
1218 case ST_CHARSTRING
: {
1219 size_limit_t t
= size_limit_t(1);
1220 SizeRangeListConstraint temp
= SizeRangeListConstraint(t
);
1221 static CharstringSubtypeTreeElement
str_elem(temp
);
1222 if (charstring_st
==NULL
) return true;
1223 CharstringSubtypeTreeElement
* cc
= new CharstringSubtypeTreeElement(
1224 CharstringSubtypeTreeElement::ET_INTERSECTION
,
1225 new CharstringSubtypeTreeElement(*charstring_st
),
1226 new CharstringSubtypeTreeElement(str_elem
)
1228 bool rv
= (cc
->is_empty()!=TTRUE
);
1232 case ST_UNIVERSAL_CHARSTRING
: {
1233 size_limit_t t
= size_limit_t(1);
1234 SizeRangeListConstraint temp
= SizeRangeListConstraint(t
);
1235 static UniversalCharstringSubtypeTreeElement
str_elem(temp
);
1236 if (universal_charstring_st
==NULL
) return true;
1237 UniversalCharstringSubtypeTreeElement
* ucc
= new UniversalCharstringSubtypeTreeElement(
1238 UniversalCharstringSubtypeTreeElement::ET_INTERSECTION
,
1239 new UniversalCharstringSubtypeTreeElement(*universal_charstring_st
),
1240 new UniversalCharstringSubtypeTreeElement(str_elem
)
1242 bool rv
= (ucc
->is_empty()!=TTRUE
);
1247 FATAL_ERROR("SubtypeConstraint::is_compatible_with_elem()");
1252 bool SubtypeConstraint::is_length_compatible(const SubtypeConstraint
*p_st
) const
1254 if (p_st
==NULL
) FATAL_ERROR("SubtypeConstraint::is_length_compatible()");
1255 if ((subtype
==ST_ERROR
) || (p_st
->subtype
==ST_ERROR
)) return true;
1256 if (subtype
!= ST_RECORDOF
&& subtype
!= ST_SETOF
&&
1257 p_st
->subtype
!= ST_RECORDOF
&& p_st
->subtype
!= ST_SETOF
)
1258 FATAL_ERROR("SubtypeConstraint::is_length_compatible()");
1259 if (length_restriction
==NULL
|| p_st
->length_restriction
==NULL
) return true;
1260 return ((*length_restriction
* *(p_st
->length_restriction
)).is_empty()!=TTRUE
);
1263 bool SubtypeConstraint::is_upper_limit_infinity() const
1265 if (ST_INTEGER
== subtype
&& integer_st
) {
1266 return integer_st
->is_upper_limit_infinity();
1268 if (ST_FLOAT
== subtype
&& float_st
) {
1269 return float_st
->is_upper_limit_infinity();
1274 bool SubtypeConstraint::is_lower_limit_infinity() const
1276 if (ST_INTEGER
== subtype
&& integer_st
) {
1277 return integer_st
->is_lower_limit_infinity();
1280 if (ST_FLOAT
== subtype
&& float_st
) {
1281 return float_st
->is_lower_limit_infinity();
1287 void SubtypeConstraint::except(const SubtypeConstraint
* other
)
1289 if (other
==NULL
) FATAL_ERROR("SubtypeConstraint::except()");
1290 if (subtype
!=other
->subtype
) FATAL_ERROR("SubtypeConstraint::except()");
1293 if (other
->integer_st
==NULL
) {
1294 if (integer_st
==NULL
) {
1295 integer_st
= new IntegerRangeListConstraint();
1297 *integer_st
= IntegerRangeListConstraint();
1300 if (integer_st
==NULL
) {
1301 integer_st
= new IntegerRangeListConstraint(~*(other
->integer_st
));
1303 *integer_st
= *integer_st
- *(other
->integer_st
);
1308 if (other
->float_st
==NULL
) {
1309 if (float_st
==NULL
) {
1310 float_st
= new RealRangeListConstraint();
1312 *float_st
= RealRangeListConstraint();
1315 if (float_st
==NULL
) {
1316 float_st
= new RealRangeListConstraint(~*(other
->float_st
));
1318 *float_st
= *float_st
- *(other
->float_st
);
1323 if (other
->boolean_st
==NULL
) {
1324 if (boolean_st
==NULL
) {
1325 boolean_st
= new BooleanListConstraint();
1327 *boolean_st
= BooleanListConstraint();
1330 if (boolean_st
==NULL
) {
1331 boolean_st
= new BooleanListConstraint(~*(other
->boolean_st
));
1333 *boolean_st
= *boolean_st
- *(other
->boolean_st
);
1337 case ST_VERDICTTYPE
:
1338 if (other
->verdict_st
==NULL
) {
1339 if (verdict_st
==NULL
) {
1340 verdict_st
= new VerdicttypeListConstraint();
1342 *verdict_st
= VerdicttypeListConstraint();
1345 if (verdict_st
==NULL
) {
1346 verdict_st
= new VerdicttypeListConstraint(~*(other
->verdict_st
));
1348 *verdict_st
= *verdict_st
- *(other
->verdict_st
);
1353 if (other
->bitstring_st
==NULL
) {
1354 if (bitstring_st
==NULL
) {
1355 bitstring_st
= new BitstringConstraint();
1357 *bitstring_st
= BitstringConstraint();
1360 if (bitstring_st
==NULL
) {
1361 bitstring_st
= new BitstringConstraint(~*(other
->bitstring_st
));
1363 *bitstring_st
= *bitstring_st
- *(other
->bitstring_st
);
1368 if (other
->hexstring_st
==NULL
) {
1369 if (hexstring_st
==NULL
) {
1370 hexstring_st
= new HexstringConstraint();
1372 *hexstring_st
= HexstringConstraint();
1375 if (hexstring_st
==NULL
) {
1376 hexstring_st
= new HexstringConstraint(~*(other
->hexstring_st
));
1378 *hexstring_st
= *hexstring_st
- *(other
->hexstring_st
);
1382 case ST_OCTETSTRING
:
1383 if (other
->octetstring_st
==NULL
) {
1384 if (octetstring_st
==NULL
) {
1385 octetstring_st
= new OctetstringConstraint();
1387 *octetstring_st
= OctetstringConstraint();
1390 if (octetstring_st
==NULL
) {
1391 octetstring_st
= new OctetstringConstraint(~*(other
->octetstring_st
));
1393 *octetstring_st
= *octetstring_st
- *(other
->octetstring_st
);
1398 if (other
->charstring_st
==NULL
) {
1399 if (charstring_st
==NULL
) {
1400 charstring_st
= new CharstringSubtypeTreeElement();
1402 *charstring_st
= CharstringSubtypeTreeElement();
1405 if (charstring_st
==NULL
) {
1406 CharstringSubtypeTreeElement
* call_st
= new CharstringSubtypeTreeElement();
1408 charstring_st
= new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_EXCEPT
,
1409 call_st
, new CharstringSubtypeTreeElement(*(other
->charstring_st
)));
1411 charstring_st
= new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_EXCEPT
,
1412 charstring_st
, new CharstringSubtypeTreeElement(*(other
->charstring_st
)));
1416 case ST_UNIVERSAL_CHARSTRING
:
1417 if (other
->universal_charstring_st
==NULL
) {
1418 if (universal_charstring_st
==NULL
) {
1419 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement();
1421 *universal_charstring_st
= UniversalCharstringSubtypeTreeElement();
1424 if (universal_charstring_st
==NULL
) {
1425 UniversalCharstringSubtypeTreeElement
* ucall_st
= new UniversalCharstringSubtypeTreeElement();
1426 ucall_st
->set_all();
1427 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_EXCEPT
,
1428 ucall_st
, new UniversalCharstringSubtypeTreeElement(*(other
->universal_charstring_st
)));
1430 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_EXCEPT
,
1431 universal_charstring_st
, new UniversalCharstringSubtypeTreeElement(*(other
->universal_charstring_st
)));
1443 if (other
->value_st
==NULL
) {
1444 if (value_st
==NULL
) {
1445 value_st
= new ValueListConstraint();
1447 *value_st
= ValueListConstraint();
1450 if (value_st
==NULL
) {
1451 value_st
= new ValueListConstraint(~*(other
->value_st
));
1453 *value_st
= *value_st
- *(other
->value_st
);
1459 if (other
->recof_st
==NULL
) {
1460 if (recof_st
==NULL
) {
1461 recof_st
= new RecofConstraint();
1463 *recof_st
= RecofConstraint();
1466 if (recof_st
==NULL
) {
1467 recof_st
= new RecofConstraint(~*(other
->recof_st
));
1469 *recof_st
= *recof_st
- *(other
->recof_st
);
1474 FATAL_ERROR("SubtypeConstraint::except()");
1476 if (other
->length_restriction
==NULL
) {
1477 if (length_restriction
==NULL
) {
1478 length_restriction
= new SizeRangeListConstraint();
1480 *length_restriction
= SizeRangeListConstraint();
1483 if (length_restriction
==NULL
) {
1484 length_restriction
= new SizeRangeListConstraint(~*(other
->length_restriction
));
1486 *length_restriction
= *length_restriction
- *(other
->length_restriction
);
1491 void SubtypeConstraint::union_(const SubtypeConstraint
* other
)
1493 if (other
==NULL
) FATAL_ERROR("SubtypeConstraint::union_()");
1494 if (subtype
!=other
->subtype
) FATAL_ERROR("SubtypeConstraint::union_()");
1497 if (integer_st
==NULL
) break;
1498 if (other
->integer_st
==NULL
) { delete integer_st
; integer_st
= NULL
; break; }
1499 *integer_st
= *integer_st
+ *(other
->integer_st
);
1502 if (float_st
==NULL
) break;
1503 if (other
->float_st
==NULL
) { delete float_st
; float_st
= NULL
; break; }
1504 *float_st
= *float_st
+ *(other
->float_st
);
1507 if (boolean_st
==NULL
) break;
1508 if (other
->boolean_st
==NULL
) { delete boolean_st
; boolean_st
= NULL
; break; }
1509 *boolean_st
= *boolean_st
+ *(other
->boolean_st
);
1511 case ST_VERDICTTYPE
:
1512 if (verdict_st
==NULL
) break;
1513 if (other
->verdict_st
==NULL
) { delete verdict_st
; verdict_st
= NULL
; break; }
1514 *verdict_st
= *verdict_st
+ *(other
->verdict_st
);
1517 if (bitstring_st
==NULL
) break;
1518 if (other
->bitstring_st
==NULL
) { delete bitstring_st
; bitstring_st
= NULL
; break; }
1519 *bitstring_st
= *bitstring_st
+ *(other
->bitstring_st
);
1522 if (hexstring_st
==NULL
) break;
1523 if (other
->hexstring_st
==NULL
) { delete hexstring_st
; hexstring_st
= NULL
; break; }
1524 *hexstring_st
= *hexstring_st
+ *(other
->hexstring_st
);
1526 case ST_OCTETSTRING
:
1527 if (octetstring_st
==NULL
) break;
1528 if (other
->octetstring_st
==NULL
) { delete octetstring_st
; octetstring_st
= NULL
; break; }
1529 *octetstring_st
= *octetstring_st
+ *(other
->octetstring_st
);
1532 if (charstring_st
==NULL
) break;
1533 if (other
->charstring_st
==NULL
) { delete charstring_st
; charstring_st
= NULL
; break; }
1534 charstring_st
= new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_UNION
,
1535 charstring_st
, new CharstringSubtypeTreeElement(*(other
->charstring_st
)));
1537 case ST_UNIVERSAL_CHARSTRING
:
1538 if (universal_charstring_st
==NULL
) break;
1539 if (other
->universal_charstring_st
==NULL
) { delete universal_charstring_st
; universal_charstring_st
= NULL
; break; }
1540 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_UNION
,
1541 universal_charstring_st
, new UniversalCharstringSubtypeTreeElement(*(other
->universal_charstring_st
)));
1551 if (value_st
==NULL
) break;
1552 if (other
->value_st
==NULL
) { delete value_st
; value_st
= NULL
; break; }
1553 *value_st
= *value_st
+ *(other
->value_st
);
1557 if (recof_st
==NULL
) break;
1558 if (other
->recof_st
==NULL
) { delete recof_st
; recof_st
= NULL
; break; }
1559 *recof_st
= *recof_st
+ *(other
->recof_st
);
1562 FATAL_ERROR("SubtypeConstraint::union_()");
1564 if (length_restriction
!=NULL
) {
1565 if (other
->length_restriction
==NULL
) {
1566 delete length_restriction
;
1567 length_restriction
= NULL
;
1569 *length_restriction
= *length_restriction
+ *(other
->length_restriction
);
1574 void SubtypeConstraint::intersection(const SubtypeConstraint
* other
)
1576 if (other
==NULL
) FATAL_ERROR("SubtypeConstraint::intersection()");
1577 if (subtype
!=other
->subtype
) FATAL_ERROR("SubtypeConstraint::intersection()");
1580 if (other
->integer_st
!=NULL
) {
1581 if (integer_st
==NULL
) {
1582 integer_st
= new IntegerRangeListConstraint(*(other
->integer_st
));
1584 *integer_st
= *integer_st
* *(other
->integer_st
);
1589 if (other
->float_st
!=NULL
) {
1590 if (float_st
==NULL
) {
1591 float_st
= new RealRangeListConstraint(*(other
->float_st
));
1593 *float_st
= *float_st
* *(other
->float_st
);
1598 if (other
->boolean_st
!=NULL
) {
1599 if (boolean_st
==NULL
) {
1600 boolean_st
= new BooleanListConstraint(*(other
->boolean_st
));
1602 *boolean_st
= *boolean_st
* *(other
->boolean_st
);
1606 case ST_VERDICTTYPE
:
1607 if (other
->verdict_st
!=NULL
) {
1608 if (verdict_st
==NULL
) {
1609 verdict_st
= new VerdicttypeListConstraint(*(other
->verdict_st
));
1611 *verdict_st
= *verdict_st
* *(other
->verdict_st
);
1616 if (other
->bitstring_st
!=NULL
) {
1617 if (bitstring_st
==NULL
) {
1618 bitstring_st
= new BitstringConstraint(*(other
->bitstring_st
));
1620 *bitstring_st
= *bitstring_st
* *(other
->bitstring_st
);
1625 if (other
->hexstring_st
!=NULL
) {
1626 if (hexstring_st
==NULL
) {
1627 hexstring_st
= new HexstringConstraint(*(other
->hexstring_st
));
1629 *hexstring_st
= *hexstring_st
* *(other
->hexstring_st
);
1633 case ST_OCTETSTRING
:
1634 if (other
->octetstring_st
!=NULL
) {
1635 if (octetstring_st
==NULL
) {
1636 octetstring_st
= new OctetstringConstraint(*(other
->octetstring_st
));
1638 *octetstring_st
= *octetstring_st
* *(other
->octetstring_st
);
1643 if (other
->charstring_st
!=NULL
) {
1644 if (charstring_st
==NULL
) {
1645 charstring_st
= new CharstringSubtypeTreeElement(*(other
->charstring_st
));
1647 charstring_st
= new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_INTERSECTION
,
1648 charstring_st
, new CharstringSubtypeTreeElement(*(other
->charstring_st
)));
1652 case ST_UNIVERSAL_CHARSTRING
:
1653 if (other
->universal_charstring_st
!=NULL
) {
1654 if (universal_charstring_st
==NULL
) {
1655 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(*(other
->universal_charstring_st
));
1657 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_INTERSECTION
,
1658 universal_charstring_st
, new UniversalCharstringSubtypeTreeElement(*(other
->universal_charstring_st
)));
1670 if (other
->value_st
!=NULL
) {
1671 if (value_st
==NULL
) {
1672 value_st
= new ValueListConstraint(*(other
->value_st
));
1674 *value_st
= *value_st
* *(other
->value_st
);
1680 if (other
->recof_st
!=NULL
) {
1681 if (recof_st
==NULL
) {
1682 recof_st
= new RecofConstraint(*(other
->recof_st
));
1684 *recof_st
= *recof_st
* *(other
->recof_st
);
1689 FATAL_ERROR("SubtypeConstraint::intersection()");
1691 if (other
->length_restriction
!=NULL
) {
1692 if (length_restriction
==NULL
) {
1693 length_restriction
= new SizeRangeListConstraint(*(other
->length_restriction
));
1695 *length_restriction
= *length_restriction
* *(other
->length_restriction
);
1700 tribool
SubtypeConstraint::is_subset(const SubtypeConstraint
* other
) const
1702 if (other
==NULL
) return TTRUE
;
1703 if (other
->subtype
!=subtype
) FATAL_ERROR("SubtypeConstraint::is_subset()");
1706 if (other
->integer_st
==NULL
) return TTRUE
;
1707 return integer_st
? integer_st
->is_subset(*(other
->integer_st
)) : TTRUE
;
1709 if (other
->float_st
==NULL
) return TTRUE
;
1710 return float_st
? float_st
->is_subset(*(other
->float_st
)) : TTRUE
;
1712 if (other
->boolean_st
==NULL
) return TTRUE
;
1713 return boolean_st
? boolean_st
->is_subset(*(other
->boolean_st
)) : TTRUE
;
1714 case ST_VERDICTTYPE
:
1715 if (other
->verdict_st
==NULL
) return TTRUE
;
1716 return verdict_st
? verdict_st
->is_subset(*(other
->verdict_st
)) : TTRUE
;
1718 if (other
->bitstring_st
==NULL
) return TTRUE
;
1719 return bitstring_st
? bitstring_st
->is_subset(*(other
->bitstring_st
)) : TTRUE
;
1721 if (other
->hexstring_st
==NULL
) return TTRUE
;
1722 return hexstring_st
? hexstring_st
->is_subset(*(other
->hexstring_st
)) : TTRUE
;
1723 case ST_OCTETSTRING
:
1724 if (other
->octetstring_st
==NULL
) return TTRUE
;
1725 return octetstring_st
? octetstring_st
->is_subset(*(other
->octetstring_st
)) : TTRUE
;
1727 if (other
->charstring_st
==NULL
) return TTRUE
;
1728 return charstring_st
? charstring_st
->is_subset(other
->charstring_st
) : TTRUE
;
1729 case ST_UNIVERSAL_CHARSTRING
:
1730 if (other
->universal_charstring_st
==NULL
) return TTRUE
;
1731 return universal_charstring_st
? universal_charstring_st
->is_subset(other
->universal_charstring_st
) : TTRUE
;
1740 if (other
->value_st
==NULL
) return TTRUE
;
1741 return value_st
? value_st
->is_subset(*(other
->value_st
)) : TTRUE
;
1744 if (other
->recof_st
==NULL
) return TTRUE
;
1745 return recof_st
? recof_st
->is_subset(*(other
->recof_st
)) : TTRUE
;
1747 FATAL_ERROR("SubtypeConstraint::is_subset()");
1752 /********************
1754 ********************/
1756 SubType::SubType(subtype_t st
, Type
*p_my_owner
, SubType
* p_parent_subtype
,
1757 vector
<SubTypeParse
> *p_parsed
, Constraints
* p_asn_constraints
)
1758 : SubtypeConstraint(st
), my_owner(p_my_owner
), parent_subtype(p_parent_subtype
)
1759 , parsed(p_parsed
), asn_constraints(p_asn_constraints
)
1760 , root(0), extendable(false), extension(0), checked(STC_NO
)
1763 if (p_my_owner
==NULL
) FATAL_ERROR("SubType::SubType()");
1771 void SubType::chk_this_value(Value
*value
)
1773 if (checked
==STC_NO
) FATAL_ERROR("SubType::chk_this_value()");
1774 if ((checked
==STC_CHECKING
) || (subtype
==ST_ERROR
)) return;
1775 Value
*val
= value
->get_value_refd_last();
1776 bool is_invalid
= false;
1777 switch (val
->get_valuetype()) {
1779 if (subtype
!=ST_INTEGER
) FATAL_ERROR("SubType::chk_this_value()");
1780 is_invalid
= (integer_st
!=NULL
) && !integer_st
->is_element(int_limit_t(*(val
->get_val_Int())));
1783 if (subtype
!=ST_FLOAT
) FATAL_ERROR("SubType::chk_this_value()");
1784 is_invalid
= (float_st
!=NULL
) && !float_st
->is_element(val
->get_val_Real());
1787 if (subtype
!=ST_BOOLEAN
) FATAL_ERROR("SubType::chk_this_value()");
1788 is_invalid
= (boolean_st
!=NULL
) && !boolean_st
->is_element(val
->get_val_bool());
1790 case Value::V_VERDICT
: {
1791 if (subtype
!=ST_VERDICTTYPE
) FATAL_ERROR("SubType::chk_this_value()");
1792 VerdicttypeListConstraint::verdicttype_constraint_t vtc
;
1793 switch (val
->get_val_verdict()) {
1794 case Value::Verdict_NONE
: vtc
= VerdicttypeListConstraint::VC_NONE
; break;
1795 case Value::Verdict_PASS
: vtc
= VerdicttypeListConstraint::VC_PASS
; break;
1796 case Value::Verdict_INCONC
: vtc
= VerdicttypeListConstraint::VC_INCONC
; break;
1797 case Value::Verdict_FAIL
: vtc
= VerdicttypeListConstraint::VC_FAIL
; break;
1798 case Value::Verdict_ERROR
: vtc
= VerdicttypeListConstraint::VC_ERROR
; break;
1799 default: FATAL_ERROR("SubType::chk_this_value()");
1801 is_invalid
= (verdict_st
!=NULL
) && !verdict_st
->is_element(vtc
);
1804 if (subtype
!=ST_BITSTRING
) FATAL_ERROR("SubType::chk_this_value()");
1805 is_invalid
= (bitstring_st
!=NULL
) && !bitstring_st
->is_element(val
->get_val_str());
1808 if (subtype
!=ST_HEXSTRING
) FATAL_ERROR("SubType::chk_this_value()");
1809 is_invalid
= (hexstring_st
!=NULL
) && !hexstring_st
->is_element(val
->get_val_str());
1812 if (subtype
!=ST_OCTETSTRING
) FATAL_ERROR("SubType::chk_this_value()");
1813 is_invalid
= (octetstring_st
!=NULL
) && !octetstring_st
->is_element(val
->get_val_str());
1816 case Value::V_ISO2022STR
:
1817 if (subtype
!=ST_CHARSTRING
) FATAL_ERROR("SubType::chk_this_value()");
1818 is_invalid
= (charstring_st
!=NULL
) && !charstring_st
->is_element(val
->get_val_str());
1821 case Value::V_CHARSYMS
:
1822 if (subtype
!=ST_UNIVERSAL_CHARSTRING
) FATAL_ERROR("SubType::chk_this_value()");
1823 is_invalid
= (universal_charstring_st
!=NULL
) && !universal_charstring_st
->is_element(val
->get_val_ustr());
1825 case Value::V_SEQOF
:
1826 if (subtype
!=ST_RECORDOF
) FATAL_ERROR("SubType::chk_this_value()");
1827 if (value
->is_unfoldable()) return;
1828 is_invalid
= (recof_st
!=NULL
) && !recof_st
->is_element(val
);
1830 case Value::V_SETOF
:
1831 if (subtype
!=ST_SETOF
) FATAL_ERROR("SubType::chk_this_value()");
1832 if (value
->is_unfoldable()) return;
1833 is_invalid
= (recof_st
!=NULL
) && !recof_st
->is_element(val
);
1837 if (subtype
!=ST_OBJID
) FATAL_ERROR("SubType::chk_this_value()");
1838 if (value
->is_unfoldable()) return;
1839 is_invalid
= (value_st
!=NULL
) && !value_st
->is_element(val
);
1842 case Value::V_NULL
: // FIXME: should go to ST_NULL
1843 if (subtype
!=ST_ENUM
) FATAL_ERROR("SubType::chk_this_value()");
1844 if (value
->is_unfoldable()) return;
1845 is_invalid
= (value_st
!=NULL
) && !value_st
->is_element(val
);
1847 case Value::V_CHOICE
:
1848 case Value::V_OPENTYPE
: // FIXME?
1849 if (subtype
!=ST_UNION
) FATAL_ERROR("SubType::chk_this_value()");
1850 if (value
->is_unfoldable()) return;
1851 is_invalid
= (value_st
!=NULL
) && !value_st
->is_element(val
);
1854 if (subtype
!=ST_RECORD
) FATAL_ERROR("SubType::chk_this_value()");
1855 if (value
->is_unfoldable()) return;
1856 is_invalid
= (value_st
!=NULL
) && !value_st
->is_element(val
);
1859 if (subtype
!=ST_SET
) FATAL_ERROR("SubType::chk_this_value()");
1860 if (value
->is_unfoldable()) return;
1861 is_invalid
= (value_st
!=NULL
) && !value_st
->is_element(val
);
1863 case Value::V_FUNCTION
:
1864 if (subtype
!=ST_FUNCTION
) FATAL_ERROR("SubType::chk_this_value()");
1865 if (value
->is_unfoldable()) return;
1866 is_invalid
= (value_st
!=NULL
) && !value_st
->is_element(val
);
1868 case Value::V_ALTSTEP
:
1869 if (subtype
!=ST_ALTSTEP
) FATAL_ERROR("SubType::chk_this_value()");
1870 if (value
->is_unfoldable()) return;
1871 is_invalid
= (value_st
!=NULL
) && !value_st
->is_element(val
);
1873 case Value::V_TESTCASE
:
1874 if (subtype
!=ST_TESTCASE
) FATAL_ERROR("SubType::chk_this_value()");
1875 if (value
->is_unfoldable()) return;
1876 is_invalid
= (value_st
!=NULL
) && !value_st
->is_element(val
);
1878 case Value::V_ERROR
:
1884 value
->error("%s is not a valid value for type `%s' which has subtype %s",
1885 val
->get_stringRepr().c_str(),
1886 my_owner
->get_typename().c_str(),
1887 to_string().c_str());
1892 void SubType::chk_this_template_generic(Template
*templ
)
1894 if (checked
==STC_NO
) FATAL_ERROR("SubType::chk_this_template_generic()");
1895 if ((checked
==STC_CHECKING
) || (subtype
==ST_ERROR
)) return;
1896 templ
= templ
->get_template_refd_last();
1897 switch (templ
->get_templatetype()) {
1898 case Ttcn::Template::OMIT_VALUE
:
1899 case Ttcn::Template::ANY_OR_OMIT
:
1900 case Ttcn::Template::TEMPLATE_ERROR
:
1901 case Ttcn::Template::ANY_VALUE
:
1903 case Ttcn::Template::VALUE_LIST
:
1904 case Ttcn::Template::COMPLEMENTED_LIST
:
1905 /* Should be canonical before */
1907 case Ttcn::Template::SPECIFIC_VALUE
:
1908 /* SPECIFIC_VALUE must be already checked in Type::chk_this_template() */
1910 case Ttcn::Template::TEMPLATE_REFD
:
1911 /* unfoldable reference: cannot be checked at compile time */
1913 case Ttcn::Template::TEMPLATE_INVOKE
:
1914 /* should be already checked in Type::chk_this_template() */
1917 chk_this_template(templ
);
1920 chk_this_template_length_restriction(templ
);
1924 void SubType::chk_this_template(Template
*templ
)
1926 switch (templ
->get_templatetype()) {
1927 case Template::TEMPLATE_LIST
:
1928 if ( (length_restriction
!=NULL
) && !length_restriction
->is_empty() ) {
1929 size_t nof_comp_woaon
= templ
->get_nof_comps_not_anyornone();
1930 if (!templ
->temps_contains_anyornone_symbol() &&
1931 nof_comp_woaon
< length_restriction
->get_minimal().get_size()) {
1932 templ
->error("At least %s elements must be present in the list",
1933 Int2string((Int
)(length_restriction
->get_minimal().get_size())).c_str());
1935 } else if ( !length_restriction
->get_maximal().get_infinity() && (nof_comp_woaon
> length_restriction
->get_maximal().get_size()) ) {
1936 templ
->error("There must not be more than %s elements in the list",
1937 Int2string((Int
)(length_restriction
->get_maximal().get_size())).c_str());
1942 /* Simply break. We don't know how many elements are there.
1943 SUPERSET_MATCH/SUBSET_MATCH is not possible to be an
1944 INDEXED_TEMPLATE_LIST. */
1945 case Template::INDEXED_TEMPLATE_LIST
:
1947 case Template::NAMED_TEMPLATE_LIST
:
1949 case Template::VALUE_RANGE
:
1950 /* Should be canonical before */
1952 case Template::ALL_FROM
:
1953 case Template::VALUE_LIST_ALL_FROM
:
1955 case Template::SUPERSET_MATCH
:
1956 case Template::SUBSET_MATCH
:
1957 if (subtype
!=ST_SETOF
){
1958 templ
->error("'subset' template matching mechanism can be used "
1959 "only with 'set of' types");
1962 for (size_t i
=0;i
<templ
->get_nof_comps();i
++)
1963 chk_this_template_generic(templ
->get_temp_byIndex(i
));
1965 case Template::BSTR_PATTERN
:
1966 chk_this_template_pattern("bitstring", templ
);
1968 case Template::HSTR_PATTERN
:
1969 chk_this_template_pattern("hexstring", templ
);
1971 case Template::OSTR_PATTERN
:
1972 chk_this_template_pattern("octetstring", templ
);
1974 case Template::CSTR_PATTERN
:
1975 chk_this_template_pattern("charstring", templ
);
1977 case Template::USTR_PATTERN
:
1978 chk_this_template_pattern("universal charstring", templ
);
1980 case Template::TEMPLATE_ERROR
:
1983 FATAL_ERROR("SubType::chk_this_template()");
1988 void SubType::chk_this_template_length_restriction(Template
*templ
)
1990 if (!templ
->is_length_restricted()) return;
1991 // if there is a length restriction on the template then check if
1992 // the intersection of the two restrictions is not empty
1993 size_limit_t
tmpl_min_len(size_limit_t(0));
1994 size_limit_t
tmpl_max_len(size_limit_t::INFINITE_SIZE
);
1995 Ttcn::LengthRestriction
*lr
=templ
->get_length_restriction();
1996 lr
->chk(Type::EXPECTED_DYNAMIC_VALUE
);
1997 if (!lr
->get_is_range()) { //Template's lr is single
1998 Value
*tmp_val
=lr
->get_single_value();
1999 if (tmp_val
->get_valuetype()!=Value::V_INT
) return;
2000 Int templ_len
= tmp_val
->get_val_Int()->get_val();
2001 tmpl_min_len
= tmpl_max_len
= size_limit_t((size_t)templ_len
);
2002 } else { //Template's lr is range
2003 Value
*tmp_lower
=lr
->get_lower_value();
2004 if (tmp_lower
->get_valuetype()!=Value::V_INT
) return;
2005 Int templ_lower
= tmp_lower
->get_val_Int()->get_val();
2006 tmpl_min_len
= size_limit_t((size_t)templ_lower
);
2007 Value
*tmp_upper
=lr
->get_upper_value();
2008 if (tmp_upper
&& tmp_upper
->get_valuetype()!=Value::V_INT
) return;
2009 if (tmp_upper
) tmpl_max_len
= size_limit_t((size_t)tmp_upper
->get_val_Int()->get_val());
2012 bool is_err
= false;
2015 if (bitstring_st
!=NULL
) {
2016 BitstringConstraint bc
= *bitstring_st
* BitstringConstraint(tmpl_min_len
,tmpl_max_len
);
2017 if (bc
.is_empty()==TTRUE
) is_err
= true;
2021 if (hexstring_st
!=NULL
) {
2022 HexstringConstraint hc
= *hexstring_st
* HexstringConstraint(tmpl_min_len
,tmpl_max_len
);
2023 if (hc
.is_empty()==TTRUE
) is_err
= true;
2026 case ST_OCTETSTRING
:
2027 if (octetstring_st
!=NULL
) {
2028 OctetstringConstraint oc
= *octetstring_st
* OctetstringConstraint(tmpl_min_len
,tmpl_max_len
);
2029 if (oc
.is_empty()==TTRUE
) is_err
= true;
2033 if (charstring_st
!=NULL
) {
2034 CharstringSubtypeTreeElement
* cc
= new CharstringSubtypeTreeElement(
2035 CharstringSubtypeTreeElement::ET_INTERSECTION
,
2036 new CharstringSubtypeTreeElement(*charstring_st
),
2037 new CharstringSubtypeTreeElement(SizeRangeListConstraint(tmpl_min_len
,tmpl_max_len
))
2039 if (cc
->is_empty()==TTRUE
) is_err
= true;
2043 case ST_UNIVERSAL_CHARSTRING
:
2044 if (universal_charstring_st
!=NULL
) {
2045 UniversalCharstringSubtypeTreeElement
* ucc
= new UniversalCharstringSubtypeTreeElement(
2046 UniversalCharstringSubtypeTreeElement::ET_INTERSECTION
,
2047 new UniversalCharstringSubtypeTreeElement(*universal_charstring_st
),
2048 new UniversalCharstringSubtypeTreeElement(SizeRangeListConstraint(tmpl_min_len
,tmpl_max_len
))
2050 if (ucc
->is_empty()==TTRUE
) is_err
= true;
2056 if (recof_st
!=NULL
) {
2057 RecofConstraint rc
= *recof_st
* RecofConstraint(tmpl_min_len
,tmpl_max_len
);
2058 if (rc
.is_empty()==TTRUE
) is_err
= true;
2065 templ
->error("Template's length restriction %s is outside of the type's subtype constraint %s",
2066 SizeRangeListConstraint(tmpl_min_len
,tmpl_max_len
).to_string().c_str(), to_string().c_str());
2070 void SubType::chk_this_template_pattern(const char *patt_type
, Template
*templ
)
2072 Template::templatetype_t temptype
= templ
->get_templatetype();
2073 if ((temptype
==Template::BSTR_PATTERN
&& subtype
!=ST_BITSTRING
) ||
2074 (temptype
==Template::HSTR_PATTERN
&& subtype
!=ST_HEXSTRING
) ||
2075 (temptype
==Template::OSTR_PATTERN
&& subtype
!=ST_OCTETSTRING
) ||
2076 (temptype
==Template::CSTR_PATTERN
&& subtype
!=ST_CHARSTRING
) ||
2077 (temptype
==Template::USTR_PATTERN
&& subtype
!=ST_UNIVERSAL_CHARSTRING
))
2079 templ
->error("Template is incompatible with subtype");
2082 if ( (length_restriction
!=NULL
) && !length_restriction
->is_empty() ) {
2083 Int patt_min_len
= static_cast<Int
>(templ
->get_min_length_of_pattern());
2084 if (patt_min_len
< (Int
)(length_restriction
->get_minimal().get_size()) &&
2085 !templ
->pattern_contains_anyornone_symbol()) {
2086 templ
->error("At least %s string elements must be present in the %s",
2087 Int2string((Int
)(length_restriction
->get_minimal().get_size())).c_str(), patt_type
);
2088 } else if ( !length_restriction
->get_maximal().get_infinity() && (patt_min_len
> (Int
)(length_restriction
->get_maximal().get_size())) ) {
2089 templ
->error("There must not be more than %s string elements in the %s",
2090 Int2string((Int
)(length_restriction
->get_maximal().get_size())).c_str(), patt_type
);
2095 void SubType::add_ttcn_value(Value
*v
)
2097 if (value_st
==NULL
) value_st
= new ValueListConstraint(v
);
2098 else *value_st
= *value_st
+ ValueListConstraint(v
);
2101 void SubType::add_ttcn_recof(Value
*v
)
2103 if (recof_st
==NULL
) recof_st
= new RecofConstraint(v
);
2104 else *recof_st
= *recof_st
+ RecofConstraint(v
);
2107 bool SubType::add_ttcn_type_list_subtype(SubType
* p_st
)
2111 if (p_st
->integer_st
==NULL
) return false;
2112 if (integer_st
==NULL
) integer_st
= new IntegerRangeListConstraint(*(p_st
->integer_st
));
2113 else *integer_st
= *integer_st
+ *(p_st
->integer_st
);
2116 if (p_st
->float_st
==NULL
) return false;
2117 if (float_st
==NULL
) float_st
= new RealRangeListConstraint(*(p_st
->float_st
));
2118 else *float_st
= *float_st
+ *(p_st
->float_st
);
2121 if (p_st
->boolean_st
==NULL
) return false;
2122 if (boolean_st
==NULL
) boolean_st
= new BooleanListConstraint(*(p_st
->boolean_st
));
2123 else *boolean_st
= *boolean_st
+ *(p_st
->boolean_st
);
2125 case ST_VERDICTTYPE
:
2126 if (p_st
->verdict_st
==NULL
) return false;
2127 if (verdict_st
==NULL
) verdict_st
= new VerdicttypeListConstraint(*(p_st
->verdict_st
));
2128 else *verdict_st
= *verdict_st
+ *(p_st
->verdict_st
);
2131 if (p_st
->bitstring_st
==NULL
) return false;
2132 if (bitstring_st
==NULL
) bitstring_st
= new BitstringConstraint(*(p_st
->bitstring_st
));
2133 else *bitstring_st
= *bitstring_st
+ *(p_st
->bitstring_st
);
2136 if (p_st
->hexstring_st
==NULL
) return false;
2137 if (hexstring_st
==NULL
) hexstring_st
= new HexstringConstraint(*(p_st
->hexstring_st
));
2138 else *hexstring_st
= *hexstring_st
+ *(p_st
->hexstring_st
);
2140 case ST_OCTETSTRING
:
2141 if (p_st
->octetstring_st
==NULL
) return false;
2142 if (octetstring_st
==NULL
) octetstring_st
= new OctetstringConstraint(*(p_st
->octetstring_st
));
2143 else *octetstring_st
= *octetstring_st
+ *(p_st
->octetstring_st
);
2146 if (p_st
->charstring_st
==NULL
) return false;
2147 if (charstring_st
==NULL
) {
2148 charstring_st
= new CharstringSubtypeTreeElement(*(p_st
->charstring_st
));
2150 charstring_st
= new CharstringSubtypeTreeElement(
2151 CharstringSubtypeTreeElement::ET_UNION
,
2153 new CharstringSubtypeTreeElement(*(p_st
->charstring_st
)));
2156 case ST_UNIVERSAL_CHARSTRING
:
2157 if (p_st
->universal_charstring_st
==NULL
) return false;
2158 if (universal_charstring_st
==NULL
) {
2159 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(*(p_st
->universal_charstring_st
));
2161 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(
2162 UniversalCharstringSubtypeTreeElement::ET_UNION
,
2163 universal_charstring_st
,
2164 new UniversalCharstringSubtypeTreeElement(*(p_st
->universal_charstring_st
)));
2175 if (p_st
->value_st
==NULL
) return false;
2176 if (value_st
==NULL
) value_st
= new ValueListConstraint(*(p_st
->value_st
));
2177 else *value_st
= *value_st
+ *(p_st
->value_st
);
2181 if (p_st
->recof_st
==NULL
) return false;
2182 if (recof_st
==NULL
) recof_st
= new RecofConstraint(*(p_st
->recof_st
));
2183 else *recof_st
= *recof_st
+ *(p_st
->recof_st
);
2186 FATAL_ERROR("SubType::add_ttcn_type_list_subtype()");
2192 bool SubType::add_parent_subtype(SubType
* st
)
2194 if (st
==NULL
) FATAL_ERROR("SubType::add_parent_subtype()");
2195 if (my_parents
.has_key(st
)) return true; // it was already successfully added -> ignore
2196 ReferenceChain
refch(my_owner
, "While checking circular type references in subtype definitions");
2197 refch
.add(my_owner
->get_fullname()); // current type
2198 // recursive check for all parents of referenced type
2199 if (!st
->chk_recursion(refch
)) return false;
2200 // if no recursion was detected then add the referenced type as parent
2201 my_parents
.add(st
,NULL
);
2205 bool SubType::chk_recursion(ReferenceChain
& refch
)
2207 if (!refch
.add(my_owner
->get_fullname())) return false; // try the referenced type
2208 for (size_t i
= 0; i
< my_parents
.size(); i
++) {
2210 if (!my_parents
.get_nth_key(i
)->chk_recursion(refch
)) return false;
2216 bool SubType::add_ttcn_single(Value
*val
, size_t restriction_index
)
2218 val
->set_my_scope(my_owner
->get_my_scope());
2219 val
->set_my_governor(my_owner
);
2220 val
->set_fullname(my_owner
->get_fullname()+".<single_restriction_"+Int2string(restriction_index
) + ">");
2221 my_owner
->chk_this_value_ref(val
);
2223 // check if this is type reference, if not then fall through
2224 if (val
->get_valuetype()==Value::V_REFD
) {
2225 Reference
* ref
= val
->get_reference();
2226 Assignment
*ass
= ref
->get_refd_assignment();
2227 if (ass
==NULL
) return false; // defintion was not found, error was reported
2228 if (ass
->get_asstype()==Assignment::A_TYPE
) {
2229 Type
* t
= ass
->get_Type();
2231 if (t
->get_typetype()==Type::T_ERROR
) return false;
2232 // if there were subreferences then get the referenced field's type
2233 if (ref
->get_subrefs()) {
2234 t
= t
->get_field_type(ref
->get_subrefs(), Type::EXPECTED_CONSTANT
);
2235 if ( (t
==NULL
) || (t
->get_typetype()==Type::T_ERROR
) ) return false;
2237 if (t
->get_typetype()==Type::T_ERROR
) return false;
2239 if (!t
->is_identical(my_owner
)) {
2240 val
->error("Reference `%s' must refer to a type which has the same root type as this type",
2241 val
->get_reference()->get_dispname().c_str());
2244 // check subtype of referenced type
2245 SubType
* t_st
= t
->get_sub_type();
2247 val
->error("Type referenced by `%s' does not have a subtype",
2248 val
->get_reference()->get_dispname().c_str());
2252 // check circular subtype reference
2253 if (!add_parent_subtype(t_st
)) return false;
2255 if (t_st
->get_subtypetype()==ST_ERROR
) return false;
2256 if (t_st
->get_subtypetype()!=subtype
) FATAL_ERROR("SubType::add_ttcn_single()");
2257 // add the subtype as union
2258 bool added
= add_ttcn_type_list_subtype(t_st
);
2260 val
->error("Type referenced by `%s' does not have a subtype",
2261 val
->get_reference()->get_dispname().c_str());
2267 my_owner
->chk_this_value(val
, 0, Type::EXPECTED_CONSTANT
,
2268 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
2270 Value
*v
=val
->get_value_refd_last();
2272 switch (v
->get_valuetype()) {
2274 if (subtype
!=ST_INTEGER
) FATAL_ERROR("SubType::add_ttcn_single()");
2275 if (integer_st
==NULL
) integer_st
= new IntegerRangeListConstraint(int_limit_t(*(v
->get_val_Int())));
2276 else *integer_st
= *integer_st
+ IntegerRangeListConstraint(int_limit_t(*(v
->get_val_Int())));
2278 case Value::V_REAL
: {
2279 if (subtype
!=ST_FLOAT
) FATAL_ERROR("SubType::add_ttcn_single()");
2280 ttcn3float r
= v
->get_val_Real();
2282 if (float_st
==NULL
) float_st
= new RealRangeListConstraint(true);
2283 else *float_st
= *float_st
+ RealRangeListConstraint(true);
2285 if (float_st
==NULL
) float_st
= new RealRangeListConstraint(real_limit_t(r
));
2286 else *float_st
= *float_st
+ RealRangeListConstraint(real_limit_t(r
));
2290 if (subtype
!=ST_BOOLEAN
) FATAL_ERROR("SubType::add_ttcn_single()");
2291 if (boolean_st
==NULL
) boolean_st
= new BooleanListConstraint(v
->get_val_bool());
2292 else *boolean_st
= *boolean_st
+ BooleanListConstraint(v
->get_val_bool());
2294 case Value::V_VERDICT
: {
2295 if (subtype
!=ST_VERDICTTYPE
) FATAL_ERROR("SubType::add_ttcn_single()");
2296 VerdicttypeListConstraint::verdicttype_constraint_t vtc
;
2297 switch (v
->get_val_verdict()) {
2298 case Value::Verdict_NONE
: vtc
= VerdicttypeListConstraint::VC_NONE
; break;
2299 case Value::Verdict_PASS
: vtc
= VerdicttypeListConstraint::VC_PASS
; break;
2300 case Value::Verdict_INCONC
: vtc
= VerdicttypeListConstraint::VC_INCONC
; break;
2301 case Value::Verdict_FAIL
: vtc
= VerdicttypeListConstraint::VC_FAIL
; break;
2302 case Value::Verdict_ERROR
: vtc
= VerdicttypeListConstraint::VC_ERROR
; break;
2303 default: FATAL_ERROR("SubType::add_ttcn_single()");
2305 if (verdict_st
==NULL
) verdict_st
= new VerdicttypeListConstraint(vtc
);
2306 else *verdict_st
= *verdict_st
+ VerdicttypeListConstraint(vtc
);
2309 if (v
->has_oid_error()) return false;
2310 if (subtype
!=ST_OBJID
) FATAL_ERROR("SubType::add_ttcn_single()");
2311 if (value_st
==NULL
) value_st
= new ValueListConstraint(v
);
2312 else *value_st
= *value_st
+ ValueListConstraint(v
);
2315 if (subtype
!=ST_BITSTRING
) FATAL_ERROR("SubType::add_ttcn_single()");
2316 if (bitstring_st
==NULL
) bitstring_st
= new BitstringConstraint(v
->get_val_str());
2317 else *bitstring_st
= *bitstring_st
+ BitstringConstraint(v
->get_val_str());
2320 if (subtype
!=ST_HEXSTRING
) FATAL_ERROR("SubType::add_ttcn_single()");
2321 if (hexstring_st
==NULL
) hexstring_st
= new HexstringConstraint(v
->get_val_str());
2322 else *hexstring_st
= *hexstring_st
+ HexstringConstraint(v
->get_val_str());
2325 if (subtype
!=ST_OCTETSTRING
) FATAL_ERROR("SubType::add_ttcn_single()");
2326 if (octetstring_st
==NULL
) octetstring_st
= new OctetstringConstraint(v
->get_val_str());
2327 else *octetstring_st
= *octetstring_st
+ OctetstringConstraint(v
->get_val_str());
2329 case Value::V_CSTR
: {
2330 if (subtype
!=ST_CHARSTRING
) FATAL_ERROR("SubType::add_ttcn_single()");
2331 CharstringSubtypeTreeElement
* cst_elem
= new CharstringSubtypeTreeElement(StringValueConstraint
<string
>(v
->get_val_str()));
2332 if (charstring_st
==NULL
) charstring_st
= cst_elem
;
2333 else charstring_st
= new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_UNION
, charstring_st
, cst_elem
);
2335 case Value::V_USTR
: {
2336 if (subtype
!=ST_UNIVERSAL_CHARSTRING
) FATAL_ERROR("SubType::add_ttcn_single()");
2337 UniversalCharstringSubtypeTreeElement
* ucst_elem
= new UniversalCharstringSubtypeTreeElement(StringValueConstraint
<ustring
>(v
->get_val_ustr()));
2338 if (universal_charstring_st
==NULL
) universal_charstring_st
= ucst_elem
;
2339 else universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_UNION
, universal_charstring_st
, ucst_elem
);
2342 case Value::V_NULL
: // FIXME: should go to ST_NULL
2343 if (subtype
!=ST_ENUM
) FATAL_ERROR("SubType::add_ttcn_single()");
2346 case Value::V_CHOICE
:
2347 if (subtype
!=ST_UNION
) FATAL_ERROR("SubType::add_ttcn_single()");
2351 if (subtype
!=ST_RECORD
) FATAL_ERROR("SubType::add_ttcn_single()");
2355 if (subtype
!=ST_SET
) FATAL_ERROR("SubType::add_ttcn_single()");
2358 case Value::V_FUNCTION
:
2359 if (subtype
!=ST_FUNCTION
) FATAL_ERROR("SubType::add_ttcn_single()");
2362 case Value::V_ALTSTEP
:
2363 if (subtype
!=ST_ALTSTEP
) FATAL_ERROR("SubType::add_ttcn_single()");
2366 case Value::V_TESTCASE
:
2367 if (subtype
!=ST_TESTCASE
) FATAL_ERROR("SubType::add_ttcn_single()");
2370 case Value::V_SEQOF
:
2371 if (subtype
!=ST_RECORDOF
) FATAL_ERROR("SubType::add_ttcn_single()");
2374 case Value::V_SETOF
:
2375 if (subtype
!=ST_SETOF
) FATAL_ERROR("SubType::add_ttcn_single()");
2378 case Value::V_ERROR
:
2386 bool SubType::add_ttcn_range(Value
*min
, bool min_exclusive
,
2387 Value
*max
, bool max_exclusive
, size_t restriction_index
, bool has_other
)
2393 case ST_UNIVERSAL_CHARSTRING
:
2396 my_owner
->error("Range subtyping is not allowed for type `%s'",
2397 my_owner
->get_typename().c_str());
2402 if (min
==NULL
) vmin
=NULL
;
2404 min
->set_my_scope(my_owner
->get_my_scope());
2405 min
->set_fullname(my_owner
->get_fullname()+".<range_restriction_"+Int2string(restriction_index
)+"_lower>");
2406 my_owner
->chk_this_value_ref(min
);
2407 my_owner
->chk_this_value(min
, 0, Type::EXPECTED_CONSTANT
,
2408 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
2409 vmin
=min
->get_value_refd_last();
2411 if (max
==NULL
) vmax
=NULL
;
2413 max
->set_my_scope(my_owner
->get_my_scope());
2414 max
->set_fullname(my_owner
->get_fullname()+".<range_restriction_"+Int2string(restriction_index
)+"_upper>");
2415 my_owner
->chk_this_value_ref(max
);
2416 my_owner
->chk_this_value(max
, 0, Type::EXPECTED_CONSTANT
,
2417 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
2418 vmax
=max
->get_value_refd_last();
2421 if ( (vmin
!=NULL
) && (vmax
!=NULL
) && (vmin
->get_valuetype()!=vmax
->get_valuetype()) ) return false;
2425 if (((vmin
!=NULL
) && (vmin
->get_valuetype()!=Value::V_INT
)) ||
2426 ((vmax
!=NULL
) && (vmax
->get_valuetype()!=Value::V_INT
))) return false;
2427 int_limit_t min_limit
= (vmin
!=NULL
) ? int_limit_t(*(vmin
->get_val_Int())) : int_limit_t::minimum
;
2428 if (min_exclusive
) {
2429 if (min_limit
==int_limit_t::minimum
) {
2430 my_owner
->error("invalid lower boundary, -infinity cannot be excluded from an integer subtype range");
2433 if (min_limit
==int_limit_t::maximum
) {
2434 my_owner
->error("!infinity is not a valid lower boundary");
2437 min_limit
= min_limit
.next();
2440 int_limit_t max_limit
= (vmax
!=NULL
) ? int_limit_t(*(vmax
->get_val_Int())) : int_limit_t::maximum
;
2441 if (max_exclusive
) {
2442 if (max_limit
==int_limit_t::maximum
) {
2443 my_owner
->error("invalid upper boundary, infinity cannot be excluded from an integer subtype range");
2446 if (max_limit
==int_limit_t::minimum
) {
2447 my_owner
->error("!-infinity is not a valid upper boundary");
2450 max_limit
= max_limit
.previous();
2453 if (max_limit
<min_limit
) {
2454 my_owner
->error("lower boundary is bigger than upper boundary in integer subtype range");
2457 if (integer_st
==NULL
) integer_st
= new IntegerRangeListConstraint(min_limit
, max_limit
);
2458 else *integer_st
= *integer_st
+ IntegerRangeListConstraint(min_limit
, max_limit
);
2461 if (((vmin
!=NULL
) && (vmin
->get_valuetype()!=Value::V_REAL
)) ||
2462 ((vmax
!=NULL
) && (vmax
->get_valuetype()!=Value::V_REAL
))) return false;
2463 if ((vmin
!=NULL
) && (vmin
->get_val_Real()!=vmin
->get_val_Real())) {
2464 my_owner
->error("lower boundary cannot be not_a_number in float subtype range");
2467 if ((vmax
!=NULL
) && (vmax
->get_val_Real()!=vmax
->get_val_Real())) {
2468 my_owner
->error("upper boundary cannot be not_a_number in float subtype range");
2471 real_limit_t min_limit
= (vmin
!=NULL
) ? real_limit_t(vmin
->get_val_Real()) : real_limit_t::minimum
;
2472 if (min_exclusive
) {
2473 if (min_limit
==real_limit_t::maximum
) {
2474 my_owner
->error("!infinity is not a valid lower boundary");
2477 min_limit
= min_limit
.next();
2479 real_limit_t max_limit
= (vmax
!=NULL
) ? real_limit_t(vmax
->get_val_Real()) : real_limit_t::maximum
;
2480 if (max_exclusive
) {
2481 if (max_limit
==real_limit_t::minimum
) {
2482 my_owner
->error("!-infinity is not a valid upper boundary");
2485 max_limit
= max_limit
.previous();
2487 if (max_limit
<min_limit
) {
2488 my_owner
->error("lower boundary is bigger than upper boundary in float subtype range");
2491 if (float_st
==NULL
) float_st
= new RealRangeListConstraint(min_limit
, max_limit
);
2492 else *float_st
= *float_st
+ RealRangeListConstraint(min_limit
, max_limit
);
2494 case ST_CHARSTRING
: {
2495 if (((vmin
!=NULL
) && (vmin
->get_valuetype()!=Value::V_CSTR
)) ||
2496 ((vmax
!=NULL
) && (vmax
->get_valuetype()!=Value::V_CSTR
))) return false;
2497 if ((vmin
==NULL
)&&(vmax
==NULL
)) {
2498 my_owner
->error("a range subtype of a charstring cannot be (-infinity..infinity)");
2502 my_owner
->error("lower boundary of a charstring subtype range cannot be -infinity");
2506 my_owner
->error("upper boundary of a charstring subtype range cannot be infinity");
2509 if (vmin
->get_val_str().size()!=1) {
2510 min
->error("lower boundary of charstring subtype range must be a single element string");
2513 if (vmax
->get_val_str().size()!=1) {
2514 max
->error("upper boundary of charstring subtype range must be a single element string");
2517 if (!char_limit_t::is_valid_value(*vmin
->get_val_str().c_str())) {
2518 min
->error("lower boundary of charstring subtype range is an invalid char");
2521 if (!char_limit_t::is_valid_value(*vmax
->get_val_str().c_str())) {
2522 max
->error("upper boundary of charstring subtype range is an invalid char");
2525 char_limit_t
min_limit(*vmin
->get_val_str().c_str()), max_limit(*vmax
->get_val_str().c_str());
2526 if (min_exclusive
) {
2527 if (min_limit
==char_limit_t::maximum
) {
2528 min
->error("exclusive lower boundary is not a legal charstring character");
2531 min_limit
= min_limit
.next();
2533 if (max_exclusive
) {
2534 if (max_limit
==char_limit_t::minimum
) {
2535 max
->error("exclusive upper boundary is not a legal charstring character");
2538 max_limit
= max_limit
.previous();
2540 if (max_limit
<min_limit
) {
2541 my_owner
->error("lower boundary is bigger than upper boundary in charstring subtype range");
2544 if (charstring_st
==NULL
) charstring_st
= new CharstringSubtypeTreeElement(CharRangeListConstraint(min_limit
,max_limit
), false);
2546 if (!has_other
) { // union in char context can be done only with range constraints
2547 charstring_st
->set_char_context(true);
2548 charstring_st
= new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_UNION
,
2550 new CharstringSubtypeTreeElement(CharRangeListConstraint(min_limit
,max_limit
), true));
2551 charstring_st
->set_char_context(false);
2553 // ignore it, error reported elsewhere
2558 case ST_UNIVERSAL_CHARSTRING
: {
2559 if (((vmin
!=NULL
) && (vmin
->get_valuetype()!=Value::V_USTR
)) ||
2560 ((vmax
!=NULL
) && (vmax
->get_valuetype()!=Value::V_USTR
))) return false;
2561 if ((vmin
==NULL
)&&(vmax
==NULL
)) {
2562 my_owner
->error("a range subtype of a universal charstring cannot be (-infinity..infinity)");
2566 my_owner
->error("lower boundary of a universal charstring subtype range cannot be -infinity");
2570 my_owner
->error("upper boundary of a universal charstring subtype range cannot be infinity");
2573 if (vmin
->get_val_ustr().size()!=1) {
2574 min
->error("lower boundary of universal charstring subtype range must be a single element string");
2577 if (vmax
->get_val_ustr().size()!=1) {
2578 max
->error("upper boundary of universal charstring subtype range must be a single element string");
2581 if (!universal_char_limit_t::is_valid_value(*vmin
->get_val_ustr().u_str())) {
2582 min
->error("lower boundary of universal charstring subtype range is an invalid char");
2585 if (!universal_char_limit_t::is_valid_value(*vmax
->get_val_ustr().u_str())) {
2586 max
->error("upper boundary of universal charstring subtype range is an invalid char");
2589 universal_char_limit_t
min_limit(*vmin
->get_val_ustr().u_str()), max_limit(*vmax
->get_val_ustr().u_str());
2590 if (min_exclusive
) {
2591 if (min_limit
==universal_char_limit_t::maximum
) {
2592 min
->error("exclusive lower boundary is not a legal universal charstring character");
2595 min_limit
= min_limit
.next();
2597 if (max_exclusive
) {
2598 if (max_limit
==universal_char_limit_t::minimum
) {
2599 max
->error("exclusive upper boundary is not a legal universal charstring character");
2602 max_limit
= max_limit
.previous();
2604 if (max_limit
<min_limit
) {
2605 my_owner
->error("lower boundary is bigger than upper boundary in universal charstring subtype range");
2609 if (universal_charstring_st
==NULL
) universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharRangeListConstraint(min_limit
,max_limit
), false);
2611 if (!has_other
) { // union in char context can be done only with range constraints
2612 universal_charstring_st
->set_char_context(true);
2613 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_UNION
,
2614 universal_charstring_st
,
2615 new UniversalCharstringSubtypeTreeElement(UniversalCharRangeListConstraint(min_limit
,max_limit
), true));
2616 universal_charstring_st
->set_char_context(false);
2618 // ignore it, error reported elsewhere
2624 FATAL_ERROR("SubType::add_ttcn_range()");
2629 bool SubType::set_ttcn_length(const size_limit_t
& min
, const size_limit_t
& max
)
2632 case ST_BITSTRING
: {
2633 if (bitstring_st
==NULL
) bitstring_st
= new BitstringConstraint(min
,max
);
2634 else *bitstring_st
= *bitstring_st
* BitstringConstraint(min
,max
);
2636 case ST_HEXSTRING
: {
2637 if (hexstring_st
==NULL
) hexstring_st
= new HexstringConstraint(min
,max
);
2638 else *hexstring_st
= *hexstring_st
* HexstringConstraint(min
,max
);
2640 case ST_OCTETSTRING
: {
2641 if (octetstring_st
==NULL
) octetstring_st
= new OctetstringConstraint(min
,max
);
2642 else *octetstring_st
= *octetstring_st
* OctetstringConstraint(min
,max
);
2644 case ST_CHARSTRING
: {
2645 CharstringSubtypeTreeElement
* cst_elem
= new CharstringSubtypeTreeElement(SizeRangeListConstraint(min
,max
));
2646 if (charstring_st
==NULL
) {
2647 charstring_st
= cst_elem
;
2649 charstring_st
= new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_INTERSECTION
, charstring_st
, cst_elem
);
2652 case ST_UNIVERSAL_CHARSTRING
: {
2653 UniversalCharstringSubtypeTreeElement
* ucst_elem
= new UniversalCharstringSubtypeTreeElement(SizeRangeListConstraint(min
,max
));
2654 if (universal_charstring_st
==NULL
) {
2655 universal_charstring_st
= ucst_elem
;
2657 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_INTERSECTION
, universal_charstring_st
, ucst_elem
);
2662 if (recof_st
==NULL
) recof_st
= new RecofConstraint(min
,max
);
2663 else *recof_st
= *recof_st
* RecofConstraint(min
,max
);
2666 my_owner
->error("Length subtyping is not allowed for type `%s'",
2667 my_owner
->get_typename().c_str());
2670 if (length_restriction
==NULL
) length_restriction
= new SizeRangeListConstraint(min
,max
);
2671 else *length_restriction
= *length_restriction
* SizeRangeListConstraint(min
,max
);
2675 void SubType::chk_boundary_valid(Value
* boundary
, Int max_value
, const char* boundary_name
)
2677 const int_val_t
*int_val
= boundary
->get_val_Int();
2678 if (*int_val
> int_val_t(max_value
)) {
2679 boundary
->error("The %s should be less than `%s' instead of `%s'",
2681 int_val_t(max_value
).t_str().c_str(),
2682 int_val
->t_str().c_str());
2683 boundary
->set_valuetype(Value::V_ERROR
);
2687 bool SubType::add_ttcn_length(Ttcn::LengthRestriction
*lr
, size_t restriction_index
)
2690 lr
->append_stringRepr(s
);
2691 Value
*lower
=NULL
,*upper
=NULL
;
2692 lr
->set_my_scope(my_owner
->get_my_scope());
2693 lr
->set_fullname(my_owner
->get_fullname()+".<length_restriction_"+Int2string(restriction_index
)+">");
2694 lr
->chk(Type::EXPECTED_CONSTANT
);
2695 lower
= lr
->get_is_range() ? lr
->get_lower_value() : lr
->get_single_value();
2696 if (!lower
->get_my_scope()) FATAL_ERROR("no scope");
2697 if (lower
->get_valuetype() != Value::V_INT
) return false;
2698 if (lr
->get_is_range()) {
2699 upper
= lr
->get_upper_value();
2700 if (upper
) {//HAS_UPPER
2701 if (upper
->get_valuetype()!=Value::V_INT
) return false;
2702 if (!upper
->get_my_scope()) upper
->set_my_scope(my_owner
->get_my_scope());
2703 chk_boundary_valid(upper
, INT_MAX
, "upper boundary");
2704 if (upper
->get_valuetype()!=Value::V_INT
) return false;
2705 return set_ttcn_length(size_limit_t((size_t)lower
->get_val_Int()->get_val()),
2706 size_limit_t((size_t)upper
->get_val_Int()->get_val()));
2708 chk_boundary_valid(lower
, INT_MAX
, "lower boundary");
2709 if (lower
->get_valuetype()!=Value::V_INT
) return false;
2710 return set_ttcn_length(size_limit_t((size_t)lower
->get_val_Int()->get_val()),
2711 size_limit_t(size_limit_t::INFINITE_SIZE
));
2715 chk_boundary_valid(lower
, INT_MAX
, "length restriction value");
2716 if (lower
->get_valuetype()!=Value::V_INT
) return false;
2717 return set_ttcn_length(size_limit_t((size_t)lower
->get_val_Int()->get_val()),
2718 size_limit_t((size_t)lower
->get_val_Int()->get_val()));
2722 bool SubType::add_ttcn_pattern(Ttcn::PatternString
* pattern
, size_t restriction_index
)
2724 pattern
->set_my_scope(my_owner
->get_my_scope());
2725 pattern
->set_fullname(my_owner
->get_fullname()+".<pattern_restriction_"+Int2string(restriction_index
) + ">");
2727 case ST_CHARSTRING
: {
2728 Error_Context
cntxt(my_owner
, "In character string pattern");
2729 pattern
->chk_refs(Type::EXPECTED_CONSTANT
);
2730 pattern
->join_strings();
2731 if (!pattern
->has_refs()) { // if chk_refs didn't remove all references then ignore
2732 pattern
->chk_pattern();
2733 CharstringSubtypeTreeElement
* cst_elem
= new CharstringSubtypeTreeElement(StringPatternConstraint(pattern
));
2734 if (charstring_st
==NULL
) {
2735 charstring_st
= cst_elem
;
2737 charstring_st
= new CharstringSubtypeTreeElement(CharstringSubtypeTreeElement::ET_INTERSECTION
, charstring_st
, cst_elem
);
2741 case ST_UNIVERSAL_CHARSTRING
: {
2742 Error_Context
cntxt(my_owner
, "In universal string pattern");
2743 pattern
->set_pattern_type(Ttcn::PatternString::USTR_PATTERN
);
2744 pattern
->chk_refs(Type::EXPECTED_CONSTANT
);
2745 pattern
->join_strings();
2746 if (!pattern
->has_refs()) { // if chk_refs didn't remove all references then ignore
2747 pattern
->chk_pattern();
2748 UniversalCharstringSubtypeTreeElement
* ucst_elem
= new UniversalCharstringSubtypeTreeElement(StringPatternConstraint(pattern
));
2749 if (universal_charstring_st
==NULL
) {
2750 universal_charstring_st
= ucst_elem
;
2752 universal_charstring_st
= new UniversalCharstringSubtypeTreeElement(UniversalCharstringSubtypeTreeElement::ET_INTERSECTION
, universal_charstring_st
, ucst_elem
);
2757 my_owner
->error("Pattern subtyping of type `%s' is not allowed", my_owner
->get_typename().c_str());
2763 void SubType::print_full_warning() const
2765 my_owner
->warning("The subtype of type `%s' is a full set, "
2766 "it does not constrain the root type.", my_owner
->get_typename().c_str());
2771 if ((checked
!=STC_NO
) || (subtype
==ST_ERROR
)) FATAL_ERROR("SubType::chk()");
2772 checked
= STC_CHECKING
;
2774 // check for circular subtype reference
2775 if (parent_subtype
&& !add_parent_subtype(parent_subtype
)) {
2781 if (parsed
) { // has TTCN-3 subtype constraint
2782 size_t added_count
= 0;
2783 bool has_single
= false, has_range
= false,
2784 has_length
= false, has_pattern
= false;
2785 for (size_t i
= 0; i
< parsed
->size(); i
++) {
2787 SubTypeParse
*parse
= (*parsed
)[i
];
2788 switch (parse
->get_selection()) {
2789 case SubTypeParse::STP_SINGLE
:
2791 added
= add_ttcn_single(parse
->Single(),i
);
2793 case SubTypeParse::STP_RANGE
:
2795 added
= add_ttcn_range(parse
->Min(), parse
->MinExclusive(),
2796 parse
->Max(), parse
->MaxExclusive(), i
,
2797 has_single
|| has_length
|| has_pattern
);
2799 case SubTypeParse::STP_LENGTH
:
2801 added
= add_ttcn_length(parse
->Length(),i
);
2803 case SubTypeParse::STP_PATTERN
:
2805 added
= add_ttcn_pattern(parse
->Pattern(),i
);
2808 FATAL_ERROR("SubType::chk(): invalid SubTypeParse selection");
2810 if (added
) added_count
++;
2814 case ST_UNIVERSAL_CHARSTRING
:
2815 if (has_single
&& has_range
) {
2817 "Mixing of value list and range subtyping is not allowed for type `%s'",
2818 my_owner
->get_typename().c_str());
2825 // in other cases mixing of different restrictions (which are legal for
2826 // this type) is properly regulated by the TTCN-3 BNF itself
2829 if (added_count
<parsed
->size()) {
2834 if (subtype
==ST_ERROR
) { checked
= STC_YES
; return; }
2836 if (parent_subtype
) {
2837 if (is_subset(parent_subtype
->get_root())==TFALSE
) {
2838 my_owner
->error("The subtype restriction is not a subset of the restriction on the parent type. "
2839 "Subtype %s is not subset of subtype %s", to_string().c_str(), parent_subtype
->get_root()->to_string().c_str());
2844 intersection(parent_subtype
->get_root());
2846 } else if (asn_constraints
) { // has ASN.1 subtype constraint
2847 SubtypeConstraint
* asn_parent_subtype
= NULL
;
2848 if (parent_subtype
) {
2849 // the type constraint of the ASN.1 type is already in the parent_subtype,
2850 // don't add it multiple times
2851 asn_parent_subtype
= parent_subtype
->get_root();
2853 asn_parent_subtype
= get_asn_type_constraint(my_owner
);
2855 asn_constraints
->chk(asn_parent_subtype
);
2856 root
= asn_constraints
->get_subtype();
2857 extendable
= asn_constraints
->is_extendable();
2858 extension
= asn_constraints
->get_extension();
2859 // the TTCN-3 subtype will be the union of the root and extension parts
2860 // the ETSI ES 201 873-7 V4.1.2 (2009-07) document says to "ignore any extension markers"
2861 // but titan now works this way :)
2862 if (root
) copy(root
);
2863 if (extension
) union_(extension
);
2864 } else { // no constraints on this type -> this is an alias type, just copy the subtype from the other
2865 if (parent_subtype
) {
2866 root
= parent_subtype
->root
;
2867 extendable
= parent_subtype
->extendable
;
2868 extension
= parent_subtype
->extension
;
2869 copy(parent_subtype
);
2871 SubtypeConstraint
* asn_parent_subtype
= get_asn_type_constraint(my_owner
);
2872 if (asn_parent_subtype
) copy(asn_parent_subtype
);
2876 // check if subtype is valid: it must not be an empty set (is_empty==TTRUE)
2877 // issue warning if subtype is given but is full set (is_full==TTRUE)
2878 // ignore cases of TUNKNOWN when compiler can't figure out if the aggregate
2879 // set is empty or full
2882 if (integer_st
!=NULL
) {
2883 if (integer_st
->is_empty()==TTRUE
) goto empty_error
;
2884 if (integer_st
->is_full()==TTRUE
) {
2885 print_full_warning();
2892 if (float_st
!=NULL
) {
2893 if (float_st
->is_empty()==TTRUE
) goto empty_error
;
2894 if (float_st
->is_full()==TTRUE
) {
2895 print_full_warning();
2902 if (boolean_st
!=NULL
) {
2903 if (boolean_st
->is_empty()==TTRUE
) goto empty_error
;
2904 if (boolean_st
->is_full()==TTRUE
) {
2905 print_full_warning();
2911 case ST_VERDICTTYPE
:
2912 if (verdict_st
!=NULL
) {
2913 if (verdict_st
->is_empty()==TTRUE
) goto empty_error
;
2914 if (verdict_st
->is_full()==TTRUE
) {
2915 print_full_warning();
2922 if (bitstring_st
!=NULL
) {
2923 if (bitstring_st
->is_empty()==TTRUE
) goto empty_error
;
2924 if (bitstring_st
->is_full()==TTRUE
) {
2925 print_full_warning();
2926 delete bitstring_st
;
2927 bitstring_st
= NULL
;
2932 if (hexstring_st
!=NULL
) {
2933 if (hexstring_st
->is_empty()==TTRUE
) goto empty_error
;
2934 if (hexstring_st
->is_full()==TTRUE
) {
2935 print_full_warning();
2936 delete hexstring_st
;
2937 hexstring_st
= NULL
;
2941 case ST_OCTETSTRING
:
2942 if (octetstring_st
!=NULL
) {
2943 if (octetstring_st
->is_empty()==TTRUE
) goto empty_error
;
2944 if (octetstring_st
->is_full()==TTRUE
) {
2945 print_full_warning();
2946 delete octetstring_st
;
2947 octetstring_st
= NULL
;
2952 if (charstring_st
!=NULL
) {
2953 if (charstring_st
->is_empty()==TTRUE
) goto empty_error
;
2954 if (charstring_st
->is_full()==TTRUE
) {
2955 print_full_warning();
2956 delete charstring_st
;
2957 charstring_st
= NULL
;
2961 case ST_UNIVERSAL_CHARSTRING
:
2962 if (universal_charstring_st
!=NULL
) {
2963 if (universal_charstring_st
->is_empty()==TTRUE
) goto empty_error
;
2964 if (universal_charstring_st
->is_full()==TTRUE
) {
2965 print_full_warning();
2966 delete universal_charstring_st
;
2967 universal_charstring_st
= NULL
;
2979 if (value_st
!=NULL
) {
2980 if (value_st
->is_empty()==TTRUE
) goto empty_error
;
2981 if (value_st
->is_full()==TTRUE
) {
2982 print_full_warning();
2990 if (recof_st
!=NULL
) {
2991 if (recof_st
->is_empty()==TTRUE
) goto empty_error
;
2992 if (recof_st
->is_full()==TTRUE
) {
2993 print_full_warning();
3000 FATAL_ERROR("SubType::chk()");
3002 if ((length_restriction
!=NULL
) && (length_restriction
->is_full()==TTRUE
)) {
3003 delete length_restriction
;
3004 length_restriction
= NULL
;
3010 my_owner
->error("The subtype is an empty set");
3016 void SubType::dump(unsigned level
) const
3018 string str
= to_string();
3019 if (str
.size()>0) DEBUG(level
, "restriction(s): %s", str
.c_str());
3022 Int
SubType::get_length_restriction() const
3024 if (checked
!=STC_YES
) FATAL_ERROR("SubType::get_length_restriction()");
3025 if (parsed
==NULL
) return -1; // only own length restriction counts
3026 if (length_restriction
==NULL
) return -1;
3027 if (length_restriction
->is_empty()) return -1;
3028 return ( (length_restriction
->get_minimal()==length_restriction
->get_maximal()) ?
3029 (Int
)(length_restriction
->get_minimal().get_size()) :
3033 bool SubType::zero_length_allowed() const
3035 if (checked
!=STC_YES
) FATAL_ERROR("SubType::zero_length_allowed()");
3036 if (parsed
==NULL
) return true; // only own length restriction counts
3037 if (length_restriction
==NULL
) return true;
3038 return length_restriction
->is_element(size_limit_t(0));
3041 string
SubType::to_string() const
3044 string
ret_val(root
->to_string());
3045 if (extendable
) ret_val
+= ", ...";
3048 ret_val
+= extension
->to_string();
3052 return SubtypeConstraint::to_string();
3055 ////////////////////////////////////////////////////////////////////////////////
3057 void SubType::generate_code(output_struct
&)
3059 if (checked
!=STC_YES
) FATAL_ERROR("SubType::generate_code()");
3062 void SubType::generate_json_schema(JSON_Tokenizer
& json
,
3063 bool allow_special_float
/* = true */)
3065 bool has_value_list
= false;
3066 size_t nof_ranges
= 0;
3067 for (size_t i
= 0; i
< parsed
->size(); ++i
) {
3068 SubTypeParse
*parse
= (*parsed
)[i
];
3069 switch (parse
->get_selection()) {
3070 case SubTypeParse::STP_SINGLE
:
3071 // single values will be added later, all at once
3072 has_value_list
= true;
3074 case SubTypeParse::STP_RANGE
:
3077 case SubTypeParse::STP_LENGTH
: {
3078 Ttcn::LengthRestriction
* len_res
= parse
->Length();
3079 Value
* min_val
= len_res
->get_is_range() ? len_res
->get_lower_value() :
3080 len_res
->get_single_value();
3081 Value
* max_val
= len_res
->get_is_range() ? len_res
->get_upper_value() :
3082 len_res
->get_single_value();
3083 const char* json_min
= NULL
;
3084 const char* json_max
= NULL
;
3088 // use minItems and maxItems for record of/set of
3089 json_min
= "minItems";
3090 json_max
= "maxItems";
3094 case ST_OCTETSTRING
:
3096 case ST_UNIVERSAL_CHARSTRING
:
3097 // use minLength and maxLength for string types
3098 json_min
= "minLength";
3099 json_max
= "maxLength";
3102 FATAL_ERROR("SubType::generate_json_schema - length %d", subtype
);
3104 json
.put_next_token(JSON_TOKEN_NAME
, json_min
);
3105 min_val
->generate_json_value(json
);
3106 if (max_val
!= NULL
) {
3107 json
.put_next_token(JSON_TOKEN_NAME
, json_max
);
3108 max_val
->generate_json_value(json
);
3111 case SubTypeParse::STP_PATTERN
: {
3112 json
.put_next_token(JSON_TOKEN_NAME
, "pattern");
3113 char* json_pattern
= parse
->Pattern()->convert_to_json();
3114 json
.put_next_token(JSON_TOKEN_STRING
, json_pattern
);
3122 bool need_anyOf
= (subtype
== ST_INTEGER
|| subtype
== ST_FLOAT
) &&
3123 (nof_ranges
+ (has_value_list
? 1 : 0) > 1);
3125 // there are multiple value range/value list restrictions,
3126 // they need to be grouped in an 'anyOf' structure
3127 json
.put_next_token(JSON_TOKEN_NAME
, "anyOf");
3128 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
3129 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
3131 if (has_value_list
) {
3132 // generate the value list into an enum
3133 json
.put_next_token(JSON_TOKEN_NAME
, "enum");
3134 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
3135 generate_json_schema_value_list(json
, allow_special_float
, false);
3136 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
3137 if (my_owner
->has_as_value_union()) {
3138 // the original value list cannot always be recreated from the generated
3139 // JSON value list in case of "as value" unions (because there are no field
3141 // the list needs to be regenerated with field names (as if it was a regular
3142 // union) under a new keyword (valueList)
3143 json
.put_next_token(JSON_TOKEN_NAME
, "valueList");
3144 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
3145 generate_json_schema_value_list(json
, allow_special_float
, true);
3146 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
3149 if (need_anyOf
&& has_value_list
) {
3150 // end of the value list and beginning of the first value range
3151 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
3152 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
3154 if (nof_ranges
> 0) {
3158 generate_json_schema_number_ranges(json
);
3161 case ST_UNIVERSAL_CHARSTRING
: {
3162 // merge all string range restrictions into one JSON schema pattern
3163 char* pattern_str
= mcopystrn("\"^[", 3);
3164 pattern_str
= generate_json_schema_string_ranges(pattern_str
);
3165 pattern_str
= mputstrn(pattern_str
, "]*$\"", 4);
3166 json
.put_next_token(JSON_TOKEN_NAME
, "pattern");
3167 json
.put_next_token(JSON_TOKEN_STRING
, pattern_str
);
3171 FATAL_ERROR("SubType::generate_json_schema - range %d", subtype
);
3175 // end of the 'anyOf' structure
3176 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
3177 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
3181 void SubType::generate_json_schema_value_list(JSON_Tokenizer
& json
,
3182 bool allow_special_float
,
3183 bool union_value_list
)
3185 for (size_t i
= 0; i
< parsed
->size(); ++i
) {
3186 SubTypeParse
*parse
= (*parsed
)[i
];
3187 if (parse
->get_selection() == SubTypeParse::STP_SINGLE
) {
3188 if (parse
->Single()->get_valuetype() == Value::V_REFD
) {
3189 Common::Assignment
* ass
= parse
->Single()->get_reference()->get_refd_assignment();
3190 if (ass
->get_asstype() == Common::Assignment::A_TYPE
) {
3191 // it's a reference to another subtype, insert its value list here
3192 ass
->get_Type()->get_sub_type()->generate_json_schema_value_list(json
,
3193 allow_special_float
, union_value_list
);
3197 Ttcn::JsonOmitCombination
omit_combo(parse
->Single());
3199 parse
->Single()->generate_json_value(json
, allow_special_float
,
3200 union_value_list
, &omit_combo
);
3201 } // only generate the first combination for the unions' "valueList" keyword
3202 while (!union_value_list
&& omit_combo
.next());
3208 bool SubType::generate_json_schema_number_ranges(JSON_Tokenizer
& json
, bool first
/* = true */)
3210 for (size_t i
= 0; i
< parsed
->size(); ++i
) {
3211 SubTypeParse
*parse
= (*parsed
)[i
];
3212 if (parse
->get_selection() == SubTypeParse::STP_SINGLE
) {
3213 if (parse
->Single()->get_valuetype() == Value::V_REFD
) {
3214 Common::Assignment
* ass
= parse
->Single()->get_reference()->get_refd_assignment();
3215 if (ass
->get_asstype() == Common::Assignment::A_TYPE
) {
3216 // it's a reference to another subtype, insert its value ranges here
3217 first
= ass
->get_Type()->get_sub_type()->generate_json_schema_number_ranges(json
, first
);
3221 else if (parse
->get_selection() == SubTypeParse::STP_RANGE
) {
3223 // the ranges are in an 'anyOf' structure, they need to be placed in an object
3224 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
3225 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
3230 // add the minimum and/or maximum values as numbers
3231 if (parse
->Min() != NULL
) {
3232 json
.put_next_token(JSON_TOKEN_NAME
, "minimum");
3233 parse
->Min()->generate_json_value(json
);
3234 json
.put_next_token(JSON_TOKEN_NAME
, "exclusiveMinimum");
3235 json
.put_next_token(parse
->MinExclusive() ? JSON_TOKEN_LITERAL_TRUE
: JSON_TOKEN_LITERAL_FALSE
);
3237 if (parse
->Max() != NULL
) {
3238 json
.put_next_token(JSON_TOKEN_NAME
, "maximum");
3239 parse
->Max()->generate_json_value(json
);
3240 json
.put_next_token(JSON_TOKEN_NAME
, "exclusiveMaximum");
3241 json
.put_next_token(parse
->MaxExclusive() ? JSON_TOKEN_LITERAL_TRUE
: JSON_TOKEN_LITERAL_FALSE
);
3248 char* SubType::generate_json_schema_string_ranges(char* pattern_str
)
3250 for (size_t i
= 0; i
< parsed
->size(); ++i
) {
3251 SubTypeParse
*parse
= (*parsed
)[i
];
3252 if (parse
->get_selection() == SubTypeParse::STP_SINGLE
) {
3253 if (parse
->Single()->get_valuetype() == Value::V_REFD
) {
3254 Common::Assignment
* ass
= parse
->Single()->get_reference()->get_refd_assignment();
3255 if (ass
->get_asstype() == Common::Assignment::A_TYPE
) {
3256 // it's a reference to another subtype, insert its string ranges here
3257 pattern_str
= ass
->get_Type()->get_sub_type()->generate_json_schema_string_ranges(pattern_str
);
3261 else if (parse
->get_selection() == SubTypeParse::STP_RANGE
) {
3262 // insert the string range into the pattern string
3263 string lower_str
= (subtype
== ST_CHARSTRING
) ? parse
->Min()->get_val_str() :
3264 ustring_to_uft8(parse
->Min()->get_val_ustr());
3265 string upper_str
= (subtype
== ST_CHARSTRING
) ? parse
->Max()->get_val_str() :
3266 ustring_to_uft8(parse
->Max()->get_val_ustr());
3267 pattern_str
= mputprintf(pattern_str
, "%s-%s", lower_str
.c_str(), upper_str
.c_str());
3273 void SubType::generate_json_schema_float(JSON_Tokenizer
& json
)
3275 bool has_nan
= float_st
->is_element(make_ttcn3float(REAL_NAN
));
3276 bool has_pos_inf
= float_st
->is_element(make_ttcn3float(REAL_INFINITY
));
3277 bool has_neg_inf
= float_st
->is_element(make_ttcn3float(-REAL_INFINITY
));
3278 bool has_special
= has_nan
|| has_pos_inf
|| has_neg_inf
;
3279 bool has_number
= false;
3280 for (size_t i
= 0; i
< parsed
->size() && !has_number
; ++i
) {
3281 // go through the restrictions and check if at least one number is allowed
3282 SubTypeParse
*parse
= (*parsed
)[i
];
3283 switch (parse
->get_selection()) {
3284 case SubTypeParse::STP_SINGLE
: {
3285 Real r
= parse
->Single()->get_val_Real();
3286 if (r
== r
&& r
!= REAL_INFINITY
&& r
!= -REAL_INFINITY
) {
3287 // a single value other than NaN, INF and -INF is a number
3291 case SubTypeParse::STP_RANGE
: {
3292 if (parse
->Min() != NULL
) {
3293 if (parse
->Min()->get_val_Real() != REAL_INFINITY
) {
3294 // a minimum value other than INF means a number is allowed
3298 if (parse
->Max() != NULL
) {
3299 // a maximum value other than -INF means a number is allowed
3300 if (parse
->Max()->get_val_Real() != -REAL_INFINITY
) {
3309 if (has_number
&& has_special
) {
3310 json
.put_next_token(JSON_TOKEN_NAME
, "anyOf");
3311 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
3312 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
3315 json
.put_next_token(JSON_TOKEN_NAME
, "type");
3316 json
.put_next_token(JSON_TOKEN_STRING
, "\"number\"");
3317 // generate the restrictions' schema elements here
3318 // (the 2nd parameter makes sure that NaN, INF and -INF are ignored)
3319 generate_json_schema(json
, false);
3321 if (has_number
&& has_special
) {
3322 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
3323 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
3326 json
.put_next_token(JSON_TOKEN_NAME
, "enum");
3327 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
3329 json
.put_next_token(JSON_TOKEN_STRING
, "\"not_a_number\"");
3332 json
.put_next_token(JSON_TOKEN_STRING
, "\"infinity\"");
3335 json
.put_next_token(JSON_TOKEN_STRING
, "\"-infinity\"");
3337 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
3339 if (has_number
&& has_special
) {
3340 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
3341 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
3345 } // namespace Common