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
17 * Szabo, Janos Zoltan – initial implementation
19 ******************************************************************************/
20 #include "Constraint.hh"
21 #include "CompilerError.hh"
26 #include "Identifier.hh"
27 #include "CompField.hh"
28 #include "asn1/Block.hh"
29 #include "asn1/TokenBuf.hh"
33 // =================================
35 // =================================
37 Constraints::Constraints(const Constraints
& p
)
38 : Node(p
), cons(), my_type(0), subtype(0), extendable(false), extension(0)
40 size_t nof_cons
= p
.cons
.size();
41 for (size_t i
= 0; i
< nof_cons
; i
++) cons
.add(p
.cons
[i
]->clone());
44 Constraints::~Constraints()
46 size_t nof_cons
= cons
.size();
47 for (size_t i
= 0; i
< nof_cons
; i
++) delete cons
[i
];
53 Constraints
*Constraints::clone() const
55 return new Constraints(*this);
58 void Constraints::add_con(Constraint
*p_con
)
60 if (!p_con
) FATAL_ERROR("Constraints::add_con()");
62 if (my_type
) p_con
->set_my_type(my_type
);
65 Constraint
* Constraints::get_tableconstraint() const
67 size_t nof_cons
= cons
.size();
68 for (size_t i
= 0; i
< nof_cons
; i
++) {
69 Constraint
*con
= cons
[i
];
70 if (con
->get_constrtype() == Constraint::CT_TABLE
) return con
;
75 void Constraints::set_my_type(Type
*p_my_type
)
78 size_t nof_cons
= cons
.size();
79 for (size_t i
= 0; i
< nof_cons
; i
++) cons
[i
]->set_my_type(p_my_type
);
82 void Constraints::chk_table()
84 if(!my_type
) FATAL_ERROR("Constraints::chk_table()");
85 size_t nof_cons
= cons
.size();
86 for (size_t i
= 0; i
< nof_cons
; i
++) {
87 Error_Context
cntxt(my_type
, "In constraint #%lu of type `%s'",
88 (unsigned long) (i
+ 1), my_type
->get_typename().c_str());
89 Constraint::constrtype_t cst
= cons
[i
]->get_constrtype();
90 if (cst
==Constraint::CT_TABLE
) cons
[i
]->chk();
94 void Constraints::chk(SubtypeConstraint
* parent_subtype
)
96 if(!my_type
) FATAL_ERROR("Common::Constraints::chk()");
98 subtype
= new SubtypeConstraint(my_type
->get_subtype_type());
99 subtype
->copy(parent_subtype
);
101 size_t nof_cons
= cons
.size();
102 for (size_t i
= 0; i
< nof_cons
; i
++) {
103 Error_Context
cntxt(my_type
, "In constraint #%lu of type `%s'",
104 (unsigned long) (i
+ 1), my_type
->get_typename().c_str());
105 cons
[i
]->set_fullname(my_type
->get_fullname()+".<constraint_"+Int2string(i
+1)+">.<"+string(cons
[i
]->get_name())+">");
106 cons
[i
]->set_my_cons(this);
107 Constraint::constrtype_t cst
= cons
[i
]->get_constrtype();
108 if (cst
!=Constraint::CT_TABLE
) cons
[i
]->chk();
109 if ( (cst
==Constraint::CT_IGNORE
) || (cst
==Constraint::CT_TABLE
) ) continue; // ignore
110 SubtypeConstraint
* sc
= cons
[i
]->get_subtype();
111 SubtypeConstraint
* sc_ext
= cons
[i
]->get_extension();
112 if (!sc
) break; // stop on error
113 extendable
= cons
[i
]->is_extendable();
114 if (extension
) { // only the root part shall be kept
119 if (sc
->is_subset(subtype
)==TFALSE
) {
120 cons
[i
]->error("Constraint #%lu is %s, this is not a subset of %s",
121 (unsigned long) (i
+ 1),
122 sc
->to_string().c_str(),
123 subtype
->to_string().c_str());
124 break; // stop on error
126 if (sc_ext
&& (sc_ext
->is_subset(subtype
)==TFALSE
)) {
127 cons
[i
]->error("Extension addition of constraint #%lu is %s, this is not a subset of %s",
128 (unsigned long) (i
+ 1),
129 sc_ext
->to_string().c_str(),
130 subtype
->to_string().c_str());
131 break; // stop on error
134 extension
= new SubtypeConstraint(my_type
->get_subtype_type());
135 extension
->copy(sc_ext
);
136 extension
->intersection(subtype
);
138 subtype
->intersection(sc
);
140 subtype
= new SubtypeConstraint(my_type
->get_subtype_type());
143 extension
= new SubtypeConstraint(my_type
->get_subtype_type());
144 extension
->copy(sc_ext
);
150 // =================================
152 // =================================
154 Constraint::Constraint(const Constraint
& p
):
155 Node(p
), Location(p
), constrtype(p
.constrtype
),
156 my_type(0), my_scope(0), my_parent(0), my_cons(0),
157 checked(false), subtype(0), extendable(false), extension(0)
161 Constraint::Constraint(constrtype_t p_constrtype
):
162 Node(), Location(), constrtype(p_constrtype
),
163 my_type(0), my_scope(0), my_parent(0), my_cons(0),
164 checked(false), subtype(0), extendable(false), extension(0)
168 Constraint::~Constraint()
174 Scope
* Constraint::get_my_scope()
176 if (!my_type
) FATAL_ERROR("Constraint::get_my_scope()");
177 return my_scope
? my_scope
: my_type
->get_my_scope();
180 void Constraint::set_my_cons(Constraints
* p_my_cons
)
185 Constraints
* Constraint::get_my_cons()
187 Constraint
* c
= this;
189 if (c
->my_cons
) return c
->my_cons
;
192 FATAL_ERROR("Constraint::get_my_cons()");
196 bool Constraint::in_char_context() const
198 Constraint
* parent
= my_parent
;
200 if (parent
->get_constrtype()==CT_PERMITTEDALPHABET
) return true;
201 parent
= parent
->get_my_parent();
206 bool Constraint::in_inner_constraint() const
208 Constraint
* parent
= my_parent
;
210 switch (parent
->get_constrtype()) {
211 case CT_SINGLEINNERTYPE
:
212 case CT_MULTIPLEINNERTYPE
:
217 parent
= parent
->get_my_parent();
222 // =================================
223 // ===== ElementSetSpecsConstraint
224 // =================================
226 ElementSetSpecsConstraint::ElementSetSpecsConstraint(const ElementSetSpecsConstraint
& p
)
230 root_constr
= p
.root_constr
? p
.root_constr
->clone() : 0;
231 ext_constr
= p
.ext_constr
? p
.ext_constr
->clone() : 0;
234 ElementSetSpecsConstraint::ElementSetSpecsConstraint(Constraint
* p_root_constr
, Constraint
* p_ext_constr
)
235 : Constraint(CT_ELEMENTSETSPEC
), root_constr(p_root_constr
), ext_constr(p_ext_constr
)
237 if (!p_root_constr
) FATAL_ERROR("ElementSetSpecsConstraint::ElementSetSpecsConstraint()");
238 // p_ext_constr can be NULL
242 ElementSetSpecsConstraint::~ElementSetSpecsConstraint()
248 void ElementSetSpecsConstraint::chk()
252 if (!root_constr
|| !my_type
) FATAL_ERROR("ElementSetSpecsConstraint::chk()");
253 Error_Context
cntxt(this, "While checking ElementSetSpecs constraint");
254 root_constr
->set_my_type(my_type
);
255 if (ext_constr
) ext_constr
->set_my_type(my_type
);
256 root_constr
->set_my_scope(get_my_scope());
257 if (ext_constr
) ext_constr
->set_my_scope(get_my_scope());
258 root_constr
->set_my_parent(this);
259 if (ext_constr
) ext_constr
->set_my_parent(this);
261 if (ext_constr
) ext_constr
->chk();
262 SubtypeConstraint::subtype_t my_subtype_type
= my_type
->get_subtype_type();
263 // naming ((r1,x1),...,(r2,x2)) according to X.680(11/2008) I.4.3.8
264 SubtypeConstraint
* r1
= root_constr
->get_subtype();
265 if (!r1
) return; // root_constr is invalid, error already reported there
266 SubtypeConstraint
* x1
= root_constr
->get_extension();
268 // only root part exists
269 subtype
= new SubtypeConstraint(my_subtype_type
);
272 extension
= new SubtypeConstraint(my_subtype_type
);
277 SubtypeConstraint
* r2
= ext_constr
->get_subtype();
278 if (!r2
) return; // ext_constr is invalid, error already reported there
279 SubtypeConstraint
* x2
= ext_constr
->get_extension();
280 subtype
= new SubtypeConstraint(my_subtype_type
);
282 extension
= new SubtypeConstraint(my_subtype_type
);
284 if (x1
) extension
->union_(x1
);
285 if (x2
) extension
->union_(x2
);
286 extension
->except(r1
);
289 void ElementSetSpecsConstraint::set_fullname(const string
& p_fullname
)
291 Node::set_fullname(p_fullname
);
292 root_constr
->set_fullname(p_fullname
+".<root_part>.<"+string(root_constr
->get_name())+">");
294 ext_constr
->set_fullname(p_fullname
+".<extension_part>.<"+string(ext_constr
->get_name())+">");
297 // =================================
298 // ===== IgnoredConstraint
299 // =================================
301 IgnoredConstraint::IgnoredConstraint(const IgnoredConstraint
& p
)
302 : Constraint(p
), my_name(p
.my_name
)
306 IgnoredConstraint::IgnoredConstraint(const char* p_name
)
307 : Constraint(CT_IGNORE
), my_name(p_name
)
309 if (p_name
==NULL
) FATAL_ERROR("IgnoredConstraint::IgnoredConstraint()");
312 void IgnoredConstraint::chk()
316 if (!my_type
) FATAL_ERROR("IgnoredConstraint::chk()");
317 if (in_char_context()) {
318 error("%s not allowed inside a permitted alphabet constraint", get_name());
321 if (my_parent
) warning("%s inside a %s is treated as `ALL' (constraint is dropped)", get_name(), my_parent
->get_name());
322 //else warning("%s is ignored", get_name());
324 // ignored constraint does not constrain the type, set to full set
325 subtype
= new SubtypeConstraint(my_type
->get_subtype_type());
328 // =================================
329 // ===== SingleValueConstraint
330 // =================================
332 SingleValueConstraint::SingleValueConstraint(const SingleValueConstraint
& p
)
335 value
= p
.value
? p
.value
->clone() : 0;
338 SingleValueConstraint::~SingleValueConstraint()
343 SingleValueConstraint::SingleValueConstraint(Value
* p_value
)
344 : Constraint(CT_SINGLEVALUE
), value(p_value
)
346 if (!p_value
) FATAL_ERROR("SingleValueConstraint::SingleValueConstraint()");
349 void SingleValueConstraint::chk()
353 if (!value
|| !my_type
) FATAL_ERROR("SingleValueConstraint::chk()");
354 Error_Context
cntxt(this, "While checking single value constraint");
355 value
->set_my_scope(get_my_scope());
356 value
->set_my_governor(my_type
);
357 my_type
->chk_this_value_ref(value
);
358 my_type
->chk_this_value(value
, 0, Type::EXPECTED_CONSTANT
,
359 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
360 if (in_char_context()) {
361 subtype
= SubtypeConstraint::create_from_asn_charvalues(my_type
, value
);
363 subtype
= SubtypeConstraint::create_from_asn_value(my_type
, value
);
367 void SingleValueConstraint::set_fullname(const string
& p_fullname
)
369 Node::set_fullname(p_fullname
);
370 value
->set_fullname(p_fullname
+".<value>");
373 // =================================
374 // ===== ContainedSubtypeConstraint
375 // =================================
377 ContainedSubtypeConstraint::ContainedSubtypeConstraint(const ContainedSubtypeConstraint
& p
)
380 type
= p
.type
? p
.type
->clone() : 0;
383 ContainedSubtypeConstraint::~ContainedSubtypeConstraint()
388 ContainedSubtypeConstraint::ContainedSubtypeConstraint(Type
* p_type
, bool p_has_includes
)
389 : Constraint(CT_CONTAINEDSUBTYPE
), type(p_type
), has_includes(p_has_includes
)
391 if (!p_type
) FATAL_ERROR("ContainedSubtypeConstraint::ContainedSubtypeConstraint()");
394 void ContainedSubtypeConstraint::chk()
398 if (!type
|| !my_type
) FATAL_ERROR("ContainedSubtypeConstraint::chk()");
399 Error_Context
cntxt(this, "While checking contained subtype constraint");
401 type
->set_my_scope(get_my_scope());
403 if (type
->get_typetype()==Type::T_ERROR
) return;
405 if (my_type
->get_type_refd_last()->get_typetype()==Type::T_OPENTYPE
) {
406 // TODO: open type and anytype should have their own ST_ANY subtype, now this is only ignored
407 subtype
= new SubtypeConstraint(my_type
->get_subtype_type());
411 if (!type
->is_identical(my_type
)) {
412 error("Contained subtype constraint is invalid, constrained and constraining types have different root type");
415 // check subtype of referenced type
416 SubType
* t_st
= type
->get_sub_type();
418 error("Contained subtype constraint is invalid, the constraining type has no subtype constraint");
422 // check circular subtype reference
423 Type
* my_owner
= get_my_cons()->get_my_type();
424 if (!my_owner
|| !my_owner
->get_sub_type()) FATAL_ERROR("ContainedSubtypeConstraint::chk()");
425 if (!my_owner
->get_sub_type()->add_parent_subtype(t_st
)) return;
427 if (t_st
->get_subtypetype()==SubtypeConstraint::ST_ERROR
) return;
428 if (t_st
->get_subtypetype()!=my_type
->get_subtype_type()) FATAL_ERROR("ContainedSubtypeConstraint::chk()");
430 subtype
= SubtypeConstraint::create_from_contained_subtype(t_st
->get_root(), in_char_context(), this);
433 void ContainedSubtypeConstraint::set_fullname(const string
& p_fullname
)
435 Node::set_fullname(p_fullname
);
436 type
->set_fullname(p_fullname
+".<type>");
439 // =================================
440 // ===== RangeEndpoint
441 // =================================
443 RangeEndpoint::RangeEndpoint(const RangeEndpoint
& p
):
444 Node(p
), Location(p
), type(p
.type
), inclusive(p
.inclusive
)
446 value
= p
.value
? p
.value
->clone() : 0;
449 RangeEndpoint::~RangeEndpoint()
454 RangeEndpoint::RangeEndpoint(endpoint_t p_type
):
455 Node(), Location(), type(p_type
), value(0), inclusive(true)
457 if (type
==VALUE
) FATAL_ERROR("RangeEndpoint::RangeEndpoint()");
460 RangeEndpoint::RangeEndpoint(Value
* p_value
):
461 Node(), Location(), type(RangeEndpoint::VALUE
), value(p_value
), inclusive(true)
463 if (!p_value
) FATAL_ERROR("RangeEndpoint::RangeEndpoint()");
466 void RangeEndpoint::chk(Type
* my_type
, ValueRangeConstraint
* constraint
)
469 value
->set_my_scope(constraint
->get_my_scope());
470 my_type
->chk_this_value_ref(value
);
471 my_type
->chk_this_value(value
, 0, Type::EXPECTED_CONSTANT
,
472 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
476 void RangeEndpoint::set_fullname(const string
& p_fullname
)
478 Node::set_fullname(p_fullname
);
479 if (value
) value
->set_fullname(p_fullname
+".<value>");
482 // =================================
483 // ===== ValueRangeConstraint
484 // =================================
486 ValueRangeConstraint::ValueRangeConstraint(const ValueRangeConstraint
& p
)
489 lower_endpoint
= p
.lower_endpoint
? p
.lower_endpoint
->clone() : 0;
490 upper_endpoint
= p
.upper_endpoint
? p
.upper_endpoint
->clone() : 0;
493 ValueRangeConstraint::ValueRangeConstraint(RangeEndpoint
* p_lower
, RangeEndpoint
* p_upper
)
494 : Constraint(CT_VALUERANGE
), lower_endpoint(p_lower
), upper_endpoint(p_upper
)
496 if (!p_lower
|| !p_upper
) FATAL_ERROR("ValueRangeConstraint::ValueRangeConstraint()");
499 void ValueRangeConstraint::chk()
503 if (!lower_endpoint
|| !upper_endpoint
|| !my_type
) FATAL_ERROR("ValueRangeConstraint::chk()");
504 Error_Context
cntxt(this, "While checking value range constraint");
505 SubtypeConstraint::subtype_t my_subtype_type
= my_type
->get_subtype_type();
506 switch (my_subtype_type
) {
507 case SubtypeConstraint::ST_INTEGER
:
508 case SubtypeConstraint::ST_FLOAT
:
510 case SubtypeConstraint::ST_CHARSTRING
:
511 switch (my_type
->get_type_refd_last()->get_typetype()) {
512 case Type::T_NUMERICSTRING
:
513 case Type::T_PRINTABLESTRING
:
514 case Type::T_IA5STRING
:
515 case Type::T_VISIBLESTRING
:
516 if (!in_char_context()) {
517 error("Value range constraint must be inside a permitted alphabet or size constraint");
522 error("Value range constraint is not allowed for type `%s'", my_type
->get_typename().c_str());
526 case SubtypeConstraint::ST_UNIVERSAL_CHARSTRING
:
527 switch (my_type
->get_type_refd_last()->get_typetype()) {
528 case Type::T_UTF8STRING
:
529 case Type::T_UNIVERSALSTRING
:
530 case Type::T_BMPSTRING
:
531 if (!in_char_context()) {
532 error("Value range constraint must be inside a permitted alphabet or size constraint");
537 error("Value range constraint is not allowed for type `%s'", my_type
->get_typename().c_str());
542 error("Value range constraint is not allowed for type `%s'", my_type
->get_typename().c_str());
545 lower_endpoint
->chk(my_type
, this);
546 upper_endpoint
->chk(my_type
, this);
547 Value
* vmin
= lower_endpoint
->get_value();
548 if (vmin
) vmin
= vmin
->get_value_refd_last();
549 Value
* vmax
= upper_endpoint
->get_value();
550 if (vmax
) vmax
= vmax
->get_value_refd_last();
551 // the subtype of the Constraints object at the time of calling this chk()
552 // function is constructed from all the previously calculated constraints
553 // (it is not yet the final subtype). This is needed to calculate the
554 // current MIN and MAX values.
555 SubtypeConstraint
* parent_subtype
= get_my_cons()->get_subtype();
556 subtype
= SubtypeConstraint::create_from_asn_range(
557 vmin
, lower_endpoint
->get_exclusive(),
558 vmax
, upper_endpoint
->get_exclusive(),
559 this, my_subtype_type
,
560 in_inner_constraint() ? NULL
/*the parent is invalid for an inner field*/ : parent_subtype
);
563 void ValueRangeConstraint::set_fullname(const string
& p_fullname
)
565 Node::set_fullname(p_fullname
);
566 lower_endpoint
->set_fullname(p_fullname
+".<lower_endpoint>");
567 upper_endpoint
->set_fullname(p_fullname
+".<upper_endpoint>");
570 // =================================
571 // ===== SizeConstraint
572 // =================================
574 SizeConstraint::SizeConstraint(const SizeConstraint
& p
)
577 constraint
= p
.constraint
? p
.constraint
->clone() : 0;
580 SizeConstraint::SizeConstraint(Constraint
* p
)
581 : Constraint(CT_SIZE
), constraint(p
)
583 if (!p
) FATAL_ERROR("SizeConstraint::SizeConstraint()");
586 void SizeConstraint::chk()
590 if (!constraint
|| !my_type
) FATAL_ERROR("SizeConstraint::chk()");
591 Error_Context
cntxt(this, "While checking size constraint");
592 constraint
->set_my_type(Type::get_pooltype(Type::T_INT_A
));
593 constraint
->set_my_scope(get_my_scope());
594 constraint
->set_my_parent(this);
596 subtype
= SubtypeConstraint::create_asn_size_constraint(
597 constraint
->get_subtype(), in_char_context(), my_type
, this);
598 extendable
= constraint
->is_extendable();
599 if (constraint
->get_extension()) {
600 extension
= SubtypeConstraint::create_asn_size_constraint(
601 constraint
->get_extension(), in_char_context(), my_type
, this);
605 void SizeConstraint::set_fullname(const string
& p_fullname
)
607 Node::set_fullname(p_fullname
);
608 constraint
->set_fullname(p_fullname
+".<"+string(constraint
->get_name())+">");
611 // =================================
612 // ===== PermittedAlphabetConstraint
613 // =================================
615 PermittedAlphabetConstraint::PermittedAlphabetConstraint(const PermittedAlphabetConstraint
& p
)
618 constraint
= p
.constraint
? p
.constraint
->clone() : 0;
621 PermittedAlphabetConstraint::PermittedAlphabetConstraint(Constraint
* p
)
622 : Constraint(CT_PERMITTEDALPHABET
), constraint(p
)
624 if (!p
) FATAL_ERROR("PermittedAlphabetConstraint::PermittedAlphabetConstraint()");
627 void PermittedAlphabetConstraint::chk()
631 if (!constraint
|| !my_type
) FATAL_ERROR("PermittedAlphabetConstraint::chk()");
632 Error_Context
cntxt(this, "While checking permitted alphabet constraint");
633 constraint
->set_my_type(my_type
);
634 constraint
->set_my_scope(get_my_scope());
635 constraint
->set_my_parent(this);
637 subtype
= SubtypeConstraint::create_permitted_alphabet_constraint(
638 constraint
->get_subtype(), in_char_context(), my_type
, this);
639 extendable
= constraint
->is_extendable();
640 if (constraint
->get_extension()) {
641 extension
= SubtypeConstraint::create_permitted_alphabet_constraint(
642 constraint
->get_extension(), in_char_context(), my_type
, this);
646 void PermittedAlphabetConstraint::set_fullname(const string
& p_fullname
)
648 Node::set_fullname(p_fullname
);
649 constraint
->set_fullname(p_fullname
+".<"+string(constraint
->get_name())+">");
652 // =================================
653 // ===== SetOperationConstraint
654 // =================================
656 SetOperationConstraint::SetOperationConstraint(const SetOperationConstraint
& p
)
657 : Constraint(p
), operationtype(p
.operationtype
)
659 operand_a
= p
.operand_a
? p
.operand_a
->clone() : 0;
660 operand_b
= p
.operand_b
? p
.operand_b
->clone() : 0;
663 void SetOperationConstraint::set_first_operand(Constraint
* p_a
)
665 if (operand_a
|| !p_a
) FATAL_ERROR("SetOperationConstraint::set_first_operand()");
669 SetOperationConstraint::SetOperationConstraint(Constraint
* p_a
, operationtype_t p_optype
, Constraint
* p_b
)
670 : Constraint(CT_SETOPERATION
), operationtype(p_optype
), operand_a(p_a
), operand_b(p_b
)
673 if (!p_b
) FATAL_ERROR("SetOperationConstraint::SetOperationConstraint()");
676 const char* SetOperationConstraint::get_operationtype_str() const
678 switch (operationtype
) {
682 return "intersection";
689 void SetOperationConstraint::chk()
693 if (!operand_a
|| !operand_b
|| !my_type
) FATAL_ERROR("SetOperationConstraint::chk()");
694 Error_Context
cntxt(this, "While checking %s operation", get_operationtype_str());
695 operand_a
->set_my_type(my_type
);
696 operand_b
->set_my_type(my_type
);
697 operand_a
->set_my_scope(get_my_scope());
698 operand_b
->set_my_scope(get_my_scope());
699 operand_a
->set_my_parent(this);
700 operand_b
->set_my_parent(this);
704 extendable
= (operationtype
!=EXCEPT
) ?
705 (operand_a
->is_extendable() || operand_b
->is_extendable()) :
706 operand_a
->is_extendable();
707 SubtypeConstraint::subtype_t my_subtype_type
= my_type
->get_subtype_type();
708 // naming ((r1,x1),...,(r2,x2)) according to X.680(11/2008) I.4.3.8
709 SubtypeConstraint
* r1
= operand_a
->get_subtype();
710 SubtypeConstraint
* x1
= operand_a
->get_extension();
711 SubtypeConstraint
* r2
= operand_b
->get_subtype();
712 SubtypeConstraint
* x2
= operand_b
->get_extension();
713 if (!r1
|| !r2
) return; // something invalid, error already reported there
714 subtype
= new SubtypeConstraint(my_subtype_type
);
716 switch (operationtype
) {
720 extension
= new SubtypeConstraint(my_subtype_type
);
722 extension
->copy(subtype
);
723 extension
->union_(x1
);
724 extension
->union_(x2
);
725 extension
->except(subtype
);
727 extension
->copy(x1
?x1
:x2
);
732 subtype
->intersection(r2
);
734 extension
= new SubtypeConstraint(my_subtype_type
);
737 extension
->union_(x1
);
738 SubtypeConstraint
* ext_tmp
= new SubtypeConstraint(my_subtype_type
);
741 extension
->intersection(ext_tmp
);
743 extension
->except(subtype
);
746 extension
->intersection(x1
?x1
:x2
);
753 extension
= new SubtypeConstraint(my_subtype_type
);
756 SubtypeConstraint
* ext_tmp
= new SubtypeConstraint(my_subtype_type
);
759 extension
->except(ext_tmp
);
761 extension
->except(subtype
);
764 extension
->except(r2
);
765 extension
->except(subtype
);
770 FATAL_ERROR("SetOperationConstraint::chk()");
774 void SetOperationConstraint::set_fullname(const string
& p_fullname
)
776 Node::set_fullname(p_fullname
);
777 operand_a
->set_fullname(p_fullname
+".<first_operand>.<"+string(operand_a
->get_name())+">");
778 operand_b
->set_fullname(p_fullname
+".<second_operand>.<"+string(operand_b
->get_name())+">");
781 // =================================
782 // ===== FullSetConstraint
783 // =================================
785 void FullSetConstraint::chk()
787 SubtypeConstraint::subtype_t my_subtype_type
= my_type
->get_subtype_type();
788 subtype
= new SubtypeConstraint(my_subtype_type
);
791 // =================================
792 // ===== PatternConstraint
793 // =================================
795 PatternConstraint::PatternConstraint(const PatternConstraint
& p
)
798 value
= p
.value
? p
.value
->clone() : 0;
801 PatternConstraint::~PatternConstraint()
806 PatternConstraint::PatternConstraint(Value
* p_value
)
807 : Constraint(CT_PATTERN
), value(p_value
)
809 if (!p_value
) FATAL_ERROR("PatternConstraint::PatternConstraint()");
812 void PatternConstraint::chk()
816 if (!value
|| !my_type
) FATAL_ERROR("PatternConstraint::chk()");
817 Error_Context
cntxt(this, "While checking pattern constraint");
818 switch (my_type
->get_subtype_type()) {
819 case SubtypeConstraint::ST_CHARSTRING
:
820 case SubtypeConstraint::ST_UNIVERSAL_CHARSTRING
:
823 error("Pattern constraint is not allowed for type `%s'", my_type
->get_typename().c_str());
826 value
->set_my_scope(get_my_scope());
827 value
->set_my_governor(my_type
);
828 my_type
->chk_this_value_ref(value
);
829 my_type
->chk_this_value(value
, 0, Type::EXPECTED_CONSTANT
,
830 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
831 // ignore ASN.1 pattern constraint (9.1 Transformation rules, point 4.)
832 if (in_char_context()) {
833 error("%s not allowed inside a permitted alphabet constraint", get_name());
836 if (my_parent
) warning("%s inside a %s is treated as `ALL' (constraint is dropped)",
837 get_name(), my_parent
->get_name());
838 else warning("%s is ignored", get_name());
840 subtype
= new SubtypeConstraint(my_type
->get_subtype_type());
843 void PatternConstraint::set_fullname(const string
& p_fullname
)
845 Node::set_fullname(p_fullname
);
846 value
->set_fullname(p_fullname
+".<value>");
849 // =================================
850 // ===== SingleInnerTypeConstraint
851 // =================================
853 SingleInnerTypeConstraint::SingleInnerTypeConstraint(const SingleInnerTypeConstraint
& p
)
856 constraint
= p
.constraint
? p
.constraint
->clone() : 0;
859 SingleInnerTypeConstraint::SingleInnerTypeConstraint(Constraint
* p
)
860 : Constraint(CT_SINGLEINNERTYPE
), constraint(p
)
862 if (!p
) FATAL_ERROR("SingleInnerTypeConstraint::SingleInnerTypeConstraint()");
865 void SingleInnerTypeConstraint::chk()
869 if (!constraint
|| !my_type
) FATAL_ERROR("SingleInnerTypeConstraint::chk()");
870 Error_Context
cntxt(this, "While checking inner type constraint");
871 Type
* t
= my_type
->get_type_refd_last();
873 error("Single inner type constraint (WITH COMPONENT) cannot be used on type `%s'", my_type
->get_typename().c_str());
876 Type
* field_type
= t
->get_ofType(); // determine the type of the field to which it refers
877 constraint
->set_my_type(field_type
);
878 constraint
->set_my_scope(get_my_scope());
879 constraint
->set_my_parent(this);
881 //if (constraint->get_subtype()) { // if the constraint was not erroneous
882 // TODO: this could be added to the a tree structure constraint on my_type,
883 // tree structure needed because of set operations, constraint cannot
884 // be added to field_type
886 // inner subtype is ignored ( ETSI ES 201 873-7 V4.1.2 -> 9.1 Transformation rules )
887 subtype
= new SubtypeConstraint(my_type
->get_subtype_type());
890 void SingleInnerTypeConstraint::set_fullname(const string
& p_fullname
)
892 Node::set_fullname(p_fullname
);
893 constraint
->set_fullname(p_fullname
+".<"+string(constraint
->get_name())+">");
896 // =================================
897 // ===== NamedConstraint
898 // =================================
900 NamedConstraint::NamedConstraint(Identifier
* p_id
, Constraint
* p_value_constraint
, presence_constraint_t p_presence_constraint
):
901 Constraint(CT_NAMED
), id(p_id
), value_constraint(p_value_constraint
), presence_constraint(p_presence_constraint
)
903 if (!id
) FATAL_ERROR("NamedConstraint::NamedConstraint()");
906 NamedConstraint::NamedConstraint(const NamedConstraint
& p
)
910 value_constraint
= p
.value_constraint
? p
.value_constraint
->clone() : 0;
911 presence_constraint
= p
.presence_constraint
;
914 NamedConstraint::~NamedConstraint()
917 delete value_constraint
;
920 const char* NamedConstraint::get_presence_constraint_name() const
922 switch (presence_constraint
) {
923 case PC_NONE
: return "";
924 case PC_PRESENT
: return "PRESENT";
925 case PC_ABSENT
: return "ABSENT";
926 case PC_OPTIONAL
: return "OPTIONAL";
927 default: FATAL_ERROR("NamedConstraint::get_presence_constraint_name()");
931 void NamedConstraint::chk()
935 if (!my_type
) FATAL_ERROR("NamedConstraint::chk()");
936 Error_Context
cntxt(this, "While checking named constraint");
937 if (value_constraint
) {
938 value_constraint
->set_my_type(my_type
);
939 value_constraint
->set_my_scope(get_my_scope());
940 value_constraint
->set_my_parent(this);
941 value_constraint
->chk();
943 subtype
= new SubtypeConstraint(my_type
->get_subtype_type()); // ignored
946 void NamedConstraint::set_fullname(const string
& p_fullname
)
948 Node::set_fullname(p_fullname
);
949 if (value_constraint
) {
950 value_constraint
->set_fullname(p_fullname
+".<"+string(value_constraint
->get_name())+">");
954 // =================================
955 // ===== MultipleInnerTypeConstraint
956 // =================================
958 MultipleInnerTypeConstraint::MultipleInnerTypeConstraint(const MultipleInnerTypeConstraint
& p
)
962 for (size_t i
=0; i
<p
.named_con_vec
.size(); i
++) {
963 named_con_vec
.add( p
.named_con_vec
[i
]->clone() );
967 MultipleInnerTypeConstraint::~MultipleInnerTypeConstraint()
969 named_con_map
.clear();
970 for (size_t i
=0; i
<named_con_vec
.size(); i
++) {
971 delete named_con_vec
[i
];
973 named_con_vec
.clear();
976 void MultipleInnerTypeConstraint::addNamedConstraint(NamedConstraint
* named_con
)
978 if (!named_con
) FATAL_ERROR("MultipleInnerTypeConstraint::addNamedConstraint()");
979 if (checked
) FATAL_ERROR("MultipleInnerTypeConstraint::addNamedConstraint()");
980 named_con_vec
.add(named_con
);
983 void MultipleInnerTypeConstraint::chk()
987 if (!my_type
) FATAL_ERROR("MultipleInnerTypeConstraint::chk()");
988 Type
* t
= my_type
->get_type_refd_last();
990 switch (t
->get_typetype()) {
991 case Type::T_REAL
: { // associated ASN.1 type is a SEQUENCE
992 Identifier
t_id(Identifier::ID_ASN
, string("REAL"));
993 t
= t
->get_my_scope()->get_scope_asss()->get_local_ass_byId(t_id
)->get_Type();
994 if (t
->get_typetype()!=Type::T_SEQ_A
) FATAL_ERROR("MultipleInnerTypeConstraint::chk()");
996 case Type::T_CHOICE_A
:
997 case Type::T_SEQ_A
: // T_EXTERNAL, T_EMBEDDED_PDV, T_UNRESTRICTEDSTRING
1001 FATAL_ERROR("MultipleInnerTypeConstraint::chk()");
1003 // check that all NamedConstraints refer to an existing component
1004 // if it exists add it to the map<> and check uniqueness
1005 // for SEQUENCE check order of fields
1006 size_t max_idx
= 0; // current highest field index, to detect invalid order
1007 bool invalid_order
= false;
1008 size_t present_count
= 0;
1009 size_t absent_count
= 0;
1010 for (size_t i
=0; i
<named_con_vec
.size(); i
++) {
1011 const Identifier
& id
= named_con_vec
[i
]->get_id();
1012 if (t
->has_comp_withName(id
)) {
1013 if (named_con_map
.has_key(id
)) {
1014 named_con_vec
[i
]->error("Duplicate reference to field `%s' of type `%s'",
1015 id
.get_dispname().c_str(), my_type
->get_typename().c_str());
1016 named_con_map
[id
]->note("Previous reference to field `%s' is here",
1017 id
.get_dispname().c_str());
1019 named_con_map
.add(id
, named_con_vec
[i
]);
1020 if (t
->get_typetype()==Type::T_SEQ_A
) {
1021 size_t curr_idx
= t
->get_comp_index_byName(id
);
1022 if (curr_idx
<max_idx
) invalid_order
= true;
1023 else max_idx
= curr_idx
;
1025 switch (named_con_vec
[i
]->get_presence_constraint()) {
1026 case NamedConstraint::PC_PRESENT
:
1029 case NamedConstraint::PC_ABSENT
:
1036 CompField
* cf
= t
->get_comp_byName(id
);
1037 switch (t
->get_typetype()) {
1040 if (!cf
->get_is_optional() && (named_con_vec
[i
]->get_presence_constraint()!=NamedConstraint::PC_NONE
)) {
1041 named_con_vec
[i
]->error("Presence constraint `%s' cannot be used on mandatory field `%s'",
1042 named_con_vec
[i
]->get_presence_constraint_name(), id
.get_dispname().c_str());
1048 Type
* field_type
= cf
->get_type();
1049 named_con_vec
[i
]->set_my_type(field_type
);
1050 named_con_vec
[i
]->set_my_scope(get_my_scope());
1051 named_con_vec
[i
]->set_my_parent(this);
1052 named_con_vec
[i
]->chk();
1054 named_con_vec
[i
]->error("Type `%s' does not have a field named `%s'",
1055 my_type
->get_typename().c_str(), id
.get_dispname().c_str());
1058 if (invalid_order
) {
1059 error("The order of fields must be the same as in the definition of type `%s'",
1060 my_type
->get_typename().c_str());
1062 if (t
->get_typetype()==Type::T_CHOICE_A
) {
1063 if (present_count
>1) {
1064 error("CHOICE type `%s' cannot have more than one `PRESENT' field", my_type
->get_typename().c_str());
1066 // in FullSpecification all not listed fields that can be absent are implicitly ABSENT
1067 size_t real_absent_count
= absent_count
+ ((!get_partial())?(t
->get_nof_comps()-named_con_map
.size()):0);
1068 if (real_absent_count
>=t
->get_nof_comps()) {
1069 error("All fields of CHOICE type `%s' are `ABSENT'", my_type
->get_typename().c_str());
1070 if (real_absent_count
>absent_count
) {
1071 note("%ld not listed field%s implicitly `ABSENT' because FullSpecification was used",
1072 (long)(real_absent_count
-absent_count
), ((real_absent_count
-absent_count
)>1)?"s are":" is");
1077 // inner subtype is ignored ( ETSI ES 201 873-7 V4.1.2 -> 9.1 Transformation rules )
1078 subtype
= new SubtypeConstraint(my_type
->get_subtype_type());
1081 void MultipleInnerTypeConstraint::set_fullname(const string
& p_fullname
)
1083 Node::set_fullname(p_fullname
);
1084 for (size_t i
=0; i
<named_con_vec
.size(); i
++) {
1085 named_con_vec
[i
]->set_fullname(p_fullname
+".<"+string(named_con_vec
[i
]->get_name())+" "+Int2string(i
)+">");
1089 // =================================
1090 // ===== UnparsedMultipleInnerTypeConstraint
1091 // =================================
1093 UnparsedMultipleInnerTypeConstraint::UnparsedMultipleInnerTypeConstraint(const UnparsedMultipleInnerTypeConstraint
& p
)
1096 block
= p
.block
? p
.block
->clone() : 0;
1100 UnparsedMultipleInnerTypeConstraint::UnparsedMultipleInnerTypeConstraint(Block
* p_block
)
1101 : Constraint(CT_UNPARSEDMULTIPLEINNERTYPE
), block(p_block
), constraint(0)
1103 if (!block
) FATAL_ERROR("UnparsedMultipleInnerTypeConstraint::UnparsedMultipleInnerTypeConstraint()");
1106 UnparsedMultipleInnerTypeConstraint::~UnparsedMultipleInnerTypeConstraint()
1112 void UnparsedMultipleInnerTypeConstraint::chk()
1114 if (checked
) return;
1116 if (!my_type
) FATAL_ERROR("UnparsedMultipleInnerTypeConstraint::chk()");
1117 Error_Context
cntxt(this, "While checking inner type constraint");
1118 Type
* t
= my_type
->get_type_refd_last();
1119 switch (t
->get_typetype()) {
1120 case Type::T_REAL
: // associated ASN.1 type is a SEQUENCE
1121 case Type::T_CHOICE_A
:
1122 case Type::T_SEQ_A
: // also refd by T_EXTERNAL, T_EMBEDDED_PDV and T_UNRESTRICTEDSTRING
1126 error("Multiple inner type constraint (WITH COMPONENTS) cannot be used on type `%s'", my_type
->get_typename().c_str());
1129 Node
*node
= block
->parse(KW_Block_MultipleTypeConstraints
);
1130 constraint
= dynamic_cast<MultipleInnerTypeConstraint
*>(node
);
1133 return; // parsing error was already reported
1135 constraint
->set_my_type(my_type
);
1136 constraint
->set_my_scope(get_my_scope());
1137 constraint
->set_my_parent(this);
1139 subtype
= new SubtypeConstraint(my_type
->get_subtype_type()); // ignored
1142 void UnparsedMultipleInnerTypeConstraint::set_fullname(const string
& p_fullname
)
1144 Node::set_fullname(p_fullname
);
1145 block
->set_fullname(p_fullname
);
1146 if (constraint
) constraint
->set_fullname(p_fullname
);
1149 } // namespace Common