Titan Core Initial Contribution
[deliverable/titan.core.git] / compiler2 / Valuestuff.cc
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 "Valuestuff.hh"
9 #include "Identifier.hh"
10 #include "Value.hh"
11 #include "asn1/Object0.hh"
12 #include "asn1/Block.hh"
13 #include "asn1/TokenBuf.hh"
14 #include <limits.h>
15
16 #include "ustring.hh"
17
18 namespace Common {
19
20 // =================================
21 // ===== Values
22 // =================================
23
24 Values::Values(bool p_indexed) : Node(), indexed(p_indexed)
25 {
26 if (!p_indexed) vs = new vector<Value>();
27 else ivs = new vector<IndexedValue>();
28 }
29
30 Values::~Values()
31 {
32 if (!indexed) {
33 for (size_t i = 0; i < vs->size(); i++) delete (*vs)[i];
34 vs->clear();
35 delete vs;
36 } else {
37 for (size_t i = 0; i < ivs->size(); i++) delete (*ivs)[i];
38 ivs->clear();
39 delete ivs;
40 }
41 }
42
43 Values *Values::clone() const
44 {
45 FATAL_ERROR("Values::clone");
46 }
47
48 void Values::set_fullname(const string& p_fullname)
49 {
50 Node::set_fullname(p_fullname);
51 if (!indexed) {
52 for (size_t i = 0; i < vs->size(); i++) {
53 Value *v = (*vs)[i];
54 if (v) v->set_fullname(p_fullname + "[" + Int2string(i) + "]");
55 }
56 } else {
57 for (size_t i = 0; i < ivs->size(); i++) {
58 IndexedValue *iv = (*ivs)[i];
59 // The order is defined by the user. The index used, doesn't really
60 // matter here.
61 if (iv) iv->set_fullname(p_fullname + "[" + Int2string(i) + "]");
62 }
63 }
64 }
65
66 void Values::set_my_scope(Scope *p_scope)
67 {
68 if (!indexed) {
69 for (size_t i = 0; i < vs->size(); i++) {
70 Value *v = (*vs)[i];
71 if (v) v->set_my_scope(p_scope);
72 }
73 } else {
74 for (size_t i = 0; i < ivs->size(); i++) {
75 IndexedValue *iv = (*ivs)[i];
76 if (iv) iv->set_my_scope(p_scope);
77 }
78 }
79 }
80
81 size_t Values::get_nof_vs() const
82 {
83 if (indexed) FATAL_ERROR("Values::get_nof_vs()");
84 return vs->size();
85 }
86
87 size_t Values::get_nof_ivs() const
88 {
89 if (!indexed) FATAL_ERROR("Values::get_nof_ivs()");
90 return ivs->size();
91 }
92
93 Value *Values::get_v_byIndex(size_t p_i) const
94 {
95 if (indexed) FATAL_ERROR("Values::get_v_byIndex");
96 return (*vs)[p_i];
97 }
98
99 IndexedValue *Values::get_iv_byIndex(size_t p_i) const
100 {
101 if (!indexed) FATAL_ERROR("Values::get_iv_byIndex()");
102 return (*ivs)[p_i];
103 }
104
105 void Values::add_v(Value *p_v)
106 {
107 if (!p_v) FATAL_ERROR("Values::add_v(): NULL parameter");
108 if (indexed) FATAL_ERROR("Values::add_v()");
109 vs->add(p_v);
110 }
111
112 void Values::add_iv(IndexedValue *p_iv)
113 {
114 if (!p_iv) FATAL_ERROR("Values::add_iv(): NULL parameter");
115 if (!indexed) FATAL_ERROR("Values::add_iv()");
116 ivs->add(p_iv);
117 }
118
119 Value *Values::steal_v_byIndex(size_t p_i)
120 {
121 if (indexed) FATAL_ERROR("Values::steal_v_byIndex()");
122 Value *ret_val = (*vs)[p_i];
123 if (!ret_val) FATAL_ERROR("Values::steal_v_byIndex()");
124 (*vs)[p_i] = NULL;
125 return ret_val;
126 }
127
128 void Values::dump(unsigned level) const
129 {
130 if (!indexed) {
131 for (size_t i = 0; i < vs->size(); i++) {
132 Value *v = (*vs)[i];
133 if (v) v->dump(level);
134 else DEBUG(level, "Value: stolen");
135 }
136 } else {
137 for (size_t i = 0; i < ivs->size(); i++) {
138 IndexedValue *iv = (*ivs)[i];
139 if (iv) iv->dump(level);
140 else DEBUG(level, "Value: stolen");
141 }
142 }
143 }
144
145 // =================================
146 // ===== IndexedValue
147 // =================================
148
149 IndexedValue::IndexedValue(Ttcn::FieldOrArrayRef *p_index, Value *p_value)
150 : Node(), Location(), index(p_index), value(p_value)
151 {
152 if (!p_index || !p_value)
153 FATAL_ERROR("NULL parameter: IndexedValue::IndexedValue()");
154 }
155
156 IndexedValue::~IndexedValue()
157 {
158 delete index;
159 delete value;
160 }
161
162 IndexedValue *IndexedValue::clone() const
163 {
164 FATAL_ERROR("IndexedValue::clone");
165 }
166
167 void IndexedValue::set_fullname(const string& p_fullname)
168 {
169 Node::set_fullname(p_fullname);
170 if (value) value->set_fullname(p_fullname);
171 if (index) index->set_fullname(p_fullname);
172 }
173
174 void IndexedValue::set_my_scope(Scope *p_scope)
175 {
176 if (value) value->set_my_scope(p_scope);
177 if (index) index->set_my_scope(p_scope);
178 }
179
180 void IndexedValue::set_code_section
181 (GovernedSimple::code_section_t p_code_section)
182 {
183 // Follow the style and add ifs everywhere...
184 if (index) index->get_val()->set_code_section(p_code_section);
185 if (value) value->set_code_section(p_code_section);
186 }
187
188 Value *IndexedValue::steal_value()
189 {
190 if (!value) FATAL_ERROR("IndexedValue::steal_value()");
191 Value *tmp = value;
192 value = 0;
193 return tmp;
194 }
195
196 void IndexedValue::dump(unsigned level) const
197 {
198 index->dump(level);
199 if (value) value->dump(level + 1);
200 else DEBUG(level + 1, "Value: stolen");
201 }
202
203 bool IndexedValue::is_unfoldable(ReferenceChain *refch,
204 Type::expected_value_t exp_val)
205 {
206 return (value->is_unfoldable(refch, exp_val) ||
207 get_index()->is_unfoldable(refch, exp_val));
208 }
209
210 // =================================
211 // ===== NamedValue
212 // =================================
213
214 NamedValue::NamedValue(Identifier *p_name, Value *p_value)
215 : Node(), Location(), name(p_name), value(p_value)
216 {
217 if (!p_name || !p_value)
218 FATAL_ERROR("NULL parameter: NamedValue::NamedValue()");
219 }
220
221 NamedValue::NamedValue(const NamedValue& p)
222 : Node(p), Location(p)
223 {
224 if (!p.value) FATAL_ERROR("NamedValue::NamedValue(): value is stolen");
225 name = p.name->clone();
226 value = p.value->clone();
227 }
228
229 NamedValue::~NamedValue()
230 {
231 delete name;
232 delete value;
233 }
234
235 NamedValue *NamedValue::clone() const
236 {
237 return new NamedValue(*this);
238 }
239
240 void NamedValue::set_fullname(const string& p_fullname)
241 {
242 Node::set_fullname(p_fullname);
243 if (value) value->set_fullname(p_fullname);
244 }
245
246 void NamedValue::set_my_scope(Scope *p_scope)
247 {
248 if (value) value->set_my_scope(p_scope);
249 }
250
251 Value *NamedValue::steal_value()
252 {
253 if (!value) FATAL_ERROR("NamedValue::steal_value()");
254 Value *tmp = value;
255 value = 0;
256 return tmp;
257 }
258
259 void NamedValue::dump(unsigned level) const
260 {
261 name->dump(level);
262 if (value) value->dump(level + 1);
263 else DEBUG(level + 1, "Value: stolen");
264 }
265
266 // =================================
267 // ===== NamedValues
268 // =================================
269
270 NamedValues::NamedValues(const NamedValues& p)
271 : Node(p), checked(false)
272 {
273 for (size_t i = 0; i < p.nvs_v.size(); i++)
274 nvs_v.add(p.nvs_v[i]->clone());
275 }
276
277 NamedValues::~NamedValues()
278 {
279 for(size_t i = 0; i < nvs_v.size(); i++) delete nvs_v[i];
280 nvs_v.clear();
281 nvs_m.clear();
282 }
283
284 NamedValues *NamedValues::clone() const
285 {
286 return new NamedValues(*this);
287 }
288
289 void NamedValues::set_fullname(const string& p_fullname)
290 {
291 Node::set_fullname(p_fullname);
292 for(size_t i = 0; i < nvs_v.size(); i++) {
293 NamedValue *nv = nvs_v[i];
294 nv->set_fullname(p_fullname + "." + nv->get_name().get_dispname());
295 }
296 }
297
298 void NamedValues::set_my_scope(Scope *p_scope)
299 {
300 for (size_t i = 0; i < nvs_v.size(); i++)
301 nvs_v[i]->set_my_scope(p_scope);
302 }
303
304 void NamedValues::add_nv(NamedValue *p_nv)
305 {
306 if (!p_nv) FATAL_ERROR("NamedValues::add_nv(): NULL parameter");
307 nvs_v.add(p_nv);
308 if (checked) {
309 const string& name = p_nv->get_name().get_name();
310 if (nvs_m.has_key(name)) FATAL_ERROR("NamedValues::add_nv()");
311 nvs_m.add(name, p_nv);
312 }
313 }
314
315 bool NamedValues::has_nv_withName(const Identifier& p_name)
316 {
317 if (!checked) chk_dupl_id(false);
318 return nvs_m.has_key(p_name.get_name());
319 }
320
321 NamedValue* NamedValues::get_nv_byName(const Identifier& p_name)
322 {
323 if (!checked) chk_dupl_id(false);
324 return nvs_m[p_name.get_name()];
325 }
326
327 void NamedValues::chk_dupl_id(bool report_errors)
328 {
329 if (checked) nvs_m.clear();
330 for (size_t i = 0; i < nvs_v.size(); i++) {
331 NamedValue *nv = nvs_v[i];
332 const Identifier& id = nv->get_name();
333 const string& name = id.get_name();
334 if (!nvs_m.has_key(name)) nvs_m.add(name, nv);
335 else if (report_errors) {
336 const char *dispname_str = id.get_dispname().c_str();
337 nv->error("Duplicate identifier: `%s'", dispname_str);
338 nvs_m[name]->note("Previous definition of `%s' is here", dispname_str);
339 }
340 }
341 checked = true;
342 }
343
344 void NamedValues::dump(unsigned level) const
345 {
346 for (size_t i = 0; i < nvs_v.size(); i++)
347 nvs_v[i]->dump(level);
348 }
349
350 // =================================
351 // ===== OID_comp
352 // =================================
353
354 const OID_comp::nameform_t OID_comp::names_root[] = {
355 { "itu__t", 0 },
356 { "ccitt", 0 },
357 { "itu__r", 0 },
358 { "iso", 1 },
359 { "joint__iso__itu__t", 2 },
360 { "joint__iso__ccitt", 2 },
361 { NULL, 0 }
362 };
363
364 const OID_comp::nameform_t OID_comp::names_itu[] = {
365 { "recommendation", 0 },
366 { "question", 1 },
367 { "administration", 2 },
368 { "network__operator", 3 },
369 { "identified__organization", 4 },
370 { "r__recommendation", 5 },
371 { NULL, 0 }
372 };
373
374 const OID_comp::nameform_t OID_comp::names_iso[] = {
375 { "standard", 0 },
376 { "registration__authority", 1 },
377 { "member__body", 2 },
378 { "identified__organization", 3 },
379 { NULL, 0 }
380 };
381
382 // taken from OID repository: http://asn1.elibel.tm.fr/oid/
383 const OID_comp::nameform_t OID_comp::names_joint[] = {
384 { "presentation", 0 },
385 { "asn1", 1 },
386 { "association__control", 2 },
387 { "reliable__transfer", 3 },
388 { "remote__operations", 4 },
389 { "ds", 5 },
390 { "directory", 5 },
391 { "mhs", 6 },
392 { "mhs__motis", 6 },
393 { "ccr", 7 },
394 { "oda", 8 },
395 { "ms", 9 },
396 { "osi__management", 9 },
397 { "transaction__processing", 10 },
398 { "dor", 11 },
399 { "distinguished__object__reference", 11 },
400 { "reference__data__transfer", 12 },
401 { "network__layer", 13 },
402 { "network__layer__management", 13 },
403 { "transport__layer", 14 },
404 { "transport__layer__management", 14 },
405 { "datalink__layer", 15 },
406 { "datalink__layer__management", 15 },
407 { "datalink__layer__management__information", 15 },
408 { "country", 16 },
409 { "registration__procedures", 17 },
410 { "registration__procedure", 17 },
411 { "physical__layer", 18 },
412 { "physical__layer__management", 18 },
413 { "mheg", 19 },
414 { "genericULS", 20 },
415 { "generic__upper__layers__security", 20 },
416 { "guls", 20 },
417 { "transport__layer__security__protocol", 21 },
418 { "network__layer__security__protocol", 22 },
419 { "international__organizations", 23 },
420 { "internationalRA", 23 },
421 { "sios", 24 },
422 { "uuid", 25 },
423 { "odp", 26 },
424 { "upu", 40 },
425 { NULL, 0 }
426 };
427
428 OID_comp::OID_comp(Identifier *p_name, Value *p_number)
429 : Node(), Location(), defdval(0), name(p_name), number(p_number), var(0)
430 {
431 if (p_name) {
432 if (p_number) formtype = NAMEANDNUMBERFORM;
433 else formtype = NAMEFORM;
434 } else {
435 if (p_number) formtype = NUMBERFORM;
436 else FATAL_ERROR("NULL parameter: Common::OID_comp::OID_comp()");
437 }
438 }
439
440 OID_comp::OID_comp(Value *p_defdval)
441 : Node(), Location(), formtype(DEFDVALUE), defdval(p_defdval), name(0),
442 number(0), var(0)
443 {
444 if(!p_defdval)
445 FATAL_ERROR("NULL parameter: Common::OID_comp::OID_comp()");
446 }
447
448 OID_comp::~OID_comp()
449 {
450 delete defdval;
451 delete name;
452 delete number;
453 delete var;
454 }
455
456 OID_comp *OID_comp::clone() const
457 {
458 FATAL_ERROR("OID_comp::clone");
459 }
460
461 void OID_comp::chk_OID(ReferenceChain& refch, Value *parent, size_t index,
462 oidstate_t& state)
463 {
464 Error_Context ec(this, "In component #%lu of OBJECT IDENTIFIER value",
465 (unsigned long) (index + 1));
466 switch (formtype) {
467 case NAMEFORM: {
468 Int v_Int = detect_nameform(state);
469 if (v_Int >= 0) {
470 // we have recognized the NameForm
471 number = new Value(Value::V_INT, v_Int);
472 number->set_fullname(get_fullname());
473 number->set_my_scope(parent->get_my_scope());
474 number->set_location(*this);
475 // the component is finished, jump out from switch
476 break;
477 } else {
478 // otherwise treat as a defined value and continue
479 Common::Reference *ref;
480 if (parent->is_asn1()) ref = new Asn::Ref_defd_simple(0, name);
481 else ref = new Ttcn::Reference(0, name);
482 name = 0;
483 defdval = new Value(Value::V_REFD, ref);
484 defdval->set_fullname(get_fullname());
485 defdval->set_my_scope(parent->get_my_scope());
486 defdval->set_location(*this);
487 formtype = DEFDVALUE;
488 }
489 }
490 // no break
491 case DEFDVALUE:
492 chk_defdvalue_OID(refch, state);
493 break;
494 case NUMBERFORM:
495 chk_numberform_OID(state);
496 break;
497 case NAMEANDNUMBERFORM:
498 chk_nameandnumberform(state);
499 break;
500 default:
501 FATAL_ERROR("OID_comp::chk_OID()");
502 } // switch
503 }
504
505 void OID_comp::chk_ROID(ReferenceChain& refch, size_t index)
506 {
507 Error_Context ec(this, "In component #%lu of RELATIVE-OID value",
508 (unsigned long) (index + 1));
509 switch (formtype) {
510 case DEFDVALUE:
511 chk_defdvalue_ROID(refch);
512 break;
513 case NUMBERFORM:
514 case NAMEANDNUMBERFORM:
515 chk_numberform_ROID();
516 break;
517 default:
518 FATAL_ERROR("OID_comp::chk_ROID()");
519 }
520 }
521
522 bool OID_comp::has_error()
523 {
524 if (formtype == DEFDVALUE) return defdval->has_oid_error();
525 else return number->get_value_refd_last()->get_valuetype() != Value::V_INT;
526 }
527
528 void OID_comp::get_comps(vector<string>& comps)
529 {
530 if (formtype == DEFDVALUE) defdval->get_oid_comps(comps);
531 else if (formtype == VARIABLE) {
532 comps.add(new string("OBJID::from_INTEGER(" + var->get_stringRepr() + ")"));
533 }
534 else comps.add(new string(number->get_stringRepr() + "u"));
535 }
536
537 bool OID_comp::is_variable()
538 {
539 return (formtype == VARIABLE);
540 }
541
542 Int OID_comp::detect_nameform(oidstate_t& state)
543 {
544 const string& name_str = name->get_name();
545 Int ret_val = -1;
546 switch (state) {
547 case START:
548 if (name_str == "itu__t" || name_str == "ccitt") {
549 state = ITU;
550 ret_val = 0;
551 } else if (name_str == "itu__r") {
552 warning("Identifier `%s' should not be used as NameForm",
553 name->get_dispname().c_str());
554 state = ITU;
555 ret_val = 0;
556 } else if (name_str == "iso") {
557 state = ISO;
558 ret_val = 1;
559 } else if (name_str == "joint__iso__itu__t"
560 || name_str == "joint__iso__ccitt") {
561 state = JOINT;
562 ret_val = 2;
563 }
564 break;
565 case ITU:
566 for (const nameform_t *nf = names_itu; nf->name != NULL; nf++) {
567 if (name_str == nf->name) {
568 ret_val = nf->value;
569 switch (nf->value) {
570 case 0:
571 state = ITU_REC;
572 break;
573 case 5:
574 warning("Identifier `%s' should not be used as NameForm",
575 name->get_dispname().c_str());
576 // no break
577 default:
578 state = LATER;
579 }
580 break;
581 }
582 }
583 break;
584 case ISO:
585 for (const nameform_t *nf = names_iso; nf->name != NULL; nf++) {
586 if (name_str == nf->name) {
587 ret_val = nf->value;
588 state = LATER;
589 break;
590 }
591 }
592 break;
593 case JOINT:
594 for (const nameform_t *nf = names_joint; nf->name != NULL; nf++) {
595 if (name_str == nf->name) {
596 ret_val = nf->value;
597 state = LATER;
598 warning("Identifier `%s' should not be used as NameForm",
599 name->get_dispname().c_str());
600 break;
601 }
602 }
603 break;
604 case ITU_REC:
605 if (name_str.size() == 1) {
606 char c = name_str[0];
607 if (c >= 'a' && c <= 'z') {
608 ret_val = c - 'a' + 1;
609 state = LATER;
610 }
611 }
612 break;
613 default:
614 break;
615 }
616 return ret_val;
617 }
618
619 void OID_comp::chk_defdvalue_OID(ReferenceChain& refch, oidstate_t& state)
620 {
621 Value *v = defdval->get_value_refd_last();
622 switch (v->get_valuetype()) {
623 case Value::V_ERROR:
624 state = LATER;
625 break;
626 case Value::V_INT:
627 // if the component is a reference to an integer value
628 // it shall be set to number form
629 formtype = NUMBERFORM;
630 number = defdval;
631 defdval = 0;
632 chk_numberform_OID(state);
633 break;
634 case Value::V_OID:
635 if (state != START) defdval->error("INTEGER or RELATIVE-OID "
636 "value was expected");
637 state = LATER;
638 v->chk_OID(refch);
639 break;
640 case Value::V_ROID:
641 switch (state) {
642 case ITU_REC:
643 state = LATER;
644 // no break
645 case LATER:
646 break;
647 default:
648 defdval->error("RELATIVE-OID value cannot be used as the "
649 "%s component of an OBJECT IDENTIFIER value",
650 state == START ? "first" : "second");
651 state = LATER;
652 break;
653 }
654 break;
655 case Value::V_REFD: {
656 Common::Reference* ref = v->get_reference();
657 Common::Assignment* as = ref->get_refd_assignment();
658 Type* t = as->get_Type()->get_type_refd_last();
659 if (t->get_typetype() == Type::T_INT) {
660 formtype = VARIABLE;
661 var = defdval;
662 defdval = 0;
663 } else {
664 defdval->error("INTEGER variable was expected");
665 }
666 state = LATER;
667 break; }
668 default:
669 if (state == START) defdval->error("INTEGER or OBJECT IDENTIFIER "
670 "value was expected for the first component");
671 else defdval->error("INTEGER or RELATIVE-OID value was expected");
672 state = LATER;
673 break;
674 }
675 }
676
677 void OID_comp::chk_numberform_OID(oidstate_t& state)
678 {
679 Value *v = number->get_value_refd_last();
680 switch (v->get_valuetype()) {
681 case Value::V_INT:
682 // everything is OK, continue the checking
683 break;
684 case Value::V_ERROR:
685 state = LATER;
686 return;
687 default:
688 number->error("INTEGER value was expected in the number form");
689 state = LATER;
690 return;
691 }
692 const int_val_t *v_Num = v->get_val_Int();
693 if (v_Num->get_val() > (Int)UINT_MAX) {
694 number->error("An integer value less than `%u' was expected in the "
695 "number form instead of `%s'", UINT_MAX, (v_Num->t_str()).c_str());
696 state = LATER;
697 return;
698 }
699 Int v_Int = v_Num->get_val();
700 switch (state) {
701 case START:
702 switch (v_Int) {
703 case 0:
704 state = ITU;
705 break;
706 case 1:
707 state = ISO;
708 break;
709 case 2:
710 state = JOINT;
711 break;
712 default:
713 number->error("The value of first OBJECT IDENTIFIER component must "
714 "be between 0 and 2 instead of %s", Int2string(v_Int).c_str());
715 state = LATER;
716 break;
717 }
718 break;
719 case ITU:
720 case ISO:
721 if (v_Int < 0 || v_Int > 39) number->error("The value of "
722 "second OBJECT IDENTIFIER component must be between 0 and 39 "
723 "instead of %s", Int2string(v_Int).c_str());
724 if (state == ITU && v_Int == 0) state = ITU_REC;
725 else state = LATER;
726 break;
727 case JOINT:
728 default:
729 if (v_Int < 0) number->error("A non-negative integer value was "
730 "expected instead of %s", Int2string(v_Int).c_str());
731 state = LATER;
732 break;
733 }
734 }
735
736 void OID_comp::chk_nameandnumberform(oidstate_t& state)
737 {
738 // make a backup of state
739 oidstate_t oldstate = state;
740 chk_numberform_OID(state);
741 Value *v = number->get_value_refd_last();
742 if (v->get_valuetype() != Value::V_INT || !v->get_val_Int()->is_native())
743 return;
744 Int v_Int = v->get_val_Int()->get_val();
745 const string& name_str = name->get_name();
746 switch (oldstate) {
747 case START:
748 if (!is_valid_name_for_number(name_str, v_Int, names_root)) {
749 number->warning("Identifier %s was expected instead of `%s' for "
750 "number %s in the NameAndNumberForm as the first OBJECT IDENTIFIER "
751 "component", get_expected_name_for_number(v_Int, number->is_asn1(),
752 names_root).c_str(), name->get_dispname().c_str(),
753 Int2string(v_Int).c_str());
754 }
755 break;
756 case ITU:
757 if (!is_valid_name_for_number(name_str, v_Int, names_itu)) {
758 number->warning("Identifier %s was expected instead of `%s' for "
759 "number %s in the NameAndNumberForm as the second OBJECT IDENTIFIER "
760 "component", get_expected_name_for_number(v_Int, number->is_asn1(),
761 names_itu).c_str(), name->get_dispname().c_str(),
762 Int2string(v_Int).c_str());
763 }
764 break;
765 case ISO:
766 if (!is_valid_name_for_number(name_str, v_Int, names_iso)) {
767 number->warning("Identifier %s was expected instead of `%s' for "
768 "number %s in the NameAndNumberForm as the second OBJECT IDENTIFIER "
769 "component", get_expected_name_for_number(v_Int, number->is_asn1(),
770 names_iso).c_str(), name->get_dispname().c_str(),
771 Int2string(v_Int).c_str());
772 }
773 break;
774 case JOINT:
775 if (!is_valid_name_for_number(name_str, v_Int, names_joint)) {
776 number->warning("Identifier %s was expected instead of `%s' for "
777 "number %s in the NameAndNumberForm as the second OBJECT IDENTIFIER "
778 "component", get_expected_name_for_number(v_Int, number->is_asn1(),
779 names_joint).c_str(), name->get_dispname().c_str(),
780 Int2string(v_Int).c_str());
781 }
782 break;
783 case ITU_REC:
784 if (v_Int >= 1 && v_Int <= 26 &&
785 (name_str.size() != 1 || name_str[0] != 'a' + v_Int - 1))
786 number->warning("Identifier `%c' was expected instead of `%s' for "
787 "number %s in the NameAndNumberForm as the third OBJECT IDENTIFIER "
788 "component", (char)('a' + v_Int - 1), name->get_dispname().c_str(),
789 Int2string(v_Int).c_str());
790 break;
791 default:
792 // no warning can be displayed in later states
793 break;
794 }
795 }
796
797 bool OID_comp::is_valid_name_for_number(const string& p_name,
798 const Int& p_number, const nameform_t *p_names)
799 {
800 bool ret_val = true;
801 for (const nameform_t *nf = p_names; nf->name != NULL; nf++) {
802 if ((unsigned int)p_number == nf->value) {
803 if (p_name == nf->name) return true;
804 else ret_val = false;
805 }
806 }
807 return ret_val;
808 }
809
810 string OID_comp::get_expected_name_for_number(const Int& p_number,
811 bool p_asn1, const nameform_t *p_names)
812 {
813 size_t nof_expected_names = 0;
814 for (const nameform_t *nf = p_names; nf->name != NULL; nf++) {
815 if ((unsigned int)p_number == nf->value) nof_expected_names++;
816 }
817 if (nof_expected_names <= 0)
818 FATAL_ERROR("OID_comp::get_expected_name_for_number()");
819 string ret_val;
820 size_t i = 0;
821 for (const nameform_t *nf = p_names; nf->name != NULL; nf++) {
822 if ((unsigned int)p_number == nf->value) {
823 if (i > 0) {
824 if (i < nof_expected_names - 1) ret_val += ", ";
825 else ret_val += " or ";
826 }
827 ret_val += "`";
828 Identifier id(Identifier::ID_NAME, string(nf->name));
829 if (p_asn1) ret_val += id.get_asnname();
830 else ret_val += id.get_ttcnname();
831 ret_val += "'";
832 i++;
833 }
834 }
835 return ret_val;
836 }
837
838 void OID_comp::chk_defdvalue_ROID(ReferenceChain& refch)
839 {
840 Value *v = defdval->get_value_refd_last();
841 switch (v->get_valuetype()) {
842 case Value::V_ERROR:
843 break;
844 case Value::V_INT:
845 // if the component is a reference to an integer value
846 // it shall be set to number form
847 formtype = NUMBERFORM;
848 number = defdval;
849 defdval = 0;
850 chk_numberform_ROID();
851 break;
852 case Value::V_ROID:
853 v->chk_ROID(refch);
854 break;
855 default:
856 defdval->error("INTEGER or RELATIVE-OID value was expected");
857 break;
858 }
859 }
860
861 void OID_comp::chk_numberform_ROID()
862 {
863 Value *v = number->get_value_refd_last();
864 switch (v->get_valuetype()) {
865 case Value::V_INT: {
866 const int_val_t *v_Num = v->get_val_Int();
867 if (*v_Num > INT_MAX) {
868 number->error("An integer value less than `%d' was expected instead "
869 "of `%s'", INT_MAX, (v_Num->t_str()).c_str());
870 return;
871 }
872 Int v_Int = v_Num->get_val();
873 if (v_Int < 0)
874 number->error("A non-negative integer value was expected instead "
875 "of %s", Int2string(v_Int).c_str());
876 break; }
877 case Value::V_ERROR:
878 break;
879 default:
880 number->error("INTEGER value was expected in the number form");
881 break;
882 }
883 }
884
885 void OID_comp::set_fullname(const string& p_fullname)
886 {
887 Node::set_fullname(p_fullname);
888 if (defdval) defdval->set_fullname(p_fullname);
889 if (number) number->set_fullname(p_fullname);
890 if (var) var->set_fullname(p_fullname);
891 }
892
893 void OID_comp::set_my_scope(Scope *p_scope)
894 {
895 if(defdval) defdval->set_my_scope(p_scope);
896 if(number) number->set_my_scope(p_scope);
897 if(var) var->set_my_scope(p_scope);
898 }
899
900 void OID_comp::append_stringRepr(string& str) const
901 {
902 switch (formtype) {
903 case NAMEFORM:
904 str += name->get_dispname();
905 break;
906 case NUMBERFORM:
907 case NAMEANDNUMBERFORM:
908 str += number->get_stringRepr();
909 break;
910 case DEFDVALUE:
911 str += defdval->get_stringRepr();
912 break;
913 case VARIABLE:
914 str += var->get_stringRepr();
915 break;
916 default:
917 str += "<unknown OID component>";
918 break;
919 }
920 }
921
922 // =================================
923 // ===== CharsDefn
924 // =================================
925
926 CharsDefn::CharsDefn(string *p_str)
927 : Node(), Location(), selector(CD_CSTRING), checked(false)
928 {
929 if(!p_str) FATAL_ERROR("CharsDefn::CharsDefn()");
930 u.str=p_str;
931 }
932
933 CharsDefn::CharsDefn(Value *p_val)
934 : Node(), Location(), selector(CD_VALUE), checked(false)
935 {
936 if(!p_val) FATAL_ERROR("CharsDefn::CharsDefn()");
937 u.val=p_val;
938 }
939
940 CharsDefn::CharsDefn(Int p_g, Int p_p, Int p_r, Int p_c)
941 : Node(), Location(), selector(CD_QUADRUPLE), checked(false)
942 {
943 u.quadruple.g=p_g;
944 u.quadruple.p=p_p;
945 u.quadruple.r=p_r;
946 u.quadruple.c=p_c;
947 }
948
949 CharsDefn::CharsDefn(Int p_c, Int p_r)
950 : Node(), Location(), selector(CD_TUPLE), checked(false)
951 {
952 u.tuple.c=p_c;
953 u.tuple.r=p_r;
954 }
955
956 CharsDefn::CharsDefn(Block *p_block)
957 : Node(), Location(), selector(CD_BLOCK), checked(false)
958 {
959 if(!p_block) FATAL_ERROR("CharsDefn::CharsDefn()");
960 u.block=p_block;
961 }
962
963 CharsDefn::~CharsDefn()
964 {
965 switch(selector) {
966 case CD_CSTRING:
967 delete u.str;
968 break;
969 case CD_VALUE:
970 delete u.val;
971 break;
972 case CD_BLOCK:
973 delete u.block;
974 break;
975 default:
976 break;
977 } // switch
978 }
979
980 CharsDefn *CharsDefn::clone() const
981 {
982 FATAL_ERROR("CharsDefn::clone");
983 }
984
985 void CharsDefn::set_fullname(const string& p_fullname)
986 {
987 Node::set_fullname(p_fullname);
988 switch (selector) {
989 case CD_VALUE:
990 u.val->set_fullname(p_fullname);
991 break;
992 case CD_BLOCK:
993 u.block->set_fullname(p_fullname);
994 break;
995 default:
996 break;
997 }
998 }
999
1000 void CharsDefn::set_my_scope(Scope *p_scope)
1001 {
1002 if(selector==CD_VALUE)
1003 u.val->set_my_scope(p_scope);
1004 }
1005
1006 void CharsDefn::parse_block()
1007 {
1008 if(selector!=CD_BLOCK) return;
1009 Block *t_block=u.block;
1010 Node *node=t_block->parse(KW_Block_QuadrupleOrTuple);
1011 CharsDefn *cd=dynamic_cast<CharsDefn*>(node);
1012 if(!cd) cd=new CharsDefn(0, 0, 0, 0);
1013 delete t_block;
1014 if(cd->selector==CD_QUADRUPLE) {
1015 u.quadruple=cd->u.quadruple;
1016 selector=CD_QUADRUPLE;
1017 }
1018 else {
1019 u.tuple=cd->u.tuple;
1020 selector=CD_TUPLE;
1021 }
1022 delete cd;
1023 }
1024
1025 void CharsDefn::chk()
1026 {
1027 if(checked) return;
1028 checked=true;
1029 if(selector==CD_BLOCK) parse_block();
1030 switch(selector) {
1031 case CD_QUADRUPLE:
1032 if(u.quadruple.g>127) {
1033 error("In quadruple: Group value must be in range 0..127");
1034 u.quadruple.g=0;
1035 }
1036 if(u.quadruple.p>255) {
1037 error("In quadruple: Plane value must be in range 0..255");
1038 u.quadruple.p=0;
1039 }
1040 if(u.quadruple.r>255) {
1041 error("In quadruple: Row value must be in range 0..255");
1042 u.quadruple.r=0;
1043 }
1044 if(u.quadruple.c>255) {
1045 error("In quadruple: Cell value must be in range 0..255");
1046 u.quadruple.c=0;
1047 }
1048 break;
1049 case CD_TUPLE:
1050 if(u.tuple.c>7) {
1051 error("In tuple: Column value must be in range 0..7");
1052 u.tuple.c=0;
1053 }
1054 if(u.tuple.r>15) {
1055 error("In tuple: Row value must be in range 0..15");
1056 u.tuple.r=0;
1057 }
1058 break;
1059 default:
1060 break;
1061 } // switch
1062 }
1063
1064 string CharsDefn::get_string(ReferenceChain *refch)
1065 {
1066 chk();
1067 switch(selector) {
1068 case CD_CSTRING:
1069 return *u.str;
1070 case CD_QUADRUPLE:
1071 error("Quadruple form is not allowed here.");
1072 return string("\0");
1073 case CD_TUPLE:{
1074 error("Tuple form is not allowed here.");
1075 char c=u.tuple.c*16+u.tuple.r;
1076 return string(1, &c); }
1077 case CD_VALUE:
1078 switch(u.val->get_value_refd_last(refch)->get_valuetype()) {
1079 case Value::V_ERROR:
1080 return string();
1081 case Value::V_CHARSYMS:
1082 case Value::V_CSTR:
1083 return u.val->get_val_str();
1084 case Value::V_ISO2022STR:
1085 error("Reference to string value was expected"
1086 " (instead of ISO-2022 string).");
1087 return string();
1088 case Value::V_USTR:
1089 error("Reference to string value was expected"
1090 " (instead of ISO-10646 string).");
1091 return string();
1092 default:
1093 error("Reference to character string value was expected.");
1094 return string();
1095 } // switch valuetype
1096 break;
1097 default:
1098 FATAL_ERROR("CharsDefn::get_string()");
1099 // to eliminate warning
1100 return string();
1101 }
1102 }
1103
1104 ustring CharsDefn::get_ustring(ReferenceChain *refch)
1105 {
1106 chk();
1107 switch(selector) {
1108 case CD_CSTRING:
1109 return ustring(*u.str);
1110 break;
1111 case CD_QUADRUPLE:
1112 return ustring(u.quadruple.g, u.quadruple.p,
1113 u.quadruple.r, u.quadruple.c);
1114 break;
1115 case CD_TUPLE:
1116 error("Tuple form is not allowed here.");
1117 return ustring(0, 0, 0, u.tuple.c*16+u.tuple.r);
1118 break;
1119 case CD_VALUE:
1120 switch(u.val->get_value_refd_last(refch)->get_valuetype()) {
1121 case Value::V_ERROR:
1122 return ustring();
1123 case Value::V_CSTR:
1124 case Value::V_USTR:
1125 case Value::V_CHARSYMS:
1126 return u.val->get_val_ustr();
1127 case Value::V_ISO2022STR:
1128 error("Reference to ISO-10646 string value was expected"
1129 " (instead of ISO-2022 string).");
1130 return ustring();
1131 default:
1132 error("Reference to string value was expected.");
1133 return ustring();
1134 } // switch valuetype
1135 break;
1136 default:
1137 FATAL_ERROR("CharsDefn::get_ustring()");
1138 // to eliminate warning
1139 return ustring();
1140 }
1141 }
1142
1143 string CharsDefn::get_iso2022string(ReferenceChain *refch)
1144 {
1145 chk();
1146 switch(selector) {
1147 case CD_CSTRING:
1148 return *u.str;
1149 case CD_QUADRUPLE:
1150 error("Quadruple form is not allowed here");
1151 return string("\0");
1152 case CD_TUPLE:{
1153 char c=u.tuple.c*16+u.tuple.r;
1154 return string(1, &c); }
1155 case CD_VALUE:
1156 switch(u.val->get_value_refd_last(refch)->get_valuetype()) {
1157 case Value::V_ERROR:
1158 return string();
1159 case Value::V_CSTR:
1160 case Value::V_ISO2022STR:
1161 case Value::V_CHARSYMS:
1162 return u.val->get_val_iso2022str();
1163 case Value::V_USTR:
1164 error("Reference to ISO-2022 string value was expected"
1165 " (instead of ISO-10646 string).");
1166 return string();
1167 default:
1168 error("Reference to string value was expected.");
1169 return string();
1170 } // switch valuetype
1171 break;
1172 default:
1173 FATAL_ERROR("CharsDefn::get_iso2022string()");
1174 // to eliminate warning
1175 return string();
1176 }
1177 }
1178
1179 size_t CharsDefn::get_len(ReferenceChain *refch)
1180 {
1181 chk();
1182 switch(selector) {
1183 case CD_CSTRING:
1184 return u.str->size();
1185 case CD_QUADRUPLE:
1186 case CD_TUPLE:
1187 return 1;
1188 case CD_VALUE:
1189 switch(u.val->get_value_refd_last(refch)->get_valuetype()) {
1190 case Value::V_ERROR:
1191 return 0;
1192 case Value::V_CSTR:
1193 case Value::V_USTR:
1194 case Value::V_ISO2022STR:
1195 case Value::V_CHARSYMS:
1196 return u.val->get_val_strlen();
1197 default:
1198 error("Reference to string value was expected.");
1199 return 0;
1200 } // switch valuetype
1201 break;
1202 default:
1203 FATAL_ERROR("CharsDefn::get_LEN()");
1204 // to eliminate warning
1205 return 0;
1206 }
1207 }
1208
1209 void CharsDefn::dump(unsigned level) const
1210 {
1211 switch (selector) {
1212 case CD_CSTRING:
1213 DEBUG(level, "\"%s\"", u.str->c_str());
1214 break;
1215 case CD_QUADRUPLE:
1216 DEBUG(level, "{%s, %s, %s, %s}",
1217 Int2string(u.quadruple.g).c_str(),
1218 Int2string(u.quadruple.p).c_str(),
1219 Int2string(u.quadruple.r).c_str(),
1220 Int2string(u.quadruple.c).c_str());
1221 break;
1222 case CD_TUPLE:
1223 DEBUG(level, "{%s, %s}", Int2string(u.tuple.c).c_str(),
1224 Int2string(u.tuple.r).c_str());
1225 break;
1226 case CD_VALUE:
1227 u.val->dump(level);
1228 break;
1229 case CD_BLOCK:
1230 u.block->dump(level);
1231 break;
1232 default:
1233 break;
1234 }
1235 }
1236
1237 // =================================
1238 // ===== CharSyms
1239 // =================================
1240
1241 CharSyms::CharSyms() : Node(), Location(), selector(CS_UNDEF)
1242 {
1243 }
1244
1245 CharSyms::~CharSyms()
1246 {
1247 for(size_t i=0; i<cds.size(); i++) delete cds[i];
1248 cds.clear();
1249 switch(selector) {
1250 case CS_UNDEF:
1251 break;
1252 case CS_CSTRING:
1253 case CS_ISO2022STRING:
1254 delete u.str;
1255 break;
1256 case CS_USTRING:
1257 delete u.ustr;
1258 break;
1259 default:
1260 FATAL_ERROR("CharSyms::~CharSyms()");
1261 } // switch
1262 }
1263
1264 CharSyms *CharSyms::clone() const
1265 {
1266 FATAL_ERROR("CharSyms::clone");
1267 }
1268
1269 void CharSyms::set_fullname(const string& p_fullname)
1270 {
1271 Node::set_fullname(p_fullname);
1272 for (size_t i = 0; i < cds.size(); i++)
1273 cds[i]->set_fullname(p_fullname + "." + Int2string(i));
1274 }
1275
1276 void CharSyms::set_my_scope(Scope *p_scope)
1277 {
1278 for(size_t i=0; i<cds.size(); i++)
1279 cds[i]->set_my_scope(p_scope);
1280 }
1281
1282 void CharSyms::add_cd(CharsDefn *p_cd)
1283 {
1284 if(!p_cd) return;
1285 cds.add(p_cd);
1286 }
1287
1288 string CharSyms::get_string(ReferenceChain *refch)
1289 {
1290 switch(selector) {
1291 case CS_UNDEF:{
1292 bool destroy_refch=refch==0;
1293 if(refch) refch->mark_state();
1294 else refch=new ReferenceChain(this, "While checking"
1295 " charstring value");
1296 u.str=new string();
1297 selector=CS_CHECKING;
1298 if(refch->add(get_fullname()))
1299 for(size_t i=0; i<cds.size(); i++)
1300 *u.str+=cds[i]->get_string(refch);
1301 if(destroy_refch) delete refch;
1302 else refch->prev_state();
1303 selector=CS_CSTRING;
1304 }
1305 // no break
1306 case CS_CSTRING:
1307 return *u.str;
1308 case CS_USTRING:
1309 error("ISO-10646 charstring cannot be used in charstring context");
1310 return string();
1311 case CS_ISO2022STRING:
1312 error("ISO-2022 charstring cannot be used in charstring context");
1313 return string();
1314 case CS_CHECKING:
1315 error("Circular reference in `%s'", get_fullname().c_str());
1316 return string();
1317 default:
1318 FATAL_ERROR("CharSyms::get_string()");
1319 return string();
1320 } // switch
1321 }
1322
1323 ustring CharSyms::get_ustring(ReferenceChain *refch)
1324 {
1325 switch(selector) {
1326 case CS_UNDEF:{
1327 bool destroy_refch=refch==0;
1328 if(refch) refch->mark_state();
1329 else refch=new ReferenceChain(this, "While checking"
1330 " charstring value");
1331 u.ustr=new ustring();
1332 selector=CS_CHECKING;
1333 if(refch->add(get_fullname()))
1334 for(size_t i=0; i<cds.size(); i++)
1335 *u.ustr+=cds[i]->get_ustring(refch);
1336 if(destroy_refch) delete refch;
1337 else refch->prev_state();
1338 selector=CS_USTRING;
1339 }
1340 // no break
1341 case CS_USTRING:
1342 return *u.ustr;
1343 case CS_CSTRING:
1344 return ustring(*u.str);
1345 case CS_ISO2022STRING:
1346 error("ISO-2022 charstring cannot be used in ISO-10646 context");
1347 return ustring();
1348 case CS_CHECKING:
1349 error("Circular reference in `%s'", get_fullname().c_str());
1350 return ustring();
1351 default:
1352 FATAL_ERROR("CharSyms::get_ustring()");
1353 return ustring();
1354 } // switch
1355 }
1356
1357 string CharSyms::get_iso2022string(ReferenceChain *refch)
1358 {
1359 switch(selector) {
1360 case CS_UNDEF:{
1361 bool destroy_refch=refch==0;
1362 if(refch) refch->mark_state();
1363 else refch=new ReferenceChain(this, "While checking"
1364 " charstring value");
1365 u.str=new string();
1366 selector=CS_CHECKING;
1367 if(refch->add(get_fullname()))
1368 for(size_t i=0; i<cds.size(); i++)
1369 *u.str+=cds[i]->get_iso2022string(refch);
1370 if(destroy_refch) delete refch;
1371 else refch->prev_state();
1372 selector=CS_CSTRING;
1373 }
1374 // no break
1375 case CS_CSTRING:
1376 case CS_ISO2022STRING:
1377 return *u.str;
1378 case CS_USTRING:
1379 error("ISO-10646 charstring cannot be used in ISO-2022 context");
1380 return string();
1381 case CS_CHECKING:
1382 error("Circular reference in `%s'", get_fullname().c_str());
1383 return string();
1384 default:
1385 FATAL_ERROR("CharSyms::get_iso2022string()");
1386 return string();
1387 } // switch
1388 }
1389
1390 size_t CharSyms::get_len(ReferenceChain *refch)
1391 {
1392 switch(selector) {
1393 case CS_UNDEF:{
1394 bool destroy_refch=refch==0;
1395 if(refch) refch->mark_state();
1396 else refch=new ReferenceChain(this, "While checking"
1397 " charstring value");
1398 size_t len=0;
1399 selector=CS_CHECKING;
1400 if(refch->add(get_fullname()))
1401 for(size_t i=0; i<cds.size(); i++)
1402 len+=cds[i]->get_len(refch);
1403 if(destroy_refch) delete refch;
1404 else refch->prev_state();
1405 selector=CS_UNDEF;
1406 }
1407 // no break
1408 case CS_CSTRING:
1409 case CS_ISO2022STRING:
1410 return u.str->size();
1411 case CS_USTRING:
1412 return u.ustr->size();
1413 case CS_CHECKING:
1414 error("Circular reference in `%s'", get_fullname().c_str());
1415 return 0;
1416 default:
1417 FATAL_ERROR("CharSyms::get_len()");
1418 return 0;
1419 } // switch
1420 }
1421
1422 void CharSyms::dump(unsigned level) const
1423 {
1424 DEBUG(level, "CharSyms:");
1425 level++;
1426 for (size_t i = 0; i < cds.size(); i++)
1427 cds[i]->dump(level);
1428 }
1429
1430 } // namespace Common
This page took 0.065001 seconds and 5 git commands to generate.