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 "TableConstraint.hh"
9 #include "../Identifier.hh"
12 #include "TokenBuf.hh"
13 // FIXME TableConstraint does not use Token or TokenBuf at all.
14 // TokenBuf.hh just happens to drag in everything that TableConstraint needs.
16 #include "../CompField.hh"
20 // =================================
22 // =================================
24 AtNotation::AtNotation(int p_levels
, FieldName
*p_cids
)
25 : Node(), levels(p_levels
), cids(p_cids
), oc_fieldname(0),
26 firstcomp(0), lastcomp(0)
29 FATAL_ERROR("NULL parameter: Asn::AtNotation::AtNotation()");
32 AtNotation::AtNotation(const AtNotation
& p
)
33 : Node(p
), levels(p
.levels
), oc_fieldname(0),
34 firstcomp(0), lastcomp(0)
39 AtNotation::~AtNotation()
45 void AtNotation::set_oc_fieldname(const Identifier
& p_oc_fieldname
)
48 FATAL_ERROR("Asn::AtNotation::set_ocfieldname()");
49 oc_fieldname
=p_oc_fieldname
.clone();
52 string
AtNotation::get_dispname() const
55 for(int i
=0; i
<levels
; i
++) s
+=".";
56 s
+=cids
->get_dispname();
60 // =================================
62 // =================================
64 AtNotations::AtNotations(const AtNotations
& p
)
67 for(size_t i
=0; i
<p
.ans
.size(); i
++)
68 ans
.add(p
.ans
[i
]->clone());
71 AtNotations::~AtNotations()
73 for(size_t i
=0; i
<ans
.size(); i
++) delete ans
[i
];
77 void AtNotations::add_an(AtNotation
*p_an
)
80 FATAL_ERROR("NULL parameter: Asn::AtNotations::add_an()");
84 // =================================
85 // ===== TableConstraint
86 // =================================
88 TableConstraint::TableConstraint(Block
*p_block_os
, Block
*p_block_ans
)
89 : Constraint(CT_TABLE
), block_os(p_block_os
), block_ans(p_block_ans
),
90 os(0), ans(0), consdtype(0), oc_fieldname(0)
93 FATAL_ERROR("NULL parameter: Asn::TableConstraint::TableConstraint()");
96 TableConstraint::TableConstraint(const TableConstraint
& p
)
97 : Constraint(p
), consdtype(0), oc_fieldname(0)
99 block_os
=p
.block_os
?p
.block_os
->clone():0;
100 block_ans
=p
.block_ans
?p
.block_ans
->clone():0;
101 os
=p
.os
?p
.os
->clone():0;
102 ans
=p
.ans
?p
.ans
->clone():0;
105 TableConstraint::~TableConstraint()
113 void TableConstraint::chk()
119 FATAL_ERROR("Asn::TableConstraint::chk()");
120 os
->set_my_scope(my_type
->get_my_scope());
121 os
->set_fullname(my_type
->get_fullname()+".<tableconstraint-os>");
122 os
->set_genname(my_type
->get_genname_own(), string("os"));
123 // search the constrained type (not the reference to it)
127 Type::typetype_t t
=consdtype
->get_typetype();
128 if(t
==Type::T_OPENTYPE
|| t
==Type::T_OCFT
) {
132 else if(t
==Type::T_ERROR
) {
135 else if(consdtype
->is_ref())
136 consdtype
=consdtype
->get_type_refd();
140 my_type
->error("TableConstraint can only be applied to"
141 " ObjectClassFieldType");
145 if(consdtype
->get_typetype()==Type::T_OCFT
) {
146 // componentrelationconstraint ignored for this...
147 oc_fieldname
=&consdtype
->get_oc_fieldname();
148 os
->set_my_governor(consdtype
->get_my_oc());
151 else if(consdtype
->get_typetype()==Type::T_OPENTYPE
) {
152 consdtype
->set_my_tableconstraint(this);
153 oc_fieldname
=&consdtype
->get_oc_fieldname();
154 os
->set_my_governor(consdtype
->get_my_oc());
157 // componentrelationconstraint...
158 // search the outermost textually enclosing seq, set or choice
159 Type
*outermostparent
=0;
160 Type
*t_type
=my_type
;
162 if(t_type
->is_secho())
163 outermostparent
=t_type
;
164 } while((t_type
=t_type
->get_parent_type()));
165 if(!outermostparent
) {
166 my_type
->error("Invalid use of ComponentRelationConstraint"
167 " (cannot determine parent type)");
170 outermostparent
->set_opentype_outermost();
171 // set has_opentypes for enclosing types
174 t_type
=t_type
->get_parent_type();
175 t_type
->set_has_opentypes();
176 } while(t_type
!=outermostparent
);
177 // checking of atnotations
178 for(size_t i
=0; i
<ans
->get_nof_ans(); i
++) {
179 AtNotation
*an
=ans
->get_an_byIndex(i
);
181 if(an
->get_levels()==0) parent
=outermostparent
;
184 for(int level
=an
->get_levels(); level
>0; level
--) {
185 parent
=parent
->get_parent_type();
187 my_type
->error("Too many dots. This component has only"
188 " %d parents.", an
->get_levels()-level
);
192 } // not the outermost
194 an
->set_firstcomp(parent
);
195 // component identifiers... do they exist?
196 FieldName
* cids
=an
->get_cids();
197 for(size_t j
=0; j
<cids
->get_nof_fields(); j
++) {
198 if(!t_type
->is_secho()) {
199 my_type
->error("Type `%s' is not a SEQUENCE, SET of CHOICE"
200 " type.", t_type
->get_fullname().c_str());
203 const Identifier
*id
=cids
->get_field_byIndex(j
);
204 if(!t_type
->has_comp_withName(*id
)) {
205 my_type
->error("Type `%s' has no component with name `%s'.",
206 t_type
->get_fullname().c_str(),
207 id
->get_dispname().c_str());
209 } // no component with that name
210 t_type
=t_type
->get_comp_byName(*id
)->get_type();
212 an
->set_lastcomp(t_type
);
213 /* check if the referenced component is constrained by the
214 * same objectset... */
217 // t_type->chk_constraints();
218 Constraints
*t_cons
=t_type
->get_constraints();
221 TableConstraint
*t_tc
=dynamic_cast<TableConstraint
*>
222 (t_cons
->get_tableconstraint());
224 Type
*t_ocft
=t_tc
->consdtype
;
225 if(t_ocft
->get_typetype()!=Type::T_OCFT
) break;
226 an
->set_oc_fieldname(t_ocft
->get_oc_fieldname());
227 // is the same objectset?
228 if(t_tc
->os
->get_refd_last()!=os
->get_refd_last()) break;
233 ("The referenced components must be value (set) fields"
234 " constrained by the same objectset"
235 " as the referencing component");
239 // well, the atnotations seems to be ok, let's produce the
240 // alternatives for the opentype
241 Type
*t_ot
=consdtype
; // opentype
242 DEBUG(1, "Adding alternatives to open type `%s'",
243 t_ot
->get_fullname().c_str());
244 Objects
*objs
=os
->get_refd_last()->get_objs();
245 for(size_t i
=0; i
<objs
->get_nof_objs(); i
++) {
246 Obj_defn
*obj
=objs
->get_obj_byIndex(i
);
247 if(!obj
->has_fs_withName_dflt(*oc_fieldname
))
249 t_type
=dynamic_cast<Type
*>
250 (obj
->get_setting_byName_dflt(*oc_fieldname
));
252 const Common::Identifier
& altname
= t_type
->get_otaltname(is_strange
);
253 if(!t_ot
->has_comp_withName(altname
)) {
254 Type
* otype
= new Type(Type::T_REFDSPEC
, t_type
);
255 otype
->set_genname(t_type
->get_genname_own());
256 t_ot
->add_comp(new CompField(altname
.clone(),
258 const char *dispname_str
= altname
.get_dispname().c_str();
259 DEBUG(2, "Alternative `%s' added", dispname_str
);
261 t_ot
->warning("Strange alternative name (`%s') was added to "
262 "open type `%s'", dispname_str
, t_ot
->get_fullname().c_str());
263 } // t_ot ! has the type
265 t_ot
->set_my_scope(t_ot
->get_my_scope());
266 t_ot
->set_fullname(t_ot
->get_fullname());
271 // this cannot be inside another constraint
273 error("Table constraint cannot be inside a %s", my_parent
->get_name());
278 void TableConstraint::parse_blocks()
281 if(block_ans
) { // ComponentRelationConstraint
282 Node
*node
=block_os
->parse(KW_Block_DefinedObjectSetBlock
);
283 os
=dynamic_cast<ObjectSet
*>(node
);
284 delete block_os
; block_os
=0;
285 node
=block_ans
->parse(KW_Block_AtNotationList
);
286 ans
=dynamic_cast<AtNotations
*>(node
);
287 delete block_ans
; block_ans
=0;
290 ans
=new AtNotations();
292 else { // SimpleTableConstraint
293 Node
*node
=block_os
->parse(KW_Block_ObjectSetSpec
);
294 os
=dynamic_cast<ObjectSet
*>(node
);
295 delete block_os
; block_os
=0;