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
18 * Szabo, Janos Zoltan – initial implementation
20 ******************************************************************************/
21 #include "Valuestuff.hh"
22 #include "Identifier.hh"
24 #include "asn1/Object0.hh"
25 #include "asn1/Block.hh"
26 #include "asn1/TokenBuf.hh"
33 // =================================
35 // =================================
37 Values::Values(bool p_indexed
) : Node(), indexed(p_indexed
)
39 if (!p_indexed
) vs
= new vector
<Value
>();
40 else ivs
= new vector
<IndexedValue
>();
46 for (size_t i
= 0; i
< vs
->size(); i
++) delete (*vs
)[i
];
50 for (size_t i
= 0; i
< ivs
->size(); i
++) delete (*ivs
)[i
];
56 Values
*Values::clone() const
58 FATAL_ERROR("Values::clone");
61 void Values::set_fullname(const string
& p_fullname
)
63 Node::set_fullname(p_fullname
);
65 for (size_t i
= 0; i
< vs
->size(); i
++) {
67 if (v
) v
->set_fullname(p_fullname
+ "[" + Int2string(i
) + "]");
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
74 if (iv
) iv
->set_fullname(p_fullname
+ "[" + Int2string(i
) + "]");
79 void Values::set_my_scope(Scope
*p_scope
)
82 for (size_t i
= 0; i
< vs
->size(); i
++) {
84 if (v
) v
->set_my_scope(p_scope
);
87 for (size_t i
= 0; i
< ivs
->size(); i
++) {
88 IndexedValue
*iv
= (*ivs
)[i
];
89 if (iv
) iv
->set_my_scope(p_scope
);
94 size_t Values::get_nof_vs() const
96 if (indexed
) FATAL_ERROR("Values::get_nof_vs()");
100 size_t Values::get_nof_ivs() const
102 if (!indexed
) FATAL_ERROR("Values::get_nof_ivs()");
106 Value
*Values::get_v_byIndex(size_t p_i
) const
108 if (indexed
) FATAL_ERROR("Values::get_v_byIndex");
112 IndexedValue
*Values::get_iv_byIndex(size_t p_i
) const
114 if (!indexed
) FATAL_ERROR("Values::get_iv_byIndex()");
118 void Values::add_v(Value
*p_v
)
120 if (!p_v
) FATAL_ERROR("Values::add_v(): NULL parameter");
121 if (indexed
) FATAL_ERROR("Values::add_v()");
125 void Values::add_iv(IndexedValue
*p_iv
)
127 if (!p_iv
) FATAL_ERROR("Values::add_iv(): NULL parameter");
128 if (!indexed
) FATAL_ERROR("Values::add_iv()");
132 Value
*Values::steal_v_byIndex(size_t p_i
)
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()");
141 void Values::dump(unsigned level
) const
144 for (size_t i
= 0; i
< vs
->size(); i
++) {
146 if (v
) v
->dump(level
);
147 else DEBUG(level
, "Value: stolen");
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");
158 // =================================
159 // ===== IndexedValue
160 // =================================
162 IndexedValue::IndexedValue(Ttcn::FieldOrArrayRef
*p_index
, Value
*p_value
)
163 : Node(), Location(), index(p_index
), value(p_value
)
165 if (!p_index
|| !p_value
)
166 FATAL_ERROR("NULL parameter: IndexedValue::IndexedValue()");
169 IndexedValue::~IndexedValue()
175 IndexedValue
*IndexedValue::clone() const
177 FATAL_ERROR("IndexedValue::clone");
180 void IndexedValue::set_fullname(const string
& p_fullname
)
182 Node::set_fullname(p_fullname
);
183 if (value
) value
->set_fullname(p_fullname
);
184 if (index
) index
->set_fullname(p_fullname
);
187 void IndexedValue::set_my_scope(Scope
*p_scope
)
189 if (value
) value
->set_my_scope(p_scope
);
190 if (index
) index
->set_my_scope(p_scope
);
193 void IndexedValue::set_code_section
194 (GovernedSimple::code_section_t p_code_section
)
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
);
201 Value
*IndexedValue::steal_value()
203 if (!value
) FATAL_ERROR("IndexedValue::steal_value()");
209 void IndexedValue::dump(unsigned level
) const
212 if (value
) value
->dump(level
+ 1);
213 else DEBUG(level
+ 1, "Value: stolen");
216 bool IndexedValue::is_unfoldable(ReferenceChain
*refch
,
217 Type::expected_value_t exp_val
)
219 return (value
->is_unfoldable(refch
, exp_val
) ||
220 get_index()->is_unfoldable(refch
, exp_val
));
223 // =================================
225 // =================================
227 NamedValue::NamedValue(Identifier
*p_name
, Value
*p_value
)
228 : Node(), Location(), name(p_name
), value(p_value
)
230 if (!p_name
|| !p_value
)
231 FATAL_ERROR("NULL parameter: NamedValue::NamedValue()");
234 NamedValue::NamedValue(const NamedValue
& p
)
235 : Node(p
), Location(p
)
237 if (!p
.value
) FATAL_ERROR("NamedValue::NamedValue(): value is stolen");
238 name
= p
.name
->clone();
239 value
= p
.value
->clone();
242 NamedValue::~NamedValue()
248 NamedValue
*NamedValue::clone() const
250 return new NamedValue(*this);
253 void NamedValue::set_fullname(const string
& p_fullname
)
255 Node::set_fullname(p_fullname
);
256 if (value
) value
->set_fullname(p_fullname
);
259 void NamedValue::set_my_scope(Scope
*p_scope
)
261 if (value
) value
->set_my_scope(p_scope
);
264 Value
*NamedValue::steal_value()
266 if (!value
) FATAL_ERROR("NamedValue::steal_value()");
272 void NamedValue::dump(unsigned level
) const
275 if (value
) value
->dump(level
+ 1);
276 else DEBUG(level
+ 1, "Value: stolen");
279 // =================================
281 // =================================
283 NamedValues::NamedValues(const NamedValues
& p
)
284 : Node(p
), checked(false)
286 for (size_t i
= 0; i
< p
.nvs_v
.size(); i
++)
287 nvs_v
.add(p
.nvs_v
[i
]->clone());
290 NamedValues::~NamedValues()
292 for(size_t i
= 0; i
< nvs_v
.size(); i
++) delete nvs_v
[i
];
297 NamedValues
*NamedValues::clone() const
299 return new NamedValues(*this);
302 void NamedValues::set_fullname(const string
& p_fullname
)
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());
311 void NamedValues::set_my_scope(Scope
*p_scope
)
313 for (size_t i
= 0; i
< nvs_v
.size(); i
++)
314 nvs_v
[i
]->set_my_scope(p_scope
);
317 void NamedValues::add_nv(NamedValue
*p_nv
)
319 if (!p_nv
) FATAL_ERROR("NamedValues::add_nv(): NULL parameter");
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
);
328 bool NamedValues::has_nv_withName(const Identifier
& p_name
)
330 if (!checked
) chk_dupl_id(false);
331 return nvs_m
.has_key(p_name
.get_name());
334 NamedValue
* NamedValues::get_nv_byName(const Identifier
& p_name
)
336 if (!checked
) chk_dupl_id(false);
337 return nvs_m
[p_name
.get_name()];
340 void NamedValues::chk_dupl_id(bool report_errors
)
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
);
357 void NamedValues::dump(unsigned level
) const
359 for (size_t i
= 0; i
< nvs_v
.size(); i
++)
360 nvs_v
[i
]->dump(level
);
363 // =================================
365 // =================================
367 const OID_comp::nameform_t
OID_comp::names_root
[] = {
372 { "joint__iso__itu__t", 2 },
373 { "joint__iso__ccitt", 2 },
377 const OID_comp::nameform_t
OID_comp::names_itu
[] = {
378 { "recommendation", 0 },
380 { "administration", 2 },
381 { "network__operator", 3 },
382 { "identified__organization", 4 },
383 { "r__recommendation", 5 },
387 const OID_comp::nameform_t
OID_comp::names_iso
[] = {
389 { "registration__authority", 1 },
390 { "member__body", 2 },
391 { "identified__organization", 3 },
395 // taken from OID repository: http://asn1.elibel.tm.fr/oid/
396 const OID_comp::nameform_t
OID_comp::names_joint
[] = {
397 { "presentation", 0 },
399 { "association__control", 2 },
400 { "reliable__transfer", 3 },
401 { "remote__operations", 4 },
409 { "osi__management", 9 },
410 { "transaction__processing", 10 },
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 },
422 { "registration__procedures", 17 },
423 { "registration__procedure", 17 },
424 { "physical__layer", 18 },
425 { "physical__layer__management", 18 },
427 { "genericULS", 20 },
428 { "generic__upper__layers__security", 20 },
430 { "transport__layer__security__protocol", 21 },
431 { "network__layer__security__protocol", 22 },
432 { "international__organizations", 23 },
433 { "internationalRA", 23 },
441 OID_comp::OID_comp(Identifier
*p_name
, Value
*p_number
)
442 : Node(), Location(), defdval(0), name(p_name
), number(p_number
), var(0)
445 if (p_number
) formtype
= NAMEANDNUMBERFORM
;
446 else formtype
= NAMEFORM
;
448 if (p_number
) formtype
= NUMBERFORM
;
449 else FATAL_ERROR("NULL parameter: Common::OID_comp::OID_comp()");
453 OID_comp::OID_comp(Value
*p_defdval
)
454 : Node(), Location(), formtype(DEFDVALUE
), defdval(p_defdval
), name(0),
458 FATAL_ERROR("NULL parameter: Common::OID_comp::OID_comp()");
461 OID_comp::~OID_comp()
469 OID_comp
*OID_comp::clone() const
471 FATAL_ERROR("OID_comp::clone");
474 void OID_comp::chk_OID(ReferenceChain
& refch
, Value
*parent
, size_t index
,
477 Error_Context
ec(this, "In component #%lu of OBJECT IDENTIFIER value",
478 (unsigned long) (index
+ 1));
481 Int v_Int
= detect_nameform(state
);
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
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
);
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
;
505 chk_defdvalue_OID(refch
, state
);
508 chk_numberform_OID(state
);
510 case NAMEANDNUMBERFORM
:
511 chk_nameandnumberform(state
);
514 FATAL_ERROR("OID_comp::chk_OID()");
518 void OID_comp::chk_ROID(ReferenceChain
& refch
, size_t index
)
520 Error_Context
ec(this, "In component #%lu of RELATIVE-OID value",
521 (unsigned long) (index
+ 1));
524 chk_defdvalue_ROID(refch
);
527 case NAMEANDNUMBERFORM
:
528 chk_numberform_ROID();
531 FATAL_ERROR("OID_comp::chk_ROID()");
535 bool OID_comp::has_error()
537 if (formtype
== DEFDVALUE
) return defdval
->has_oid_error();
538 else return number
->get_value_refd_last()->get_valuetype() != Value::V_INT
;
541 void OID_comp::get_comps(vector
<string
>& comps
)
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() + ")"));
547 else comps
.add(new string(number
->get_stringRepr() + "u"));
550 bool OID_comp::is_variable()
552 return (formtype
== VARIABLE
);
555 Int
OID_comp::detect_nameform(oidstate_t
& state
)
557 const string
& name_str
= name
->get_name();
561 if (name_str
== "itu__t" || name_str
== "ccitt") {
564 } else if (name_str
== "itu__r") {
565 warning("Identifier `%s' should not be used as NameForm",
566 name
->get_dispname().c_str());
569 } else if (name_str
== "iso") {
572 } else if (name_str
== "joint__iso__itu__t"
573 || name_str
== "joint__iso__ccitt") {
579 for (const nameform_t
*nf
= names_itu
; nf
->name
!= NULL
; nf
++) {
580 if (name_str
== nf
->name
) {
587 warning("Identifier `%s' should not be used as NameForm",
588 name
->get_dispname().c_str());
598 for (const nameform_t
*nf
= names_iso
; nf
->name
!= NULL
; nf
++) {
599 if (name_str
== nf
->name
) {
607 for (const nameform_t
*nf
= names_joint
; nf
->name
!= NULL
; nf
++) {
608 if (name_str
== nf
->name
) {
611 warning("Identifier `%s' should not be used as NameForm",
612 name
->get_dispname().c_str());
618 if (name_str
.size() == 1) {
619 char c
= name_str
[0];
620 if (c
>= 'a' && c
<= 'z') {
621 ret_val
= c
- 'a' + 1;
632 void OID_comp::chk_defdvalue_OID(ReferenceChain
& refch
, oidstate_t
& state
)
634 Value
*v
= defdval
->get_value_refd_last();
635 switch (v
->get_valuetype()) {
640 // if the component is a reference to an integer value
641 // it shall be set to number form
642 formtype
= NUMBERFORM
;
645 chk_numberform_OID(state
);
648 if (state
!= START
) defdval
->error("INTEGER or RELATIVE-OID "
649 "value was expected");
661 defdval
->error("RELATIVE-OID value cannot be used as the "
662 "%s component of an OBJECT IDENTIFIER value",
663 state
== START
? "first" : "second");
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
) {
677 defdval
->error("INTEGER variable was expected");
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");
690 void OID_comp::chk_numberform_OID(oidstate_t
& state
)
692 Value
*v
= number
->get_value_refd_last();
693 switch (v
->get_valuetype()) {
695 // everything is OK, continue the checking
701 number
->error("INTEGER value was expected in the number form");
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());
712 Int v_Int
= v_Num
->get_val();
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());
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
;
742 if (v_Int
< 0) number
->error("A non-negative integer value was "
743 "expected instead of %s", Int2string(v_Int
).c_str());
749 void OID_comp::chk_nameandnumberform(oidstate_t
& state
)
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())
757 Int v_Int
= v
->get_val_Int()->get_val();
758 const string
& name_str
= name
->get_name();
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());
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());
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());
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());
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());
805 // no warning can be displayed in later states
810 bool OID_comp::is_valid_name_for_number(const string
& p_name
,
811 const Int
& p_number
, const nameform_t
*p_names
)
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;
823 string
OID_comp::get_expected_name_for_number(const Int
& p_number
,
824 bool p_asn1
, const nameform_t
*p_names
)
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
++;
830 if (nof_expected_names
<= 0)
831 FATAL_ERROR("OID_comp::get_expected_name_for_number()");
834 for (const nameform_t
*nf
= p_names
; nf
->name
!= NULL
; nf
++) {
835 if ((unsigned int)p_number
== nf
->value
) {
837 if (i
< nof_expected_names
- 1) ret_val
+= ", ";
838 else ret_val
+= " or ";
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();
851 void OID_comp::chk_defdvalue_ROID(ReferenceChain
& refch
)
853 Value
*v
= defdval
->get_value_refd_last();
854 switch (v
->get_valuetype()) {
858 // if the component is a reference to an integer value
859 // it shall be set to number form
860 formtype
= NUMBERFORM
;
863 chk_numberform_ROID();
869 defdval
->error("INTEGER or RELATIVE-OID value was expected");
874 void OID_comp::chk_numberform_ROID()
876 Value
*v
= number
->get_value_refd_last();
877 switch (v
->get_valuetype()) {
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());
885 Int v_Int
= v_Num
->get_val();
887 number
->error("A non-negative integer value was expected instead "
888 "of %s", Int2string(v_Int
).c_str());
893 number
->error("INTEGER value was expected in the number form");
898 void OID_comp::set_fullname(const string
& p_fullname
)
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
);
906 void OID_comp::set_my_scope(Scope
*p_scope
)
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
);
913 void OID_comp::append_stringRepr(string
& str
) const
917 str
+= name
->get_dispname();
920 case NAMEANDNUMBERFORM
:
921 str
+= number
->get_stringRepr();
924 str
+= defdval
->get_stringRepr();
927 str
+= var
->get_stringRepr();
930 str
+= "<unknown OID component>";
935 // =================================
937 // =================================
939 CharsDefn::CharsDefn(string
*p_str
)
940 : Node(), Location(), selector(CD_CSTRING
), checked(false)
942 if(!p_str
) FATAL_ERROR("CharsDefn::CharsDefn()");
946 CharsDefn::CharsDefn(Value
*p_val
)
947 : Node(), Location(), selector(CD_VALUE
), checked(false)
949 if(!p_val
) FATAL_ERROR("CharsDefn::CharsDefn()");
953 CharsDefn::CharsDefn(Int p_g
, Int p_p
, Int p_r
, Int p_c
)
954 : Node(), Location(), selector(CD_QUADRUPLE
), checked(false)
962 CharsDefn::CharsDefn(Int p_c
, Int p_r
)
963 : Node(), Location(), selector(CD_TUPLE
), checked(false)
969 CharsDefn::CharsDefn(Block
*p_block
)
970 : Node(), Location(), selector(CD_BLOCK
), checked(false)
972 if(!p_block
) FATAL_ERROR("CharsDefn::CharsDefn()");
976 CharsDefn::~CharsDefn()
993 CharsDefn
*CharsDefn::clone() const
995 FATAL_ERROR("CharsDefn::clone");
998 void CharsDefn::set_fullname(const string
& p_fullname
)
1000 Node::set_fullname(p_fullname
);
1003 u
.val
->set_fullname(p_fullname
);
1006 u
.block
->set_fullname(p_fullname
);
1013 void CharsDefn::set_my_scope(Scope
*p_scope
)
1015 if(selector
==CD_VALUE
)
1016 u
.val
->set_my_scope(p_scope
);
1019 void CharsDefn::parse_block()
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);
1027 if(cd
->selector
==CD_QUADRUPLE
) {
1028 u
.quadruple
=cd
->u
.quadruple
;
1029 selector
=CD_QUADRUPLE
;
1032 u
.tuple
=cd
->u
.tuple
;
1038 void CharsDefn::chk()
1042 if(selector
==CD_BLOCK
) parse_block();
1045 if(u
.quadruple
.g
>127) {
1046 error("In quadruple: Group value must be in range 0..127");
1049 if(u
.quadruple
.p
>255) {
1050 error("In quadruple: Plane value must be in range 0..255");
1053 if(u
.quadruple
.r
>255) {
1054 error("In quadruple: Row value must be in range 0..255");
1057 if(u
.quadruple
.c
>255) {
1058 error("In quadruple: Cell value must be in range 0..255");
1064 error("In tuple: Column value must be in range 0..7");
1068 error("In tuple: Row value must be in range 0..15");
1077 string
CharsDefn::get_string(ReferenceChain
*refch
)
1084 error("Quadruple form is not allowed here.");
1085 return string("\0");
1087 error("Tuple form is not allowed here.");
1088 char c
=u
.tuple
.c
*16+u
.tuple
.r
;
1089 return string(1, &c
); }
1091 switch(u
.val
->get_value_refd_last(refch
)->get_valuetype()) {
1092 case Value::V_ERROR
:
1094 case Value::V_CHARSYMS
:
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).");
1102 error("Reference to string value was expected"
1103 " (instead of ISO-10646 string).");
1106 error("Reference to character string value was expected.");
1108 } // switch valuetype
1111 FATAL_ERROR("CharsDefn::get_string()");
1112 // to eliminate warning
1117 ustring
CharsDefn::get_ustring(ReferenceChain
*refch
)
1122 return ustring(*u
.str
);
1125 return ustring(u
.quadruple
.g
, u
.quadruple
.p
,
1126 u
.quadruple
.r
, u
.quadruple
.c
);
1129 error("Tuple form is not allowed here.");
1130 return ustring(0, 0, 0, u
.tuple
.c
*16+u
.tuple
.r
);
1133 switch(u
.val
->get_value_refd_last(refch
)->get_valuetype()) {
1134 case Value::V_ERROR
:
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).");
1145 error("Reference to string value was expected.");
1147 } // switch valuetype
1150 FATAL_ERROR("CharsDefn::get_ustring()");
1151 // to eliminate warning
1156 string
CharsDefn::get_iso2022string(ReferenceChain
*refch
)
1163 error("Quadruple form is not allowed here");
1164 return string("\0");
1166 char c
=u
.tuple
.c
*16+u
.tuple
.r
;
1167 return string(1, &c
); }
1169 switch(u
.val
->get_value_refd_last(refch
)->get_valuetype()) {
1170 case Value::V_ERROR
:
1173 case Value::V_ISO2022STR
:
1174 case Value::V_CHARSYMS
:
1175 return u
.val
->get_val_iso2022str();
1177 error("Reference to ISO-2022 string value was expected"
1178 " (instead of ISO-10646 string).");
1181 error("Reference to string value was expected.");
1183 } // switch valuetype
1186 FATAL_ERROR("CharsDefn::get_iso2022string()");
1187 // to eliminate warning
1192 size_t CharsDefn::get_len(ReferenceChain
*refch
)
1197 return u
.str
->size();
1202 switch(u
.val
->get_value_refd_last(refch
)->get_valuetype()) {
1203 case Value::V_ERROR
:
1207 case Value::V_ISO2022STR
:
1208 case Value::V_CHARSYMS
:
1209 return u
.val
->get_val_strlen();
1211 error("Reference to string value was expected.");
1213 } // switch valuetype
1216 FATAL_ERROR("CharsDefn::get_LEN()");
1217 // to eliminate warning
1222 void CharsDefn::dump(unsigned level
) const
1226 DEBUG(level
, "\"%s\"", u
.str
->c_str());
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());
1236 DEBUG(level
, "{%s, %s}", Int2string(u
.tuple
.c
).c_str(),
1237 Int2string(u
.tuple
.r
).c_str());
1243 u
.block
->dump(level
);
1250 // =================================
1252 // =================================
1254 CharSyms::CharSyms() : Node(), Location(), selector(CS_UNDEF
)
1258 CharSyms::~CharSyms()
1260 for(size_t i
=0; i
<cds
.size(); i
++) delete cds
[i
];
1266 case CS_ISO2022STRING
:
1273 FATAL_ERROR("CharSyms::~CharSyms()");
1277 CharSyms
*CharSyms::clone() const
1279 FATAL_ERROR("CharSyms::clone");
1282 void CharSyms::set_fullname(const string
& p_fullname
)
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
));
1289 void CharSyms::set_my_scope(Scope
*p_scope
)
1291 for(size_t i
=0; i
<cds
.size(); i
++)
1292 cds
[i
]->set_my_scope(p_scope
);
1295 void CharSyms::add_cd(CharsDefn
*p_cd
)
1301 string
CharSyms::get_string(ReferenceChain
*refch
)
1305 bool destroy_refch
=refch
==0;
1306 if(refch
) refch
->mark_state();
1307 else refch
=new ReferenceChain(this, "While checking"
1308 " charstring value");
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
;
1322 error("ISO-10646 charstring cannot be used in charstring context");
1324 case CS_ISO2022STRING
:
1325 error("ISO-2022 charstring cannot be used in charstring context");
1328 error("Circular reference in `%s'", get_fullname().c_str());
1331 FATAL_ERROR("CharSyms::get_string()");
1336 ustring
CharSyms::get_ustring(ReferenceChain
*refch
)
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
;
1357 return ustring(*u
.str
);
1358 case CS_ISO2022STRING
:
1359 error("ISO-2022 charstring cannot be used in ISO-10646 context");
1362 error("Circular reference in `%s'", get_fullname().c_str());
1365 FATAL_ERROR("CharSyms::get_ustring()");
1370 string
CharSyms::get_iso2022string(ReferenceChain
*refch
)
1374 bool destroy_refch
=refch
==0;
1375 if(refch
) refch
->mark_state();
1376 else refch
=new ReferenceChain(this, "While checking"
1377 " charstring value");
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
;
1389 case CS_ISO2022STRING
:
1392 error("ISO-10646 charstring cannot be used in ISO-2022 context");
1395 error("Circular reference in `%s'", get_fullname().c_str());
1398 FATAL_ERROR("CharSyms::get_iso2022string()");
1403 size_t CharSyms::get_len(ReferenceChain
*refch
)
1407 bool destroy_refch
=refch
==0;
1408 if(refch
) refch
->mark_state();
1409 else refch
=new ReferenceChain(this, "While checking"
1410 " charstring value");
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();
1422 case CS_ISO2022STRING
:
1423 return u
.str
->size();
1425 return u
.ustr
->size();
1427 error("Circular reference in `%s'", get_fullname().c_str());
1430 FATAL_ERROR("CharSyms::get_len()");
1435 void CharSyms::dump(unsigned level
) const
1437 DEBUG(level
, "CharSyms:");
1439 for (size_t i
= 0; i
< cds
.size(); i
++)
1440 cds
[i
]->dump(level
);
1443 } // namespace Common