Sync with 5.1.0
[deliverable/titan.core.git] / compiler2 / asn1 / TableConstraint.cc
CommitLineData
970ed795
EL
1///////////////////////////////////////////////////////////////////////////////
2// Copyright (c) 2000-2014 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"
10#include "Object.hh"
11#include "Ref.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.
15
16#include "../CompField.hh"
17
18namespace Asn {
19
20 // =================================
21 // ===== AtNotation
22 // =================================
23
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)
27 {
28 if(!p_cids)
29 FATAL_ERROR("NULL parameter: Asn::AtNotation::AtNotation()");
30 }
31
32 AtNotation::AtNotation(const AtNotation& p)
33 : Node(p), levels(p.levels), oc_fieldname(0),
34 firstcomp(0), lastcomp(0)
35 {
36 cids=p.cids->clone();
37 }
38
39 AtNotation::~AtNotation()
40 {
41 delete cids;
42 delete oc_fieldname;
43 }
44
45 void AtNotation::set_oc_fieldname(const Identifier& p_oc_fieldname)
46 {
47 if(oc_fieldname)
48 FATAL_ERROR("Asn::AtNotation::set_ocfieldname()");
49 oc_fieldname=p_oc_fieldname.clone();
50 }
51
52 string AtNotation::get_dispname() const
53 {
54 string s('@');
55 for(int i=0; i<levels; i++) s+=".";
56 s+=cids->get_dispname();
57 return s;
58 }
59
60 // =================================
61 // ===== AtNotations
62 // =================================
63
64 AtNotations::AtNotations(const AtNotations& p)
65 : Node(p)
66 {
67 for(size_t i=0; i<p.ans.size(); i++)
68 ans.add(p.ans[i]->clone());
69 }
70
71 AtNotations::~AtNotations()
72 {
73 for(size_t i=0; i<ans.size(); i++) delete ans[i];
74 ans.clear();
75 }
76
77 void AtNotations::add_an(AtNotation *p_an)
78 {
79 if(!p_an)
80 FATAL_ERROR("NULL parameter: Asn::AtNotations::add_an()");
81 ans.add(p_an);
82 }
83
84 // =================================
85 // ===== TableConstraint
86 // =================================
87
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)
91 {
92 if(!block_os)
93 FATAL_ERROR("NULL parameter: Asn::TableConstraint::TableConstraint()");
94 }
95
96 TableConstraint::TableConstraint(const TableConstraint& p)
97 : Constraint(p), consdtype(0), oc_fieldname(0)
98 {
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;
103 }
104
105 TableConstraint::~TableConstraint()
106 {
107 delete block_os;
108 delete block_ans;
109 delete os;
110 delete ans;
111 }
112
113 void TableConstraint::chk()
114 {
115 if(checked) return;
116 checked=true;
117 parse_blocks();
118 if(!my_type)
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)
124 consdtype=my_type;
125 bool ok=false;
126 while(true) {
127 Type::typetype_t t=consdtype->get_typetype();
128 if(t==Type::T_OPENTYPE || t==Type::T_OCFT) {
129 ok=true;
130 break;
131 }
132 else if(t==Type::T_ERROR) {
133 return;
134 }
135 else if(consdtype->is_ref())
136 consdtype=consdtype->get_type_refd();
137 else break;
138 }
139 if(!ok) {
140 my_type->error("TableConstraint can only be applied to"
141 " ObjectClassFieldType");
142 return;
143 }
144 // consdtype is ok
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());
149 os->chk();
150 }
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());
155 os->chk();
156 if(ans) {
157 // componentrelationconstraint...
158 // search the outermost textually enclosing seq, set or choice
159 Type *outermostparent=0;
160 Type *t_type=my_type;
161 do {
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)");
168 return;
169 }
170 outermostparent->set_opentype_outermost();
171 // set has_opentypes for enclosing types
172 t_type=my_type;
173 do {
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);
180 Type *parent = NULL;
181 if(an->get_levels()==0) parent=outermostparent;
182 else {
183 parent=my_type;
184 for(int level=an->get_levels(); level>0; level--) {
185 parent=parent->get_parent_type();
186 if(!parent) {
187 my_type->error("Too many dots. This component has only"
188 " %d parents.", an->get_levels()-level);
189 return;
190 } // ! parent
191 } // for level
192 } // not the outermost
193 t_type=parent;
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());
201 return;
202 } // ! secho
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());
208 return;
209 } // no component with that name
210 t_type=t_type->get_comp_byName(*id)->get_type();
211 } // for j
212 an->set_lastcomp(t_type);
213 /* check if the referenced component is constrained by the
214 * same objectset... */
215 ok=false;
216 do {
217 // t_type->chk_constraints();
218 Constraints *t_cons=t_type->get_constraints();
219 if(!t_cons) break;
220 t_cons->chk_table();
221 TableConstraint *t_tc=dynamic_cast<TableConstraint*>
222 (t_cons->get_tableconstraint());
223 if(!t_tc) break;
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;
229 ok=true;
230 } while(false);
231 if(!ok) {
232 my_type->error
233 ("The referenced components must be value (set) fields"
234 " constrained by the same objectset"
235 " as the referencing component");
236 return;
237 }
238 } // for i
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))
248 continue;
249 t_type=dynamic_cast<Type*>
250 (obj->get_setting_byName_dflt(*oc_fieldname));
251 bool is_strange;
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(),
257 otype));
258 const char *dispname_str = altname.get_dispname().c_str();
259 DEBUG(2, "Alternative `%s' added", dispname_str);
260 if (is_strange)
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
264 } // for i (objs)
265 t_ot->set_my_scope(t_ot->get_my_scope());
266 t_ot->set_fullname(t_ot->get_fullname());
267 t_ot->chk();
268 } // if ans
269 } // opentype check
270
271 // this cannot be inside another constraint
272 if (my_parent) {
273 error("Table constraint cannot be inside a %s", my_parent->get_name());
274 }
275
276 } // member function
277
278 void TableConstraint::parse_blocks()
279 {
280 if(block_os) {
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;
288 if(!ans)
289 /* syntax error */
290 ans=new AtNotations();
291 }
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;
296 }
297 if(!os) {
298 /* syntax error */
299 os=new OS_defn();
300 }
301 }
302 }
303
304} // namespace Asn
This page took 0.034242 seconds and 5 git commands to generate.