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
13 ******************************************************************************/
14 #include "TableConstraint.hh"
15 #include "../Identifier.hh"
18 #include "TokenBuf.hh"
19 // FIXME TableConstraint does not use Token or TokenBuf at all.
20 // TokenBuf.hh just happens to drag in everything that TableConstraint needs.
22 #include "../CompField.hh"
26 // =================================
28 // =================================
30 AtNotation::AtNotation(int p_levels
, FieldName
*p_cids
)
31 : Node(), levels(p_levels
), cids(p_cids
), oc_fieldname(0),
32 firstcomp(0), lastcomp(0)
35 FATAL_ERROR("NULL parameter: Asn::AtNotation::AtNotation()");
38 AtNotation::AtNotation(const AtNotation
& p
)
39 : Node(p
), levels(p
.levels
), oc_fieldname(0),
40 firstcomp(0), lastcomp(0)
45 AtNotation::~AtNotation()
51 void AtNotation::set_oc_fieldname(const Identifier
& p_oc_fieldname
)
54 FATAL_ERROR("Asn::AtNotation::set_ocfieldname()");
55 oc_fieldname
=p_oc_fieldname
.clone();
58 string
AtNotation::get_dispname() const
61 for(int i
=0; i
<levels
; i
++) s
+=".";
62 s
+=cids
->get_dispname();
66 // =================================
68 // =================================
70 AtNotations::AtNotations(const AtNotations
& p
)
73 for(size_t i
=0; i
<p
.ans
.size(); i
++)
74 ans
.add(p
.ans
[i
]->clone());
77 AtNotations::~AtNotations()
79 for(size_t i
=0; i
<ans
.size(); i
++) delete ans
[i
];
83 void AtNotations::add_an(AtNotation
*p_an
)
86 FATAL_ERROR("NULL parameter: Asn::AtNotations::add_an()");
90 // =================================
91 // ===== TableConstraint
92 // =================================
94 TableConstraint::TableConstraint(Block
*p_block_os
, Block
*p_block_ans
)
95 : Constraint(CT_TABLE
), block_os(p_block_os
), block_ans(p_block_ans
),
96 os(0), ans(0), consdtype(0), oc_fieldname(0)
99 FATAL_ERROR("NULL parameter: Asn::TableConstraint::TableConstraint()");
102 TableConstraint::TableConstraint(const TableConstraint
& p
)
103 : Constraint(p
), consdtype(0), oc_fieldname(0)
105 block_os
=p
.block_os
?p
.block_os
->clone():0;
106 block_ans
=p
.block_ans
?p
.block_ans
->clone():0;
107 os
=p
.os
?p
.os
->clone():0;
108 ans
=p
.ans
?p
.ans
->clone():0;
111 TableConstraint::~TableConstraint()
119 void TableConstraint::chk()
125 FATAL_ERROR("Asn::TableConstraint::chk()");
126 os
->set_my_scope(my_type
->get_my_scope());
127 os
->set_fullname(my_type
->get_fullname()+".<tableconstraint-os>");
128 os
->set_genname(my_type
->get_genname_own(), string("os"));
129 // search the constrained type (not the reference to it)
133 Type::typetype_t t
=consdtype
->get_typetype();
134 if(t
==Type::T_OPENTYPE
|| t
==Type::T_OCFT
) {
138 else if(t
==Type::T_ERROR
) {
141 else if(consdtype
->is_ref())
142 consdtype
=consdtype
->get_type_refd();
146 my_type
->error("TableConstraint can only be applied to"
147 " ObjectClassFieldType");
151 if(consdtype
->get_typetype()==Type::T_OCFT
) {
152 // componentrelationconstraint ignored for this...
153 oc_fieldname
=&consdtype
->get_oc_fieldname();
154 os
->set_my_governor(consdtype
->get_my_oc());
157 else if(consdtype
->get_typetype()==Type::T_OPENTYPE
) {
158 consdtype
->set_my_tableconstraint(this);
159 oc_fieldname
=&consdtype
->get_oc_fieldname();
160 os
->set_my_governor(consdtype
->get_my_oc());
163 // componentrelationconstraint...
164 // search the outermost textually enclosing seq, set or choice
165 Type
*outermostparent
=0;
166 Type
*t_type
=my_type
;
168 if(t_type
->is_secho())
169 outermostparent
=t_type
;
170 } while((t_type
=t_type
->get_parent_type()));
171 if(!outermostparent
) {
172 my_type
->error("Invalid use of ComponentRelationConstraint"
173 " (cannot determine parent type)");
176 outermostparent
->set_opentype_outermost();
177 // set has_opentypes for enclosing types
180 t_type
=t_type
->get_parent_type();
181 t_type
->set_has_opentypes();
182 } while(t_type
!=outermostparent
);
183 // checking of atnotations
184 for(size_t i
=0; i
<ans
->get_nof_ans(); i
++) {
185 AtNotation
*an
=ans
->get_an_byIndex(i
);
187 if(an
->get_levels()==0) parent
=outermostparent
;
190 for(int level
=an
->get_levels(); level
>0; level
--) {
191 parent
=parent
->get_parent_type();
193 my_type
->error("Too many dots. This component has only"
194 " %d parents.", an
->get_levels()-level
);
198 } // not the outermost
200 an
->set_firstcomp(parent
);
201 // component identifiers... do they exist?
202 FieldName
* cids
=an
->get_cids();
203 for(size_t j
=0; j
<cids
->get_nof_fields(); j
++) {
204 if(!t_type
->is_secho()) {
205 my_type
->error("Type `%s' is not a SEQUENCE, SET of CHOICE"
206 " type.", t_type
->get_fullname().c_str());
209 const Identifier
*id
=cids
->get_field_byIndex(j
);
210 if(!t_type
->has_comp_withName(*id
)) {
211 my_type
->error("Type `%s' has no component with name `%s'.",
212 t_type
->get_fullname().c_str(),
213 id
->get_dispname().c_str());
215 } // no component with that name
216 t_type
=t_type
->get_comp_byName(*id
)->get_type();
218 an
->set_lastcomp(t_type
);
219 /* check if the referenced component is constrained by the
220 * same objectset... */
223 // t_type->chk_constraints();
224 Constraints
*t_cons
=t_type
->get_constraints();
227 TableConstraint
*t_tc
=dynamic_cast<TableConstraint
*>
228 (t_cons
->get_tableconstraint());
230 Type
*t_ocft
=t_tc
->consdtype
;
231 if(t_ocft
->get_typetype()!=Type::T_OCFT
) break;
232 an
->set_oc_fieldname(t_ocft
->get_oc_fieldname());
233 // is the same objectset?
234 if(t_tc
->os
->get_refd_last()!=os
->get_refd_last()) break;
239 ("The referenced components must be value (set) fields"
240 " constrained by the same objectset"
241 " as the referencing component");
245 // well, the atnotations seems to be ok, let's produce the
246 // alternatives for the opentype
247 Type
*t_ot
=consdtype
; // opentype
248 DEBUG(1, "Adding alternatives to open type `%s'",
249 t_ot
->get_fullname().c_str());
250 Objects
*objs
=os
->get_refd_last()->get_objs();
251 for(size_t i
=0; i
<objs
->get_nof_objs(); i
++) {
252 Obj_defn
*obj
=objs
->get_obj_byIndex(i
);
253 if(!obj
->has_fs_withName_dflt(*oc_fieldname
))
255 t_type
=dynamic_cast<Type
*>
256 (obj
->get_setting_byName_dflt(*oc_fieldname
));
258 const Common::Identifier
& altname
= t_type
->get_otaltname(is_strange
);
259 if(!t_ot
->has_comp_withName(altname
)) {
260 Type
* otype
= new Type(Type::T_REFDSPEC
, t_type
);
261 otype
->set_genname(t_type
->get_genname_own());
262 t_ot
->add_comp(new CompField(altname
.clone(),
264 const char *dispname_str
= altname
.get_dispname().c_str();
265 DEBUG(2, "Alternative `%s' added", dispname_str
);
267 t_ot
->warning("Strange alternative name (`%s') was added to "
268 "open type `%s'", dispname_str
, t_ot
->get_fullname().c_str());
269 } // t_ot ! has the type
271 t_ot
->set_my_scope(t_ot
->get_my_scope());
272 t_ot
->set_fullname(t_ot
->get_fullname());
277 // this cannot be inside another constraint
279 error("Table constraint cannot be inside a %s", my_parent
->get_name());
284 void TableConstraint::parse_blocks()
287 if(block_ans
) { // ComponentRelationConstraint
288 Node
*node
=block_os
->parse(KW_Block_DefinedObjectSetBlock
);
289 os
=dynamic_cast<ObjectSet
*>(node
);
290 delete block_os
; block_os
=0;
291 node
=block_ans
->parse(KW_Block_AtNotationList
);
292 ans
=dynamic_cast<AtNotations
*>(node
);
293 delete block_ans
; block_ans
=0;
296 ans
=new AtNotations();
298 else { // SimpleTableConstraint
299 Node
*node
=block_os
->parse(KW_Block_ObjectSetSpec
);
300 os
=dynamic_cast<ObjectSet
*>(node
);
301 delete block_os
; block_os
=0;