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"
11 #include "asn1/Object0.hh"
12 #include "asn1/Block.hh"
13 #include "asn1/TokenBuf.hh"
20 // =================================
22 // =================================
24 Values::Values(bool p_indexed
) : Node(), indexed(p_indexed
)
26 if (!p_indexed
) vs
= new vector
<Value
>();
27 else ivs
= new vector
<IndexedValue
>();
33 for (size_t i
= 0; i
< vs
->size(); i
++) delete (*vs
)[i
];
37 for (size_t i
= 0; i
< ivs
->size(); i
++) delete (*ivs
)[i
];
43 Values
*Values::clone() const
45 FATAL_ERROR("Values::clone");
48 void Values::set_fullname(const string
& p_fullname
)
50 Node::set_fullname(p_fullname
);
52 for (size_t i
= 0; i
< vs
->size(); i
++) {
54 if (v
) v
->set_fullname(p_fullname
+ "[" + Int2string(i
) + "]");
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
61 if (iv
) iv
->set_fullname(p_fullname
+ "[" + Int2string(i
) + "]");
66 void Values::set_my_scope(Scope
*p_scope
)
69 for (size_t i
= 0; i
< vs
->size(); i
++) {
71 if (v
) v
->set_my_scope(p_scope
);
74 for (size_t i
= 0; i
< ivs
->size(); i
++) {
75 IndexedValue
*iv
= (*ivs
)[i
];
76 if (iv
) iv
->set_my_scope(p_scope
);
81 size_t Values::get_nof_vs() const
83 if (indexed
) FATAL_ERROR("Values::get_nof_vs()");
87 size_t Values::get_nof_ivs() const
89 if (!indexed
) FATAL_ERROR("Values::get_nof_ivs()");
93 Value
*Values::get_v_byIndex(size_t p_i
) const
95 if (indexed
) FATAL_ERROR("Values::get_v_byIndex");
99 IndexedValue
*Values::get_iv_byIndex(size_t p_i
) const
101 if (!indexed
) FATAL_ERROR("Values::get_iv_byIndex()");
105 void Values::add_v(Value
*p_v
)
107 if (!p_v
) FATAL_ERROR("Values::add_v(): NULL parameter");
108 if (indexed
) FATAL_ERROR("Values::add_v()");
112 void Values::add_iv(IndexedValue
*p_iv
)
114 if (!p_iv
) FATAL_ERROR("Values::add_iv(): NULL parameter");
115 if (!indexed
) FATAL_ERROR("Values::add_iv()");
119 Value
*Values::steal_v_byIndex(size_t p_i
)
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()");
128 void Values::dump(unsigned level
) const
131 for (size_t i
= 0; i
< vs
->size(); i
++) {
133 if (v
) v
->dump(level
);
134 else DEBUG(level
, "Value: stolen");
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");
145 // =================================
146 // ===== IndexedValue
147 // =================================
149 IndexedValue::IndexedValue(Ttcn::FieldOrArrayRef
*p_index
, Value
*p_value
)
150 : Node(), Location(), index(p_index
), value(p_value
)
152 if (!p_index
|| !p_value
)
153 FATAL_ERROR("NULL parameter: IndexedValue::IndexedValue()");
156 IndexedValue::~IndexedValue()
162 IndexedValue
*IndexedValue::clone() const
164 FATAL_ERROR("IndexedValue::clone");
167 void IndexedValue::set_fullname(const string
& p_fullname
)
169 Node::set_fullname(p_fullname
);
170 if (value
) value
->set_fullname(p_fullname
);
171 if (index
) index
->set_fullname(p_fullname
);
174 void IndexedValue::set_my_scope(Scope
*p_scope
)
176 if (value
) value
->set_my_scope(p_scope
);
177 if (index
) index
->set_my_scope(p_scope
);
180 void IndexedValue::set_code_section
181 (GovernedSimple::code_section_t p_code_section
)
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
);
188 Value
*IndexedValue::steal_value()
190 if (!value
) FATAL_ERROR("IndexedValue::steal_value()");
196 void IndexedValue::dump(unsigned level
) const
199 if (value
) value
->dump(level
+ 1);
200 else DEBUG(level
+ 1, "Value: stolen");
203 bool IndexedValue::is_unfoldable(ReferenceChain
*refch
,
204 Type::expected_value_t exp_val
)
206 return (value
->is_unfoldable(refch
, exp_val
) ||
207 get_index()->is_unfoldable(refch
, exp_val
));
210 // =================================
212 // =================================
214 NamedValue::NamedValue(Identifier
*p_name
, Value
*p_value
)
215 : Node(), Location(), name(p_name
), value(p_value
)
217 if (!p_name
|| !p_value
)
218 FATAL_ERROR("NULL parameter: NamedValue::NamedValue()");
221 NamedValue::NamedValue(const NamedValue
& p
)
222 : Node(p
), Location(p
)
224 if (!p
.value
) FATAL_ERROR("NamedValue::NamedValue(): value is stolen");
225 name
= p
.name
->clone();
226 value
= p
.value
->clone();
229 NamedValue::~NamedValue()
235 NamedValue
*NamedValue::clone() const
237 return new NamedValue(*this);
240 void NamedValue::set_fullname(const string
& p_fullname
)
242 Node::set_fullname(p_fullname
);
243 if (value
) value
->set_fullname(p_fullname
);
246 void NamedValue::set_my_scope(Scope
*p_scope
)
248 if (value
) value
->set_my_scope(p_scope
);
251 Value
*NamedValue::steal_value()
253 if (!value
) FATAL_ERROR("NamedValue::steal_value()");
259 void NamedValue::dump(unsigned level
) const
262 if (value
) value
->dump(level
+ 1);
263 else DEBUG(level
+ 1, "Value: stolen");
266 // =================================
268 // =================================
270 NamedValues::NamedValues(const NamedValues
& p
)
271 : Node(p
), checked(false)
273 for (size_t i
= 0; i
< p
.nvs_v
.size(); i
++)
274 nvs_v
.add(p
.nvs_v
[i
]->clone());
277 NamedValues::~NamedValues()
279 for(size_t i
= 0; i
< nvs_v
.size(); i
++) delete nvs_v
[i
];
284 NamedValues
*NamedValues::clone() const
286 return new NamedValues(*this);
289 void NamedValues::set_fullname(const string
& p_fullname
)
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());
298 void NamedValues::set_my_scope(Scope
*p_scope
)
300 for (size_t i
= 0; i
< nvs_v
.size(); i
++)
301 nvs_v
[i
]->set_my_scope(p_scope
);
304 void NamedValues::add_nv(NamedValue
*p_nv
)
306 if (!p_nv
) FATAL_ERROR("NamedValues::add_nv(): NULL parameter");
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
);
315 bool NamedValues::has_nv_withName(const Identifier
& p_name
)
317 if (!checked
) chk_dupl_id(false);
318 return nvs_m
.has_key(p_name
.get_name());
321 NamedValue
* NamedValues::get_nv_byName(const Identifier
& p_name
)
323 if (!checked
) chk_dupl_id(false);
324 return nvs_m
[p_name
.get_name()];
327 void NamedValues::chk_dupl_id(bool report_errors
)
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
);
344 void NamedValues::dump(unsigned level
) const
346 for (size_t i
= 0; i
< nvs_v
.size(); i
++)
347 nvs_v
[i
]->dump(level
);
350 // =================================
352 // =================================
354 const OID_comp::nameform_t
OID_comp::names_root
[] = {
359 { "joint__iso__itu__t", 2 },
360 { "joint__iso__ccitt", 2 },
364 const OID_comp::nameform_t
OID_comp::names_itu
[] = {
365 { "recommendation", 0 },
367 { "administration", 2 },
368 { "network__operator", 3 },
369 { "identified__organization", 4 },
370 { "r__recommendation", 5 },
374 const OID_comp::nameform_t
OID_comp::names_iso
[] = {
376 { "registration__authority", 1 },
377 { "member__body", 2 },
378 { "identified__organization", 3 },
382 // taken from OID repository: http://asn1.elibel.tm.fr/oid/
383 const OID_comp::nameform_t
OID_comp::names_joint
[] = {
384 { "presentation", 0 },
386 { "association__control", 2 },
387 { "reliable__transfer", 3 },
388 { "remote__operations", 4 },
396 { "osi__management", 9 },
397 { "transaction__processing", 10 },
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 },
409 { "registration__procedures", 17 },
410 { "registration__procedure", 17 },
411 { "physical__layer", 18 },
412 { "physical__layer__management", 18 },
414 { "genericULS", 20 },
415 { "generic__upper__layers__security", 20 },
417 { "transport__layer__security__protocol", 21 },
418 { "network__layer__security__protocol", 22 },
419 { "international__organizations", 23 },
420 { "internationalRA", 23 },
428 OID_comp::OID_comp(Identifier
*p_name
, Value
*p_number
)
429 : Node(), Location(), defdval(0), name(p_name
), number(p_number
), var(0)
432 if (p_number
) formtype
= NAMEANDNUMBERFORM
;
433 else formtype
= NAMEFORM
;
435 if (p_number
) formtype
= NUMBERFORM
;
436 else FATAL_ERROR("NULL parameter: Common::OID_comp::OID_comp()");
440 OID_comp::OID_comp(Value
*p_defdval
)
441 : Node(), Location(), formtype(DEFDVALUE
), defdval(p_defdval
), name(0),
445 FATAL_ERROR("NULL parameter: Common::OID_comp::OID_comp()");
448 OID_comp::~OID_comp()
456 OID_comp
*OID_comp::clone() const
458 FATAL_ERROR("OID_comp::clone");
461 void OID_comp::chk_OID(ReferenceChain
& refch
, Value
*parent
, size_t index
,
464 Error_Context
ec(this, "In component #%lu of OBJECT IDENTIFIER value",
465 (unsigned long) (index
+ 1));
468 Int v_Int
= detect_nameform(state
);
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
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
);
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
;
492 chk_defdvalue_OID(refch
, state
);
495 chk_numberform_OID(state
);
497 case NAMEANDNUMBERFORM
:
498 chk_nameandnumberform(state
);
501 FATAL_ERROR("OID_comp::chk_OID()");
505 void OID_comp::chk_ROID(ReferenceChain
& refch
, size_t index
)
507 Error_Context
ec(this, "In component #%lu of RELATIVE-OID value",
508 (unsigned long) (index
+ 1));
511 chk_defdvalue_ROID(refch
);
514 case NAMEANDNUMBERFORM
:
515 chk_numberform_ROID();
518 FATAL_ERROR("OID_comp::chk_ROID()");
522 bool OID_comp::has_error()
524 if (formtype
== DEFDVALUE
) return defdval
->has_oid_error();
525 else return number
->get_value_refd_last()->get_valuetype() != Value::V_INT
;
528 void OID_comp::get_comps(vector
<string
>& comps
)
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() + ")"));
534 else comps
.add(new string(number
->get_stringRepr() + "u"));
537 bool OID_comp::is_variable()
539 return (formtype
== VARIABLE
);
542 Int
OID_comp::detect_nameform(oidstate_t
& state
)
544 const string
& name_str
= name
->get_name();
548 if (name_str
== "itu__t" || name_str
== "ccitt") {
551 } else if (name_str
== "itu__r") {
552 warning("Identifier `%s' should not be used as NameForm",
553 name
->get_dispname().c_str());
556 } else if (name_str
== "iso") {
559 } else if (name_str
== "joint__iso__itu__t"
560 || name_str
== "joint__iso__ccitt") {
566 for (const nameform_t
*nf
= names_itu
; nf
->name
!= NULL
; nf
++) {
567 if (name_str
== nf
->name
) {
574 warning("Identifier `%s' should not be used as NameForm",
575 name
->get_dispname().c_str());
585 for (const nameform_t
*nf
= names_iso
; nf
->name
!= NULL
; nf
++) {
586 if (name_str
== nf
->name
) {
594 for (const nameform_t
*nf
= names_joint
; nf
->name
!= NULL
; nf
++) {
595 if (name_str
== nf
->name
) {
598 warning("Identifier `%s' should not be used as NameForm",
599 name
->get_dispname().c_str());
605 if (name_str
.size() == 1) {
606 char c
= name_str
[0];
607 if (c
>= 'a' && c
<= 'z') {
608 ret_val
= c
- 'a' + 1;
619 void OID_comp::chk_defdvalue_OID(ReferenceChain
& refch
, oidstate_t
& state
)
621 Value
*v
= defdval
->get_value_refd_last();
622 switch (v
->get_valuetype()) {
627 // if the component is a reference to an integer value
628 // it shall be set to number form
629 formtype
= NUMBERFORM
;
632 chk_numberform_OID(state
);
635 if (state
!= START
) defdval
->error("INTEGER or RELATIVE-OID "
636 "value was expected");
648 defdval
->error("RELATIVE-OID value cannot be used as the "
649 "%s component of an OBJECT IDENTIFIER value",
650 state
== START
? "first" : "second");
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
) {
664 defdval
->error("INTEGER variable was expected");
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");
677 void OID_comp::chk_numberform_OID(oidstate_t
& state
)
679 Value
*v
= number
->get_value_refd_last();
680 switch (v
->get_valuetype()) {
682 // everything is OK, continue the checking
688 number
->error("INTEGER value was expected in the number form");
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());
699 Int v_Int
= v_Num
->get_val();
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());
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
;
729 if (v_Int
< 0) number
->error("A non-negative integer value was "
730 "expected instead of %s", Int2string(v_Int
).c_str());
736 void OID_comp::chk_nameandnumberform(oidstate_t
& state
)
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())
744 Int v_Int
= v
->get_val_Int()->get_val();
745 const string
& name_str
= name
->get_name();
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());
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());
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());
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());
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());
792 // no warning can be displayed in later states
797 bool OID_comp::is_valid_name_for_number(const string
& p_name
,
798 const Int
& p_number
, const nameform_t
*p_names
)
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;
810 string
OID_comp::get_expected_name_for_number(const Int
& p_number
,
811 bool p_asn1
, const nameform_t
*p_names
)
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
++;
817 if (nof_expected_names
<= 0)
818 FATAL_ERROR("OID_comp::get_expected_name_for_number()");
821 for (const nameform_t
*nf
= p_names
; nf
->name
!= NULL
; nf
++) {
822 if ((unsigned int)p_number
== nf
->value
) {
824 if (i
< nof_expected_names
- 1) ret_val
+= ", ";
825 else ret_val
+= " or ";
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();
838 void OID_comp::chk_defdvalue_ROID(ReferenceChain
& refch
)
840 Value
*v
= defdval
->get_value_refd_last();
841 switch (v
->get_valuetype()) {
845 // if the component is a reference to an integer value
846 // it shall be set to number form
847 formtype
= NUMBERFORM
;
850 chk_numberform_ROID();
856 defdval
->error("INTEGER or RELATIVE-OID value was expected");
861 void OID_comp::chk_numberform_ROID()
863 Value
*v
= number
->get_value_refd_last();
864 switch (v
->get_valuetype()) {
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());
872 Int v_Int
= v_Num
->get_val();
874 number
->error("A non-negative integer value was expected instead "
875 "of %s", Int2string(v_Int
).c_str());
880 number
->error("INTEGER value was expected in the number form");
885 void OID_comp::set_fullname(const string
& p_fullname
)
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
);
893 void OID_comp::set_my_scope(Scope
*p_scope
)
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
);
900 void OID_comp::append_stringRepr(string
& str
) const
904 str
+= name
->get_dispname();
907 case NAMEANDNUMBERFORM
:
908 str
+= number
->get_stringRepr();
911 str
+= defdval
->get_stringRepr();
914 str
+= var
->get_stringRepr();
917 str
+= "<unknown OID component>";
922 // =================================
924 // =================================
926 CharsDefn::CharsDefn(string
*p_str
)
927 : Node(), Location(), selector(CD_CSTRING
), checked(false)
929 if(!p_str
) FATAL_ERROR("CharsDefn::CharsDefn()");
933 CharsDefn::CharsDefn(Value
*p_val
)
934 : Node(), Location(), selector(CD_VALUE
), checked(false)
936 if(!p_val
) FATAL_ERROR("CharsDefn::CharsDefn()");
940 CharsDefn::CharsDefn(Int p_g
, Int p_p
, Int p_r
, Int p_c
)
941 : Node(), Location(), selector(CD_QUADRUPLE
), checked(false)
949 CharsDefn::CharsDefn(Int p_c
, Int p_r
)
950 : Node(), Location(), selector(CD_TUPLE
), checked(false)
956 CharsDefn::CharsDefn(Block
*p_block
)
957 : Node(), Location(), selector(CD_BLOCK
), checked(false)
959 if(!p_block
) FATAL_ERROR("CharsDefn::CharsDefn()");
963 CharsDefn::~CharsDefn()
980 CharsDefn
*CharsDefn::clone() const
982 FATAL_ERROR("CharsDefn::clone");
985 void CharsDefn::set_fullname(const string
& p_fullname
)
987 Node::set_fullname(p_fullname
);
990 u
.val
->set_fullname(p_fullname
);
993 u
.block
->set_fullname(p_fullname
);
1000 void CharsDefn::set_my_scope(Scope
*p_scope
)
1002 if(selector
==CD_VALUE
)
1003 u
.val
->set_my_scope(p_scope
);
1006 void CharsDefn::parse_block()
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);
1014 if(cd
->selector
==CD_QUADRUPLE
) {
1015 u
.quadruple
=cd
->u
.quadruple
;
1016 selector
=CD_QUADRUPLE
;
1019 u
.tuple
=cd
->u
.tuple
;
1025 void CharsDefn::chk()
1029 if(selector
==CD_BLOCK
) parse_block();
1032 if(u
.quadruple
.g
>127) {
1033 error("In quadruple: Group value must be in range 0..127");
1036 if(u
.quadruple
.p
>255) {
1037 error("In quadruple: Plane value must be in range 0..255");
1040 if(u
.quadruple
.r
>255) {
1041 error("In quadruple: Row value must be in range 0..255");
1044 if(u
.quadruple
.c
>255) {
1045 error("In quadruple: Cell value must be in range 0..255");
1051 error("In tuple: Column value must be in range 0..7");
1055 error("In tuple: Row value must be in range 0..15");
1064 string
CharsDefn::get_string(ReferenceChain
*refch
)
1071 error("Quadruple form is not allowed here.");
1072 return string("\0");
1074 error("Tuple form is not allowed here.");
1075 char c
=u
.tuple
.c
*16+u
.tuple
.r
;
1076 return string(1, &c
); }
1078 switch(u
.val
->get_value_refd_last(refch
)->get_valuetype()) {
1079 case Value::V_ERROR
:
1081 case Value::V_CHARSYMS
:
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).");
1089 error("Reference to string value was expected"
1090 " (instead of ISO-10646 string).");
1093 error("Reference to character string value was expected.");
1095 } // switch valuetype
1098 FATAL_ERROR("CharsDefn::get_string()");
1099 // to eliminate warning
1104 ustring
CharsDefn::get_ustring(ReferenceChain
*refch
)
1109 return ustring(*u
.str
);
1112 return ustring(u
.quadruple
.g
, u
.quadruple
.p
,
1113 u
.quadruple
.r
, u
.quadruple
.c
);
1116 error("Tuple form is not allowed here.");
1117 return ustring(0, 0, 0, u
.tuple
.c
*16+u
.tuple
.r
);
1120 switch(u
.val
->get_value_refd_last(refch
)->get_valuetype()) {
1121 case Value::V_ERROR
:
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).");
1132 error("Reference to string value was expected.");
1134 } // switch valuetype
1137 FATAL_ERROR("CharsDefn::get_ustring()");
1138 // to eliminate warning
1143 string
CharsDefn::get_iso2022string(ReferenceChain
*refch
)
1150 error("Quadruple form is not allowed here");
1151 return string("\0");
1153 char c
=u
.tuple
.c
*16+u
.tuple
.r
;
1154 return string(1, &c
); }
1156 switch(u
.val
->get_value_refd_last(refch
)->get_valuetype()) {
1157 case Value::V_ERROR
:
1160 case Value::V_ISO2022STR
:
1161 case Value::V_CHARSYMS
:
1162 return u
.val
->get_val_iso2022str();
1164 error("Reference to ISO-2022 string value was expected"
1165 " (instead of ISO-10646 string).");
1168 error("Reference to string value was expected.");
1170 } // switch valuetype
1173 FATAL_ERROR("CharsDefn::get_iso2022string()");
1174 // to eliminate warning
1179 size_t CharsDefn::get_len(ReferenceChain
*refch
)
1184 return u
.str
->size();
1189 switch(u
.val
->get_value_refd_last(refch
)->get_valuetype()) {
1190 case Value::V_ERROR
:
1194 case Value::V_ISO2022STR
:
1195 case Value::V_CHARSYMS
:
1196 return u
.val
->get_val_strlen();
1198 error("Reference to string value was expected.");
1200 } // switch valuetype
1203 FATAL_ERROR("CharsDefn::get_LEN()");
1204 // to eliminate warning
1209 void CharsDefn::dump(unsigned level
) const
1213 DEBUG(level
, "\"%s\"", u
.str
->c_str());
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());
1223 DEBUG(level
, "{%s, %s}", Int2string(u
.tuple
.c
).c_str(),
1224 Int2string(u
.tuple
.r
).c_str());
1230 u
.block
->dump(level
);
1237 // =================================
1239 // =================================
1241 CharSyms::CharSyms() : Node(), Location(), selector(CS_UNDEF
)
1245 CharSyms::~CharSyms()
1247 for(size_t i
=0; i
<cds
.size(); i
++) delete cds
[i
];
1253 case CS_ISO2022STRING
:
1260 FATAL_ERROR("CharSyms::~CharSyms()");
1264 CharSyms
*CharSyms::clone() const
1266 FATAL_ERROR("CharSyms::clone");
1269 void CharSyms::set_fullname(const string
& p_fullname
)
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
));
1276 void CharSyms::set_my_scope(Scope
*p_scope
)
1278 for(size_t i
=0; i
<cds
.size(); i
++)
1279 cds
[i
]->set_my_scope(p_scope
);
1282 void CharSyms::add_cd(CharsDefn
*p_cd
)
1288 string
CharSyms::get_string(ReferenceChain
*refch
)
1292 bool destroy_refch
=refch
==0;
1293 if(refch
) refch
->mark_state();
1294 else refch
=new ReferenceChain(this, "While checking"
1295 " charstring value");
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
;
1309 error("ISO-10646 charstring cannot be used in charstring context");
1311 case CS_ISO2022STRING
:
1312 error("ISO-2022 charstring cannot be used in charstring context");
1315 error("Circular reference in `%s'", get_fullname().c_str());
1318 FATAL_ERROR("CharSyms::get_string()");
1323 ustring
CharSyms::get_ustring(ReferenceChain
*refch
)
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
;
1344 return ustring(*u
.str
);
1345 case CS_ISO2022STRING
:
1346 error("ISO-2022 charstring cannot be used in ISO-10646 context");
1349 error("Circular reference in `%s'", get_fullname().c_str());
1352 FATAL_ERROR("CharSyms::get_ustring()");
1357 string
CharSyms::get_iso2022string(ReferenceChain
*refch
)
1361 bool destroy_refch
=refch
==0;
1362 if(refch
) refch
->mark_state();
1363 else refch
=new ReferenceChain(this, "While checking"
1364 " charstring value");
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
;
1376 case CS_ISO2022STRING
:
1379 error("ISO-10646 charstring cannot be used in ISO-2022 context");
1382 error("Circular reference in `%s'", get_fullname().c_str());
1385 FATAL_ERROR("CharSyms::get_iso2022string()");
1390 size_t CharSyms::get_len(ReferenceChain
*refch
)
1394 bool destroy_refch
=refch
==0;
1395 if(refch
) refch
->mark_state();
1396 else refch
=new ReferenceChain(this, "While checking"
1397 " charstring value");
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();
1409 case CS_ISO2022STRING
:
1410 return u
.str
->size();
1412 return u
.ustr
->size();
1414 error("Circular reference in `%s'", get_fullname().c_str());
1417 FATAL_ERROR("CharSyms::get_len()");
1422 void CharSyms::dump(unsigned level
) const
1424 DEBUG(level
, "CharSyms:");
1426 for (size_t i
= 0; i
< cds
.size(); i
++)
1427 cds
[i
]->dump(level
);
1430 } // namespace Common