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