1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #include "Constraint.hh"
9 #include "CompilerError.hh"
14 #include "Identifier.hh"
15 #include "CompField.hh"
16 #include "asn1/Block.hh"
17 #include "asn1/TokenBuf.hh"
21 // =================================
23 // =================================
25 Constraints::Constraints(const Constraints
& p
)
26 : Node(p
), cons(), my_type(0), subtype(0), extendable(false), extension(0)
28 size_t nof_cons
= p
.cons
.size();
29 for (size_t i
= 0; i
< nof_cons
; i
++) cons
.add(p
.cons
[i
]->clone());
32 Constraints::~Constraints()
34 size_t nof_cons
= cons
.size();
35 for (size_t i
= 0; i
< nof_cons
; i
++) delete cons
[i
];
41 Constraints
*Constraints::clone() const
43 return new Constraints(*this);
46 void Constraints::add_con(Constraint
*p_con
)
48 if (!p_con
) FATAL_ERROR("Constraints::add_con()");
50 if (my_type
) p_con
->set_my_type(my_type
);
53 Constraint
* Constraints::get_tableconstraint() const
55 size_t nof_cons
= cons
.size();
56 for (size_t i
= 0; i
< nof_cons
; i
++) {
57 Constraint
*con
= cons
[i
];
58 if (con
->get_constrtype() == Constraint::CT_TABLE
) return con
;
63 void Constraints::set_my_type(Type
*p_my_type
)
66 size_t nof_cons
= cons
.size();
67 for (size_t i
= 0; i
< nof_cons
; i
++) cons
[i
]->set_my_type(p_my_type
);
70 void Constraints::chk_table()
72 if(!my_type
) FATAL_ERROR("Constraints::chk_table()");
73 size_t nof_cons
= cons
.size();
74 for (size_t i
= 0; i
< nof_cons
; i
++) {
75 Error_Context
cntxt(my_type
, "In constraint #%lu of type `%s'",
76 (unsigned long) (i
+ 1), my_type
->get_typename().c_str());
77 Constraint::constrtype_t cst
= cons
[i
]->get_constrtype();
78 if (cst
==Constraint::CT_TABLE
) cons
[i
]->chk();
82 void Constraints::chk(SubtypeConstraint
* parent_subtype
)
84 if(!my_type
) FATAL_ERROR("Common::Constraints::chk()");
86 subtype
= new SubtypeConstraint(my_type
->get_subtype_type());
87 subtype
->copy(parent_subtype
);
89 size_t nof_cons
= cons
.size();
90 for (size_t i
= 0; i
< nof_cons
; i
++) {
91 Error_Context
cntxt(my_type
, "In constraint #%lu of type `%s'",
92 (unsigned long) (i
+ 1), my_type
->get_typename().c_str());
93 cons
[i
]->set_fullname(my_type
->get_fullname()+".<constraint_"+Int2string(i
+1)+">.<"+string(cons
[i
]->get_name())+">");
94 cons
[i
]->set_my_cons(this);
95 Constraint::constrtype_t cst
= cons
[i
]->get_constrtype();
96 if (cst
!=Constraint::CT_TABLE
) cons
[i
]->chk();
97 if ( (cst
==Constraint::CT_IGNORE
) || (cst
==Constraint::CT_TABLE
) ) continue; // ignore
98 SubtypeConstraint
* sc
= cons
[i
]->get_subtype();
99 SubtypeConstraint
* sc_ext
= cons
[i
]->get_extension();
100 if (!sc
) break; // stop on error
101 extendable
= cons
[i
]->is_extendable();
102 if (extension
) { // only the root part shall be kept
107 if (sc
->is_subset(subtype
)==TFALSE
) {
108 cons
[i
]->error("Constraint #%lu is %s, this is not a subset of %s",
109 (unsigned long) (i
+ 1),
110 sc
->to_string().c_str(),
111 subtype
->to_string().c_str());
112 break; // stop on error
114 if (sc_ext
&& (sc_ext
->is_subset(subtype
)==TFALSE
)) {
115 cons
[i
]->error("Extension addition of constraint #%lu is %s, this is not a subset of %s",
116 (unsigned long) (i
+ 1),
117 sc_ext
->to_string().c_str(),
118 subtype
->to_string().c_str());
119 break; // stop on error
122 extension
= new SubtypeConstraint(my_type
->get_subtype_type());
123 extension
->copy(sc_ext
);
124 extension
->intersection(subtype
);
126 subtype
->intersection(sc
);
128 subtype
= new SubtypeConstraint(my_type
->get_subtype_type());
131 extension
= new SubtypeConstraint(my_type
->get_subtype_type());
132 extension
->copy(sc_ext
);
138 // =================================
140 // =================================
142 Constraint::Constraint(const Constraint
& p
):
143 Node(p
), Location(p
), constrtype(p
.constrtype
),
144 my_type(0), my_scope(0), my_parent(0), my_cons(0),
145 checked(false), subtype(0), extendable(false), extension(0)
149 Constraint::Constraint(constrtype_t p_constrtype
):
150 Node(), Location(), constrtype(p_constrtype
),
151 my_type(0), my_scope(0), my_parent(0), my_cons(0),
152 checked(false), subtype(0), extendable(false), extension(0)
156 Constraint::~Constraint()
162 Scope
* Constraint::get_my_scope()
164 if (!my_type
) FATAL_ERROR("Constraint::get_my_scope()");
165 return my_scope
? my_scope
: my_type
->get_my_scope();
168 void Constraint::set_my_cons(Constraints
* p_my_cons
)
173 Constraints
* Constraint::get_my_cons()
175 Constraint
* c
= this;
177 if (c
->my_cons
) return c
->my_cons
;
180 FATAL_ERROR("Constraint::get_my_cons()");
184 bool Constraint::in_char_context() const
186 Constraint
* parent
= my_parent
;
188 if (parent
->get_constrtype()==CT_PERMITTEDALPHABET
) return true;
189 parent
= parent
->get_my_parent();
194 bool Constraint::in_inner_constraint() const
196 Constraint
* parent
= my_parent
;
198 switch (parent
->get_constrtype()) {
199 case CT_SINGLEINNERTYPE
:
200 case CT_MULTIPLEINNERTYPE
:
205 parent
= parent
->get_my_parent();
210 // =================================
211 // ===== ElementSetSpecsConstraint
212 // =================================
214 ElementSetSpecsConstraint::ElementSetSpecsConstraint(const ElementSetSpecsConstraint
& p
)
218 root_constr
= p
.root_constr
? p
.root_constr
->clone() : 0;
219 ext_constr
= p
.ext_constr
? p
.ext_constr
->clone() : 0;
222 ElementSetSpecsConstraint::ElementSetSpecsConstraint(Constraint
* p_root_constr
, Constraint
* p_ext_constr
)
223 : Constraint(CT_ELEMENTSETSPEC
), root_constr(p_root_constr
), ext_constr(p_ext_constr
)
225 if (!p_root_constr
) FATAL_ERROR("ElementSetSpecsConstraint::ElementSetSpecsConstraint()");
226 // p_ext_constr can be NULL
230 ElementSetSpecsConstraint::~ElementSetSpecsConstraint()
236 void ElementSetSpecsConstraint::chk()
240 if (!root_constr
|| !my_type
) FATAL_ERROR("ElementSetSpecsConstraint::chk()");
241 Error_Context
cntxt(this, "While checking ElementSetSpecs constraint");
242 root_constr
->set_my_type(my_type
);
243 if (ext_constr
) ext_constr
->set_my_type(my_type
);
244 root_constr
->set_my_scope(get_my_scope());
245 if (ext_constr
) ext_constr
->set_my_scope(get_my_scope());
246 root_constr
->set_my_parent(this);
247 if (ext_constr
) ext_constr
->set_my_parent(this);
249 if (ext_constr
) ext_constr
->chk();
250 SubtypeConstraint::subtype_t my_subtype_type
= my_type
->get_subtype_type();
251 // naming ((r1,x1),...,(r2,x2)) according to X.680(11/2008) I.4.3.8
252 SubtypeConstraint
* r1
= root_constr
->get_subtype();
253 if (!r1
) return; // root_constr is invalid, error already reported there
254 SubtypeConstraint
* x1
= root_constr
->get_extension();
256 // only root part exists
257 subtype
= new SubtypeConstraint(my_subtype_type
);
260 extension
= new SubtypeConstraint(my_subtype_type
);
265 SubtypeConstraint
* r2
= ext_constr
->get_subtype();
266 if (!r2
) return; // ext_constr is invalid, error already reported there
267 SubtypeConstraint
* x2
= ext_constr
->get_extension();
268 subtype
= new SubtypeConstraint(my_subtype_type
);
270 extension
= new SubtypeConstraint(my_subtype_type
);
272 if (x1
) extension
->union_(x1
);
273 if (x2
) extension
->union_(x2
);
274 extension
->except(r1
);
277 void ElementSetSpecsConstraint::set_fullname(const string
& p_fullname
)
279 Node::set_fullname(p_fullname
);
280 root_constr
->set_fullname(p_fullname
+".<root_part>.<"+string(root_constr
->get_name())+">");
282 ext_constr
->set_fullname(p_fullname
+".<extension_part>.<"+string(ext_constr
->get_name())+">");
285 // =================================
286 // ===== IgnoredConstraint
287 // =================================
289 IgnoredConstraint::IgnoredConstraint(const IgnoredConstraint
& p
)
290 : Constraint(p
), my_name(p
.my_name
)
294 IgnoredConstraint::IgnoredConstraint(const char* p_name
)
295 : Constraint(CT_IGNORE
), my_name(p_name
)
297 if (p_name
==NULL
) FATAL_ERROR("IgnoredConstraint::IgnoredConstraint()");
300 void IgnoredConstraint::chk()
304 if (!my_type
) FATAL_ERROR("IgnoredConstraint::chk()");
305 if (in_char_context()) {
306 error("%s not allowed inside a permitted alphabet constraint", get_name());
309 if (my_parent
) warning("%s inside a %s is treated as `ALL' (constraint is dropped)", get_name(), my_parent
->get_name());
310 //else warning("%s is ignored", get_name());
312 // ignored constraint does not constrain the type, set to full set
313 subtype
= new SubtypeConstraint(my_type
->get_subtype_type());
316 // =================================
317 // ===== SingleValueConstraint
318 // =================================
320 SingleValueConstraint::SingleValueConstraint(const SingleValueConstraint
& p
)
323 value
= p
.value
? p
.value
->clone() : 0;
326 SingleValueConstraint::~SingleValueConstraint()
331 SingleValueConstraint::SingleValueConstraint(Value
* p_value
)
332 : Constraint(CT_SINGLEVALUE
), value(p_value
)
334 if (!p_value
) FATAL_ERROR("SingleValueConstraint::SingleValueConstraint()");
337 void SingleValueConstraint::chk()
341 if (!value
|| !my_type
) FATAL_ERROR("SingleValueConstraint::chk()");
342 Error_Context
cntxt(this, "While checking single value constraint");
343 value
->set_my_scope(get_my_scope());
344 value
->set_my_governor(my_type
);
345 my_type
->chk_this_value_ref(value
);
346 my_type
->chk_this_value(value
, 0, Type::EXPECTED_CONSTANT
,
347 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
348 if (in_char_context()) {
349 subtype
= SubtypeConstraint::create_from_asn_charvalues(my_type
, value
);
351 subtype
= SubtypeConstraint::create_from_asn_value(my_type
, value
);
355 void SingleValueConstraint::set_fullname(const string
& p_fullname
)
357 Node::set_fullname(p_fullname
);
358 value
->set_fullname(p_fullname
+".<value>");
361 // =================================
362 // ===== ContainedSubtypeConstraint
363 // =================================
365 ContainedSubtypeConstraint::ContainedSubtypeConstraint(const ContainedSubtypeConstraint
& p
)
368 type
= p
.type
? p
.type
->clone() : 0;
371 ContainedSubtypeConstraint::~ContainedSubtypeConstraint()
376 ContainedSubtypeConstraint::ContainedSubtypeConstraint(Type
* p_type
, bool p_has_includes
)
377 : Constraint(CT_CONTAINEDSUBTYPE
), type(p_type
), has_includes(p_has_includes
)
379 if (!p_type
) FATAL_ERROR("ContainedSubtypeConstraint::ContainedSubtypeConstraint()");
382 void ContainedSubtypeConstraint::chk()
386 if (!type
|| !my_type
) FATAL_ERROR("ContainedSubtypeConstraint::chk()");
387 Error_Context
cntxt(this, "While checking contained subtype constraint");
389 type
->set_my_scope(get_my_scope());
391 if (type
->get_typetype()==Type::T_ERROR
) return;
393 if (my_type
->get_type_refd_last()->get_typetype()==Type::T_OPENTYPE
) {
394 // TODO: open type and anytype should have their own ST_ANY subtype, now this is only ignored
395 subtype
= new SubtypeConstraint(my_type
->get_subtype_type());
399 if (!type
->is_identical(my_type
)) {
400 error("Contained subtype constraint is invalid, constrained and constraining types have different root type");
403 // check subtype of referenced type
404 SubType
* t_st
= type
->get_sub_type();
406 error("Contained subtype constraint is invalid, the constraining type has no subtype constraint");
410 // check circular subtype reference
411 Type
* my_owner
= get_my_cons()->get_my_type();
412 if (!my_owner
|| !my_owner
->get_sub_type()) FATAL_ERROR("ContainedSubtypeConstraint::chk()");
413 if (!my_owner
->get_sub_type()->add_parent_subtype(t_st
)) return;
415 if (t_st
->get_subtypetype()==SubtypeConstraint::ST_ERROR
) return;
416 if (t_st
->get_subtypetype()!=my_type
->get_subtype_type()) FATAL_ERROR("ContainedSubtypeConstraint::chk()");
418 subtype
= SubtypeConstraint::create_from_contained_subtype(t_st
->get_root(), in_char_context(), this);
421 void ContainedSubtypeConstraint::set_fullname(const string
& p_fullname
)
423 Node::set_fullname(p_fullname
);
424 type
->set_fullname(p_fullname
+".<type>");
427 // =================================
428 // ===== RangeEndpoint
429 // =================================
431 RangeEndpoint::RangeEndpoint(const RangeEndpoint
& p
):
432 Node(p
), Location(p
), type(p
.type
), inclusive(p
.inclusive
)
434 value
= p
.value
? p
.value
->clone() : 0;
437 RangeEndpoint::~RangeEndpoint()
442 RangeEndpoint::RangeEndpoint(endpoint_t p_type
):
443 Node(), Location(), type(p_type
), value(0), inclusive(true)
445 if (type
==VALUE
) FATAL_ERROR("RangeEndpoint::RangeEndpoint()");
448 RangeEndpoint::RangeEndpoint(Value
* p_value
):
449 Node(), Location(), type(RangeEndpoint::VALUE
), value(p_value
), inclusive(true)
451 if (!p_value
) FATAL_ERROR("RangeEndpoint::RangeEndpoint()");
454 void RangeEndpoint::chk(Type
* my_type
, ValueRangeConstraint
* constraint
)
457 value
->set_my_scope(constraint
->get_my_scope());
458 my_type
->chk_this_value_ref(value
);
459 my_type
->chk_this_value(value
, 0, Type::EXPECTED_CONSTANT
,
460 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
464 void RangeEndpoint::set_fullname(const string
& p_fullname
)
466 Node::set_fullname(p_fullname
);
467 if (value
) value
->set_fullname(p_fullname
+".<value>");
470 // =================================
471 // ===== ValueRangeConstraint
472 // =================================
474 ValueRangeConstraint::ValueRangeConstraint(const ValueRangeConstraint
& p
)
477 lower_endpoint
= p
.lower_endpoint
? p
.lower_endpoint
->clone() : 0;
478 upper_endpoint
= p
.upper_endpoint
? p
.upper_endpoint
->clone() : 0;
481 ValueRangeConstraint::ValueRangeConstraint(RangeEndpoint
* p_lower
, RangeEndpoint
* p_upper
)
482 : Constraint(CT_VALUERANGE
), lower_endpoint(p_lower
), upper_endpoint(p_upper
)
484 if (!p_lower
|| !p_upper
) FATAL_ERROR("ValueRangeConstraint::ValueRangeConstraint()");
487 void ValueRangeConstraint::chk()
491 if (!lower_endpoint
|| !upper_endpoint
|| !my_type
) FATAL_ERROR("ValueRangeConstraint::chk()");
492 Error_Context
cntxt(this, "While checking value range constraint");
493 SubtypeConstraint::subtype_t my_subtype_type
= my_type
->get_subtype_type();
494 switch (my_subtype_type
) {
495 case SubtypeConstraint::ST_INTEGER
:
496 case SubtypeConstraint::ST_FLOAT
:
498 case SubtypeConstraint::ST_CHARSTRING
:
499 switch (my_type
->get_type_refd_last()->get_typetype()) {
500 case Type::T_NUMERICSTRING
:
501 case Type::T_PRINTABLESTRING
:
502 case Type::T_IA5STRING
:
503 case Type::T_VISIBLESTRING
:
504 if (!in_char_context()) {
505 error("Value range constraint must be inside a permitted alphabet or size constraint");
510 error("Value range constraint is not allowed for type `%s'", my_type
->get_typename().c_str());
514 case SubtypeConstraint::ST_UNIVERSAL_CHARSTRING
:
515 switch (my_type
->get_type_refd_last()->get_typetype()) {
516 case Type::T_UTF8STRING
:
517 case Type::T_UNIVERSALSTRING
:
518 case Type::T_BMPSTRING
:
519 if (!in_char_context()) {
520 error("Value range constraint must be inside a permitted alphabet or size constraint");
525 error("Value range constraint is not allowed for type `%s'", my_type
->get_typename().c_str());
530 error("Value range constraint is not allowed for type `%s'", my_type
->get_typename().c_str());
533 lower_endpoint
->chk(my_type
, this);
534 upper_endpoint
->chk(my_type
, this);
535 Value
* vmin
= lower_endpoint
->get_value();
536 if (vmin
) vmin
= vmin
->get_value_refd_last();
537 Value
* vmax
= upper_endpoint
->get_value();
538 if (vmax
) vmax
= vmax
->get_value_refd_last();
539 // the subtype of the Constraints object at the time of calling this chk()
540 // function is constructed from all the previously calculated constraints
541 // (it is not yet the final subtype). This is needed to calculate the
542 // current MIN and MAX values.
543 SubtypeConstraint
* parent_subtype
= get_my_cons()->get_subtype();
544 subtype
= SubtypeConstraint::create_from_asn_range(
545 vmin
, lower_endpoint
->get_exclusive(),
546 vmax
, upper_endpoint
->get_exclusive(),
547 this, my_subtype_type
,
548 in_inner_constraint() ? NULL
/*the parent is invalid for an inner field*/ : parent_subtype
);
551 void ValueRangeConstraint::set_fullname(const string
& p_fullname
)
553 Node::set_fullname(p_fullname
);
554 lower_endpoint
->set_fullname(p_fullname
+".<lower_endpoint>");
555 upper_endpoint
->set_fullname(p_fullname
+".<upper_endpoint>");
558 // =================================
559 // ===== SizeConstraint
560 // =================================
562 SizeConstraint::SizeConstraint(const SizeConstraint
& p
)
565 constraint
= p
.constraint
? p
.constraint
->clone() : 0;
568 SizeConstraint::SizeConstraint(Constraint
* p
)
569 : Constraint(CT_SIZE
), constraint(p
)
571 if (!p
) FATAL_ERROR("SizeConstraint::SizeConstraint()");
574 void SizeConstraint::chk()
578 if (!constraint
|| !my_type
) FATAL_ERROR("SizeConstraint::chk()");
579 Error_Context
cntxt(this, "While checking size constraint");
580 constraint
->set_my_type(Type::get_pooltype(Type::T_INT_A
));
581 constraint
->set_my_scope(get_my_scope());
582 constraint
->set_my_parent(this);
584 subtype
= SubtypeConstraint::create_asn_size_constraint(
585 constraint
->get_subtype(), in_char_context(), my_type
, this);
586 extendable
= constraint
->is_extendable();
587 if (constraint
->get_extension()) {
588 extension
= SubtypeConstraint::create_asn_size_constraint(
589 constraint
->get_extension(), in_char_context(), my_type
, this);
593 void SizeConstraint::set_fullname(const string
& p_fullname
)
595 Node::set_fullname(p_fullname
);
596 constraint
->set_fullname(p_fullname
+".<"+string(constraint
->get_name())+">");
599 // =================================
600 // ===== PermittedAlphabetConstraint
601 // =================================
603 PermittedAlphabetConstraint::PermittedAlphabetConstraint(const PermittedAlphabetConstraint
& p
)
606 constraint
= p
.constraint
? p
.constraint
->clone() : 0;
609 PermittedAlphabetConstraint::PermittedAlphabetConstraint(Constraint
* p
)
610 : Constraint(CT_PERMITTEDALPHABET
), constraint(p
)
612 if (!p
) FATAL_ERROR("PermittedAlphabetConstraint::PermittedAlphabetConstraint()");
615 void PermittedAlphabetConstraint::chk()
619 if (!constraint
|| !my_type
) FATAL_ERROR("PermittedAlphabetConstraint::chk()");
620 Error_Context
cntxt(this, "While checking permitted alphabet constraint");
621 constraint
->set_my_type(my_type
);
622 constraint
->set_my_scope(get_my_scope());
623 constraint
->set_my_parent(this);
625 subtype
= SubtypeConstraint::create_permitted_alphabet_constraint(
626 constraint
->get_subtype(), in_char_context(), my_type
, this);
627 extendable
= constraint
->is_extendable();
628 if (constraint
->get_extension()) {
629 extension
= SubtypeConstraint::create_permitted_alphabet_constraint(
630 constraint
->get_extension(), in_char_context(), my_type
, this);
634 void PermittedAlphabetConstraint::set_fullname(const string
& p_fullname
)
636 Node::set_fullname(p_fullname
);
637 constraint
->set_fullname(p_fullname
+".<"+string(constraint
->get_name())+">");
640 // =================================
641 // ===== SetOperationConstraint
642 // =================================
644 SetOperationConstraint::SetOperationConstraint(const SetOperationConstraint
& p
)
645 : Constraint(p
), operationtype(p
.operationtype
)
647 operand_a
= p
.operand_a
? p
.operand_a
->clone() : 0;
648 operand_b
= p
.operand_b
? p
.operand_b
->clone() : 0;
651 void SetOperationConstraint::set_first_operand(Constraint
* p_a
)
653 if (operand_a
|| !p_a
) FATAL_ERROR("SetOperationConstraint::set_first_operand()");
657 SetOperationConstraint::SetOperationConstraint(Constraint
* p_a
, operationtype_t p_optype
, Constraint
* p_b
)
658 : Constraint(CT_SETOPERATION
), operationtype(p_optype
), operand_a(p_a
), operand_b(p_b
)
661 if (!p_b
) FATAL_ERROR("SetOperationConstraint::SetOperationConstraint()");
664 const char* SetOperationConstraint::get_operationtype_str() const
666 switch (operationtype
) {
670 return "intersection";
677 void SetOperationConstraint::chk()
681 if (!operand_a
|| !operand_b
|| !my_type
) FATAL_ERROR("SetOperationConstraint::chk()");
682 Error_Context
cntxt(this, "While checking %s operation", get_operationtype_str());
683 operand_a
->set_my_type(my_type
);
684 operand_b
->set_my_type(my_type
);
685 operand_a
->set_my_scope(get_my_scope());
686 operand_b
->set_my_scope(get_my_scope());
687 operand_a
->set_my_parent(this);
688 operand_b
->set_my_parent(this);
692 extendable
= (operationtype
!=EXCEPT
) ?
693 (operand_a
->is_extendable() || operand_b
->is_extendable()) :
694 operand_a
->is_extendable();
695 SubtypeConstraint::subtype_t my_subtype_type
= my_type
->get_subtype_type();
696 // naming ((r1,x1),...,(r2,x2)) according to X.680(11/2008) I.4.3.8
697 SubtypeConstraint
* r1
= operand_a
->get_subtype();
698 SubtypeConstraint
* x1
= operand_a
->get_extension();
699 SubtypeConstraint
* r2
= operand_b
->get_subtype();
700 SubtypeConstraint
* x2
= operand_b
->get_extension();
701 if (!r1
|| !r2
) return; // something invalid, error already reported there
702 subtype
= new SubtypeConstraint(my_subtype_type
);
704 switch (operationtype
) {
708 extension
= new SubtypeConstraint(my_subtype_type
);
710 extension
->copy(subtype
);
711 extension
->union_(x1
);
712 extension
->union_(x2
);
713 extension
->except(subtype
);
715 extension
->copy(x1
?x1
:x2
);
720 subtype
->intersection(r2
);
722 extension
= new SubtypeConstraint(my_subtype_type
);
725 extension
->union_(x1
);
726 SubtypeConstraint
* ext_tmp
= new SubtypeConstraint(my_subtype_type
);
729 extension
->intersection(ext_tmp
);
731 extension
->except(subtype
);
734 extension
->intersection(x1
?x1
:x2
);
741 extension
= new SubtypeConstraint(my_subtype_type
);
744 SubtypeConstraint
* ext_tmp
= new SubtypeConstraint(my_subtype_type
);
747 extension
->except(ext_tmp
);
749 extension
->except(subtype
);
752 extension
->except(r2
);
753 extension
->except(subtype
);
758 FATAL_ERROR("SetOperationConstraint::chk()");
762 void SetOperationConstraint::set_fullname(const string
& p_fullname
)
764 Node::set_fullname(p_fullname
);
765 operand_a
->set_fullname(p_fullname
+".<first_operand>.<"+string(operand_a
->get_name())+">");
766 operand_b
->set_fullname(p_fullname
+".<second_operand>.<"+string(operand_b
->get_name())+">");
769 // =================================
770 // ===== FullSetConstraint
771 // =================================
773 void FullSetConstraint::chk()
775 SubtypeConstraint::subtype_t my_subtype_type
= my_type
->get_subtype_type();
776 subtype
= new SubtypeConstraint(my_subtype_type
);
779 // =================================
780 // ===== PatternConstraint
781 // =================================
783 PatternConstraint::PatternConstraint(const PatternConstraint
& p
)
786 value
= p
.value
? p
.value
->clone() : 0;
789 PatternConstraint::~PatternConstraint()
794 PatternConstraint::PatternConstraint(Value
* p_value
)
795 : Constraint(CT_PATTERN
), value(p_value
)
797 if (!p_value
) FATAL_ERROR("PatternConstraint::PatternConstraint()");
800 void PatternConstraint::chk()
804 if (!value
|| !my_type
) FATAL_ERROR("PatternConstraint::chk()");
805 Error_Context
cntxt(this, "While checking pattern constraint");
806 switch (my_type
->get_subtype_type()) {
807 case SubtypeConstraint::ST_CHARSTRING
:
808 case SubtypeConstraint::ST_UNIVERSAL_CHARSTRING
:
811 error("Pattern constraint is not allowed for type `%s'", my_type
->get_typename().c_str());
814 value
->set_my_scope(get_my_scope());
815 value
->set_my_governor(my_type
);
816 my_type
->chk_this_value_ref(value
);
817 my_type
->chk_this_value(value
, 0, Type::EXPECTED_CONSTANT
,
818 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
819 // ignore ASN.1 pattern constraint (9.1 Transformation rules, point 4.)
820 if (in_char_context()) {
821 error("%s not allowed inside a permitted alphabet constraint", get_name());
824 if (my_parent
) warning("%s inside a %s is treated as `ALL' (constraint is dropped)",
825 get_name(), my_parent
->get_name());
826 else warning("%s is ignored", get_name());
828 subtype
= new SubtypeConstraint(my_type
->get_subtype_type());
831 void PatternConstraint::set_fullname(const string
& p_fullname
)
833 Node::set_fullname(p_fullname
);
834 value
->set_fullname(p_fullname
+".<value>");
837 // =================================
838 // ===== SingleInnerTypeConstraint
839 // =================================
841 SingleInnerTypeConstraint::SingleInnerTypeConstraint(const SingleInnerTypeConstraint
& p
)
844 constraint
= p
.constraint
? p
.constraint
->clone() : 0;
847 SingleInnerTypeConstraint::SingleInnerTypeConstraint(Constraint
* p
)
848 : Constraint(CT_SINGLEINNERTYPE
), constraint(p
)
850 if (!p
) FATAL_ERROR("SingleInnerTypeConstraint::SingleInnerTypeConstraint()");
853 void SingleInnerTypeConstraint::chk()
857 if (!constraint
|| !my_type
) FATAL_ERROR("SingleInnerTypeConstraint::chk()");
858 Error_Context
cntxt(this, "While checking inner type constraint");
859 Type
* t
= my_type
->get_type_refd_last();
861 error("Single inner type constraint (WITH COMPONENT) cannot be used on type `%s'", my_type
->get_typename().c_str());
864 Type
* field_type
= t
->get_ofType(); // determine the type of the field to which it refers
865 constraint
->set_my_type(field_type
);
866 constraint
->set_my_scope(get_my_scope());
867 constraint
->set_my_parent(this);
869 //if (constraint->get_subtype()) { // if the constraint was not erroneous
870 // TODO: this could be added to the a tree structure constraint on my_type,
871 // tree structure needed because of set operations, constraint cannot
872 // be added to field_type
874 // inner subtype is ignored ( ETSI ES 201 873-7 V4.1.2 -> 9.1 Transformation rules )
875 subtype
= new SubtypeConstraint(my_type
->get_subtype_type());
878 void SingleInnerTypeConstraint::set_fullname(const string
& p_fullname
)
880 Node::set_fullname(p_fullname
);
881 constraint
->set_fullname(p_fullname
+".<"+string(constraint
->get_name())+">");
884 // =================================
885 // ===== NamedConstraint
886 // =================================
888 NamedConstraint::NamedConstraint(Identifier
* p_id
, Constraint
* p_value_constraint
, presence_constraint_t p_presence_constraint
):
889 Constraint(CT_NAMED
), id(p_id
), value_constraint(p_value_constraint
), presence_constraint(p_presence_constraint
)
891 if (!id
) FATAL_ERROR("NamedConstraint::NamedConstraint()");
894 NamedConstraint::NamedConstraint(const NamedConstraint
& p
)
898 value_constraint
= p
.value_constraint
? p
.value_constraint
->clone() : 0;
899 presence_constraint
= p
.presence_constraint
;
902 NamedConstraint::~NamedConstraint()
905 delete value_constraint
;
908 const char* NamedConstraint::get_presence_constraint_name() const
910 switch (presence_constraint
) {
911 case PC_NONE
: return "";
912 case PC_PRESENT
: return "PRESENT";
913 case PC_ABSENT
: return "ABSENT";
914 case PC_OPTIONAL
: return "OPTIONAL";
915 default: FATAL_ERROR("NamedConstraint::get_presence_constraint_name()");
919 void NamedConstraint::chk()
923 if (!my_type
) FATAL_ERROR("NamedConstraint::chk()");
924 Error_Context
cntxt(this, "While checking named constraint");
925 if (value_constraint
) {
926 value_constraint
->set_my_type(my_type
);
927 value_constraint
->set_my_scope(get_my_scope());
928 value_constraint
->set_my_parent(this);
929 value_constraint
->chk();
931 subtype
= new SubtypeConstraint(my_type
->get_subtype_type()); // ignored
934 void NamedConstraint::set_fullname(const string
& p_fullname
)
936 Node::set_fullname(p_fullname
);
937 if (value_constraint
) {
938 value_constraint
->set_fullname(p_fullname
+".<"+string(value_constraint
->get_name())+">");
942 // =================================
943 // ===== MultipleInnerTypeConstraint
944 // =================================
946 MultipleInnerTypeConstraint::MultipleInnerTypeConstraint(const MultipleInnerTypeConstraint
& p
)
950 for (size_t i
=0; i
<p
.named_con_vec
.size(); i
++) {
951 named_con_vec
.add( p
.named_con_vec
[i
]->clone() );
955 MultipleInnerTypeConstraint::~MultipleInnerTypeConstraint()
957 named_con_map
.clear();
958 for (size_t i
=0; i
<named_con_vec
.size(); i
++) {
959 delete named_con_vec
[i
];
961 named_con_vec
.clear();
964 void MultipleInnerTypeConstraint::addNamedConstraint(NamedConstraint
* named_con
)
966 if (!named_con
) FATAL_ERROR("MultipleInnerTypeConstraint::addNamedConstraint()");
967 if (checked
) FATAL_ERROR("MultipleInnerTypeConstraint::addNamedConstraint()");
968 named_con_vec
.add(named_con
);
971 void MultipleInnerTypeConstraint::chk()
975 if (!my_type
) FATAL_ERROR("MultipleInnerTypeConstraint::chk()");
976 Type
* t
= my_type
->get_type_refd_last();
978 switch (t
->get_typetype()) {
979 case Type::T_REAL
: { // associated ASN.1 type is a SEQUENCE
980 Identifier
t_id(Identifier::ID_ASN
, string("REAL"));
981 t
= t
->get_my_scope()->get_scope_asss()->get_local_ass_byId(t_id
)->get_Type();
982 if (t
->get_typetype()!=Type::T_SEQ_A
) FATAL_ERROR("MultipleInnerTypeConstraint::chk()");
984 case Type::T_CHOICE_A
:
985 case Type::T_SEQ_A
: // T_EXTERNAL, T_EMBEDDED_PDV, T_UNRESTRICTEDSTRING
989 FATAL_ERROR("MultipleInnerTypeConstraint::chk()");
991 // check that all NamedConstraints refer to an existing component
992 // if it exists add it to the map<> and check uniqueness
993 // for SEQUENCE check order of fields
994 size_t max_idx
= 0; // current highest field index, to detect invalid order
995 bool invalid_order
= false;
996 size_t present_count
= 0;
997 size_t absent_count
= 0;
998 for (size_t i
=0; i
<named_con_vec
.size(); i
++) {
999 const Identifier
& id
= named_con_vec
[i
]->get_id();
1000 if (t
->has_comp_withName(id
)) {
1001 if (named_con_map
.has_key(id
)) {
1002 named_con_vec
[i
]->error("Duplicate reference to field `%s' of type `%s'",
1003 id
.get_dispname().c_str(), my_type
->get_typename().c_str());
1004 named_con_map
[id
]->note("Previous reference to field `%s' is here",
1005 id
.get_dispname().c_str());
1007 named_con_map
.add(id
, named_con_vec
[i
]);
1008 if (t
->get_typetype()==Type::T_SEQ_A
) {
1009 size_t curr_idx
= t
->get_comp_index_byName(id
);
1010 if (curr_idx
<max_idx
) invalid_order
= true;
1011 else max_idx
= curr_idx
;
1013 switch (named_con_vec
[i
]->get_presence_constraint()) {
1014 case NamedConstraint::PC_PRESENT
:
1017 case NamedConstraint::PC_ABSENT
:
1024 CompField
* cf
= t
->get_comp_byName(id
);
1025 switch (t
->get_typetype()) {
1028 if (!cf
->get_is_optional() && (named_con_vec
[i
]->get_presence_constraint()!=NamedConstraint::PC_NONE
)) {
1029 named_con_vec
[i
]->error("Presence constraint `%s' cannot be used on mandatory field `%s'",
1030 named_con_vec
[i
]->get_presence_constraint_name(), id
.get_dispname().c_str());
1036 Type
* field_type
= cf
->get_type();
1037 named_con_vec
[i
]->set_my_type(field_type
);
1038 named_con_vec
[i
]->set_my_scope(get_my_scope());
1039 named_con_vec
[i
]->set_my_parent(this);
1040 named_con_vec
[i
]->chk();
1042 named_con_vec
[i
]->error("Type `%s' does not have a field named `%s'",
1043 my_type
->get_typename().c_str(), id
.get_dispname().c_str());
1046 if (invalid_order
) {
1047 error("The order of fields must be the same as in the definition of type `%s'",
1048 my_type
->get_typename().c_str());
1050 if (t
->get_typetype()==Type::T_CHOICE_A
) {
1051 if (present_count
>1) {
1052 error("CHOICE type `%s' cannot have more than one `PRESENT' field", my_type
->get_typename().c_str());
1054 // in FullSpecification all not listed fields that can be absent are implicitly ABSENT
1055 size_t real_absent_count
= absent_count
+ ((!get_partial())?(t
->get_nof_comps()-named_con_map
.size()):0);
1056 if (real_absent_count
>=t
->get_nof_comps()) {
1057 error("All fields of CHOICE type `%s' are `ABSENT'", my_type
->get_typename().c_str());
1058 if (real_absent_count
>absent_count
) {
1059 note("%ld not listed field%s implicitly `ABSENT' because FullSpecification was used",
1060 (long)(real_absent_count
-absent_count
), ((real_absent_count
-absent_count
)>1)?"s are":" is");
1065 // inner subtype is ignored ( ETSI ES 201 873-7 V4.1.2 -> 9.1 Transformation rules )
1066 subtype
= new SubtypeConstraint(my_type
->get_subtype_type());
1069 void MultipleInnerTypeConstraint::set_fullname(const string
& p_fullname
)
1071 Node::set_fullname(p_fullname
);
1072 for (size_t i
=0; i
<named_con_vec
.size(); i
++) {
1073 named_con_vec
[i
]->set_fullname(p_fullname
+".<"+string(named_con_vec
[i
]->get_name())+" "+Int2string(i
)+">");
1077 // =================================
1078 // ===== UnparsedMultipleInnerTypeConstraint
1079 // =================================
1081 UnparsedMultipleInnerTypeConstraint::UnparsedMultipleInnerTypeConstraint(const UnparsedMultipleInnerTypeConstraint
& p
)
1084 block
= p
.block
? p
.block
->clone() : 0;
1088 UnparsedMultipleInnerTypeConstraint::UnparsedMultipleInnerTypeConstraint(Block
* p_block
)
1089 : Constraint(CT_UNPARSEDMULTIPLEINNERTYPE
), block(p_block
), constraint(0)
1091 if (!block
) FATAL_ERROR("UnparsedMultipleInnerTypeConstraint::UnparsedMultipleInnerTypeConstraint()");
1094 UnparsedMultipleInnerTypeConstraint::~UnparsedMultipleInnerTypeConstraint()
1100 void UnparsedMultipleInnerTypeConstraint::chk()
1102 if (checked
) return;
1104 if (!my_type
) FATAL_ERROR("UnparsedMultipleInnerTypeConstraint::chk()");
1105 Error_Context
cntxt(this, "While checking inner type constraint");
1106 Type
* t
= my_type
->get_type_refd_last();
1107 switch (t
->get_typetype()) {
1108 case Type::T_REAL
: // associated ASN.1 type is a SEQUENCE
1109 case Type::T_CHOICE_A
:
1110 case Type::T_SEQ_A
: // also refd by T_EXTERNAL, T_EMBEDDED_PDV and T_UNRESTRICTEDSTRING
1114 error("Multiple inner type constraint (WITH COMPONENTS) cannot be used on type `%s'", my_type
->get_typename().c_str());
1117 Node
*node
= block
->parse(KW_Block_MultipleTypeConstraints
);
1118 constraint
= dynamic_cast<MultipleInnerTypeConstraint
*>(node
);
1121 return; // parsing error was already reported
1123 constraint
->set_my_type(my_type
);
1124 constraint
->set_my_scope(get_my_scope());
1125 constraint
->set_my_parent(this);
1127 subtype
= new SubtypeConstraint(my_type
->get_subtype_type()); // ignored
1130 void UnparsedMultipleInnerTypeConstraint::set_fullname(const string
& p_fullname
)
1132 Node::set_fullname(p_fullname
);
1133 block
->set_fullname(p_fullname
);
1134 if (constraint
) constraint
->set_fullname(p_fullname
);
1137 } // namespace Common