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