1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 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 "../common/dbgnew.hh"
9 #include "Identifier.hh"
12 #include "CompilerError.hh"
16 // =================================
17 // ===== Identifier::id_data_t
18 // =================================
20 struct Identifier::id_data_t
{
22 string name
, asnname
, ttcnname
;
23 /** ASN kind of the identifier. */
25 ASN_UNDEF
, /**< undefined */
26 ASN_LOWER
, /**< LOWERIDENTIFIER [a-z](-?[A-Za-z0-9]+)* */
27 ASN_UPPER
, /**< UPPERIDENTIFIER [A-Z](-?[A-Za-z0-9]+)* */
28 ASN_ALLUPPER
, /**< ALLUPPERIDENTIFIER [A-Z](-?[A-Z0-9]+)* */
29 ASN_WORD
, /**< WORD [A-Z](-?[A-Z]+)* */
30 ASN_ampUPPER
, /**< ampUPPERIDENTIFIER \\\&{UPPERIDENTIFIER} */
31 ASN_ampLOWER
/**< ampLOWERIDENTIFIER \\\&{LOWERIDENTIFIER} */
33 static void asn_2_name(string
& p_to
, const string
& p_from
);
34 static void name_2_asn(string
& p_to
, const string
& p_from
);
35 static void ttcn_2_name(string
& p_to
, const string
& p_from
);
36 static void name_2_ttcn(string
& p_to
, const string
& p_from
);
37 id_data_t(const string
& p_name
)
38 : ref_count(1), name(p_name
), asnname(), ttcnname(), asn_kind(ASN_UNDEF
){}
39 static void delete_this(id_data_t
*p_id_data_t
);
40 /** Gets the internal (and C++) name. */
41 const string
& get_name() const {return name
;}
42 /** Gets the ASN display name. */
43 const string
& get_asnname();
44 /** Gets the TTCN display name. */
45 const string
& get_ttcnname();
46 bool get_has_valid(id_t p_id_t
);
47 string
get_names() const;
48 /** True if it is a valid ASN modulereference. */
49 bool isvalid_asn_modref();
50 /** True if it is a valid ASN typereference. */
51 bool isvalid_asn_typeref();
52 /** True if it is a valid ASN valuereference. */
53 bool isvalid_asn_valref();
54 /** True if it is a valid ASN valuesetreference. */
55 bool isvalid_asn_valsetref();
56 /** True if it is a valid ASN objectclassreference. */
57 bool isvalid_asn_objclassref();
58 /** True if it is a valid ASN objectreference. */
59 bool isvalid_asn_objref();
60 /** True if it is a valid ASN objectsetreference. */
61 bool isvalid_asn_objsetref();
62 /** True if it is a valid ASN typefieldreference. */
63 bool isvalid_asn_typefieldref();
64 /** True if it is a valid ASN valuefieldreference. */
65 bool isvalid_asn_valfieldref();
66 /** True if it is a valid ASN valuesetfieldreference. */
67 bool isvalid_asn_valsetfieldref();
68 /** True if it is a valid ASN objectfieldreference. */
69 bool isvalid_asn_objfieldref();
70 /** True if it is a valid ASN objectsetfieldreference. */
71 bool isvalid_asn_objsetfieldref();
72 /** True if it is a valid ASN "word". */
73 bool isvalid_asn_word();
76 void decide_asn_kind();
79 // =================================
80 // ===== internal_data_t
81 // =================================
83 class internal_data_t
{
85 static internal_data_t
*instance
;
86 static const char* const keywords
[][3];
87 size_t identifier_counter
;
89 const string string_invalid
;
90 /** Container for identifiers, indexed by ID_NAME. */
91 map
<string
, Identifier::id_data_t
> id_map_name
;
92 /** Container for identifiers, indexed by ID_ASN. */
93 map
<string
, Identifier::id_data_t
> id_map_asn
;
94 /** Container for identifiers, indexed by ID_TTCN. */
95 map
<string
, Identifier::id_data_t
> id_map_ttcn
;
98 internal_data_t(const internal_data_t
&);
100 void add_keyword(const char* const keyword
[3]);
103 static internal_data_t
*Instance();
104 /** Increases the instance counter. Initializes the keywords if
105 * this is the first instance. Must be called in every Identifier
107 void increase_counter();
108 /** Decreases the instance counter. Finalizes the keywords if this
109 * is the last instance. Must be called in Identifier
111 void decrease_counter();
114 // ======================================================================
115 // ======================================================================
117 // =================================
118 // ===== Identifier::id_data_t
119 // =================================
121 void Identifier::id_data_t::asn_2_name(string
& p_to
, const string
& p_from
)
124 /* "@aaa" -> "_root_aaa" */
125 if (p_to
.size() > 0 && p_to
[0] == '@') p_to
.replace(0, 1, "_root_");
126 /* "aa.<xxxx>.bb" -> "aa.bb" */
128 while ((pos
= p_to
.find(".<", pos
)) < p_to
.size()) {
129 size_t pos2
= p_to
.find(">.", pos
);
130 if (pos2
< p_to
.size()) p_to
.replace(pos
, pos2
+ 1 - pos
, "");
135 while ((pos
= p_to
.find('-', pos
)) < p_to
.size()) {
136 p_to
.replace(pos
, 1, "__");
141 while ((pos
= p_to
.find('.', pos
)) < p_to
.size()) {
147 while ((pos
= p_to
.find('&', pos
)) < p_to
.size())
148 p_to
.replace(pos
, 1, "");
151 void Identifier::id_data_t::name_2_asn(string
& p_to
, const string
& p_from
)
154 /* remove leading '_'s */
156 while (pos
< p_to
.size() && p_to
[pos
] == '_') pos
++;
157 if (pos
> 0) p_to
.replace(0, pos
, "");
158 /* remove trailing '_'s */
160 while (pos
> 0 && p_to
[pos
- 1] == '_') pos
--;
161 if (pos
< p_to
.size()) p_to
.resize(pos
);
164 while ((pos
= p_to
.find("__", pos
)) < p_to
.size()) {
165 p_to
.replace(pos
, 2, "-");
170 while ((pos
= p_to
.find('_', pos
)) < p_to
.size()) {
176 void Identifier::id_data_t::ttcn_2_name(string
& p_to
, const string
& p_from
)
181 while ((pos
= p_to
.find('_', pos
)) < p_to
.size()) {
182 p_to
.replace(pos
, 1, "__");
187 void Identifier::id_data_t::name_2_ttcn(string
& p_to
, const string
& p_from
)
190 /* remove leading '_'s */
192 while (pos
< p_to
.size() && p_to
[pos
] == '_') pos
++;
193 if (pos
> 0) p_to
.replace(0, pos
, "");
194 /* remove trailing '_'s */
196 while (pos
> 0 && p_to
[pos
- 1] == '_') pos
--;
197 if (pos
< p_to
.size()) p_to
.resize(pos
);
200 while ((pos
= p_to
.find("__", pos
)) < p_to
.size()) {
201 p_to
.replace(pos
, 1, "");
206 const string
& Identifier::id_data_t::get_asnname()
208 if (asnname
.empty()) name_2_asn(asnname
, name
);
212 const string
& Identifier::id_data_t::get_ttcnname()
214 if (ttcnname
.empty()) name_2_ttcn(ttcnname
, name
);
218 bool Identifier::id_data_t::get_has_valid(id_t p_id_t
)
220 const string
& inval
=internal_data_t::Instance()->string_invalid
;
223 return get_name()!=inval
;
225 return get_asnname()!=inval
;
227 return get_ttcnname()!=inval
;
229 FATAL_ERROR("Identifier::id_data_t::get_has_valid()");
234 void Identifier::id_data_t::delete_this(id_data_t
*p_id_data_t
)
236 p_id_data_t
->ref_count
--;
237 if(p_id_data_t
->ref_count
==0)
241 string
Identifier::id_data_t::get_names() const
243 const string
& inval
=internal_data_t::Instance()->string_invalid
;
244 string s
="(C++: `"+name
+"'";
245 if(!asnname
.empty() && asnname
!=inval
)
246 s
+=", ASN: `"+asnname
+"'";
247 if(!ttcnname
.empty() && ttcnname
!=inval
)
248 s
+=", TTCN: `"+ttcnname
+"'";
253 void Identifier::id_data_t::decide_asn_kind()
255 if(asn_kind
!=ASN_UNDEF
) return;
257 if(asnname
==internal_data_t::Instance()->string_invalid
) return;
258 if(asnname
[0]=='&') {
259 if(asnname
.size()>=2) {
260 if(isupper(asnname
[1]))
261 asn_kind
=ASN_ampUPPER
;
262 else if(islower(asnname
[1]))
263 asn_kind
=ASN_ampLOWER
;
266 else if(islower(asnname
[0])) {
269 else if(isupper(asnname
[0])) {
271 if(asnname
.find_if(0, asnname
.size(), islower
)==asnname
.size()) {
272 asn_kind
=ASN_ALLUPPER
;
273 if(asnname
.find_if(0, asnname
.size(), isdigit
)==asnname
.size()) {
280 bool Identifier::id_data_t::isvalid_asn_modref()
282 return isvalid_asn_typeref();
285 bool Identifier::id_data_t::isvalid_asn_typeref()
288 return (asn_kind
==ASN_UPPER
289 || asn_kind
==ASN_ALLUPPER
290 || asn_kind
==ASN_WORD
);
293 bool Identifier::id_data_t::isvalid_asn_valref()
296 return (asn_kind
==ASN_LOWER
);
299 bool Identifier::id_data_t::isvalid_asn_valsetref()
301 return isvalid_asn_typeref();
304 bool Identifier::id_data_t::isvalid_asn_objclassref()
307 return (asn_kind
==ASN_ALLUPPER
308 || asn_kind
==ASN_WORD
);
311 bool Identifier::id_data_t::isvalid_asn_objref()
314 return (asn_kind
==ASN_LOWER
);
317 bool Identifier::id_data_t::isvalid_asn_objsetref()
319 return isvalid_asn_typeref();
322 bool Identifier::id_data_t::isvalid_asn_typefieldref()
325 return (asn_kind
==ASN_ampUPPER
);
328 bool Identifier::id_data_t::isvalid_asn_valfieldref()
331 return (asn_kind
==ASN_ampLOWER
);
334 bool Identifier::id_data_t::isvalid_asn_valsetfieldref()
337 return (asn_kind
==ASN_ampUPPER
);
340 bool Identifier::id_data_t::isvalid_asn_objfieldref()
343 return (asn_kind
==ASN_ampLOWER
);
346 bool Identifier::id_data_t::isvalid_asn_objsetfieldref()
349 return (asn_kind
==ASN_ampUPPER
);
352 bool Identifier::id_data_t::isvalid_asn_word()
355 return (asn_kind
==ASN_WORD
);
358 // =================================
359 // ===== internal_data_t
360 // =================================
362 internal_data_t
*internal_data_t::instance
=0;
364 /* format: c++ - asn - ttcn */
365 const char* const internal_data_t::keywords
[][3] = {
366 /* C++ keywords - never can be used */
381 {"const_cast", 0, 0},
387 {"dynamic_cast", 0, 0},
414 {"reinterpret_cast", 0, 0},
420 {"static_cast", 0, 0},
441 /* C++ keywords postfixed, avoiding conflicts from valid ASN/TTCN names */
442 {"asm_", "asm", "asm"},
443 {"auto_", "auto", "auto"},
444 {"bitand_", "bitand", "bitand"},
445 {"bitor_", "bitor", "bitor"},
446 {"bool_", "bool", "bool"},
447 {"class_", "class", "class"},
448 {"compl_", "compl", "compl"},
449 {"delete_", "delete", "delete"},
450 {"double_", "double", "double"},
451 {"enum_", "enum", "enum"},
452 {"explicit_", "explicit", "explicit"},
453 {"export_", "export", "export"},
454 {"extern_", "extern", "extern"},
455 {"friend__", "friend", "friend_"},
456 {"inline_", "inline", "inline"},
457 {"int_", "int", "int"},
458 {"long_", "long", "long"},
459 {"mutable_", "mutable", "mutable"},
460 {"namespace_", "namespace", "namespace"},
461 {"new_", "new", "new"},
462 {"operator_", "operator", "operator"},
463 {"private__", "private", "private_"},
464 {"protected_", "protected", "protected"},
465 {"public__", "public", "public_"},
466 {"register_", "register", "register"},
467 {"short_", "short", "short"},
468 {"signed_", "signed", "signed"},
469 {"static_", "static", "static"},
470 {"struct_", "struct", "struct"},
471 {"switch_", "switch", "switch"},
472 {"this_", "this", "this"},
473 {"throw_", "throw", "throw"},
474 {"try_", "try", "try"},
475 {"typedef_", "typedef", "typedef"},
476 {"typeid_", "typeid", "typeid"},
477 {"typename_", "typename", "typename"},
478 {"unsigned_", "unsigned", "unsigned"},
479 {"using_", "using", "using"},
480 {"virtual_", "virtual", "virtual"},
481 {"void_", "void", "void"},
482 {"volatile_", "volatile", "volatile"},
483 /* C++ keywords postfixed - keywords in TTCN */
484 {"and__", "and", "and_"},
485 {"break__", "break", "break_"},
486 {"case__", "case", "case_"},
487 {"catch__", "catch", "catch_"},
488 {"char__", "char", "char_"},
489 {"const__", "const", "const_"},
490 {"continue__", "continue", "continue_"},
491 {"default__", "default", "default_"},
492 {"do__", "do", "do_"},
493 {"else__", "else", "else_"},
494 {"false__", "false", "false_"},
495 {"float__", "float", "float_"},
496 {"for__", "for", "for_"},
497 {"goto__", "goto", "goto_"},
498 {"if__", "if", "if_"},
499 {"not__", "not", "not_"},
500 {"or__", "or", "or_"},
501 {"return__", "return", "return_"},
502 {"sizeof__", "sizeof", "sizeof_"},
503 {"template__", "template", "template_"},
504 {"true__", "true", "true_"},
505 {"union__", "union", "union_"},
506 {"while__", "while", "while_"},
507 {"xor__", "xor", "xor_"},
508 /* reserved names of base library */
541 {"int2unichar", 0, 0},
561 {"stderr", 0, 0}, // temporary hack
562 {"stdin", 0, 0}, // temporary hack
563 {"stdout", 0, 0}, // temporary hack
570 {"unichar2int", 0, 0},
571 {"unichar2char", 0, 0},
573 {"verdicttype", 0, 0},
574 {"unichar2oct", 0, 0},
575 {"oct2unichar", 0, 0},
576 {"get_stringencoding", 0, 0},
577 {"remove_bom", 0, 0},
578 {"encode_base64", 0, 0},
579 {"decode_base64", 0, 0},
580 /* reserved names of base library - keywords in TTCN - valid ASN.1 */
581 {"bit2hex__", "bit2hex", "bit2hex_"},
582 {"bit2int__", "bit2int", "bit2int_"},
583 {"bit2oct__", "bit2oct", "bit2oct_"},
584 {"bit2str__", "bit2str", "bit2str_"},
585 {"boolean__", "boolean", "boolean_"},
586 {"char2int__", "char2int", "char2int_"},
587 {"char2oct__", "char2oct", "char2oct_"},
588 {"component__", "component", "component_"},
589 {"decomp__", "decomp", "decomp_"},
590 {"float2int__", "float2int", "float2int_"},
591 {"float2str__", "float2str", "float2str_"},
592 {"hex2bit__", "hex2bit", "hex2bit_"},
593 {"hex2int__", "hex2int", "hex2int_"},
594 {"hex2oct__", "hex2oct", "hex2oct_"},
595 {"hex2str__", "hex2str", "hex2str_"},
596 {"int2bit__", "int2bit", "int2bit_"},
597 {"int2char__", "int2char", "int2char_"},
598 {"int2float__", "int2float", "int2float_"},
599 {"int2hex__", "int2hex", "int2hex_"},
600 {"int2oct__", "int2oct", "int2oct_"},
601 {"int2str__", "int2str", "int2str_"},
602 {"int2unichar__", "int2unichar", "int2unichar_"},
603 {"ischosen__", "ischosen", "ischosen_"},
604 {"ispresent__", "ispresent", "ispresent_"},
605 {"isvalue__", "isvalue", "isvalue_"},
606 {"lengthof__", "lengthof", "lengthof_"},
607 {"log__", "log", "log_"},
608 {"log2str__", "log2str", "log2str_"},
609 {"match__", "match", "match_"},
610 {"mod__", "mod", "mod_"},
611 {"oct2bit__", "oct2bit", "oct2bit_"},
612 {"oct2char__", "oct2char", "oct2char_"},
613 {"oct2hex__", "oct2hex", "oct2hex_"},
614 {"oct2int__", "oct2int", "oct2int_"},
615 {"oct2str__", "oct2str", "oct2str_"},
616 {"regexp__", "regexp", "regexp_"},
617 {"replace__", "replace", "replace_"},
618 {"rem__", "rem", "rem_"},
619 {"rnd__", "rnd", "rnd_"},
620 {"self__", "self", "self_"},
621 {"str2bit__", "str2bit", "str2bit_"},
622 {"str2float__", "str2float", "str2float_"},
623 {"str2hex__", "str2hex", "str2hex_"},
624 {"str2int__", "str2int", "str2int_"},
625 {"str2oct__", "str2oct", "str2oct_"},
626 {"substr__", "substr", "substr_"},
627 {"unichar2int__", "unichar2int", "unichar2int_"},
628 {"unichar2char__", "unichar2char", "unichar2char_"},
629 {"valueof__", "valueof", "valueof_"},
630 {"verdicttype__", "verdicttype", "verdicttype_"},
631 {"ttcn2string__", "ttcn2string", "ttcn2string_"},
632 {"string2ttcn__", "string2ttcn", "string2ttcn_"},
633 {"unichar2oct__", "unichar2oct", "unichar2oct_"},
634 {"oct2unichar__", "oct2unichar", "oct2unichar_"},
635 {"remove__bom__", "remove_bom", "remove_bom_"},
636 {"encode__base64__", "encode_base64", "encode_base64_"},
637 {"decode__base64__", "decode_base64", "decode_base64_"},
638 {"get__stringencoding__", "get_stringencoding", "get_stringencoding_"},
639 /* reserved names of base library - keywords in ASN.1 */
640 {"FALSE_", 0, "FALSE"},
641 {"OPTIONAL_", 0, "OPTIONAL"},
642 {"TRUE_", 0, "TRUE"},
643 /* reserved names of base library - not keywords */
644 {"CHAR_", "CHAR", "CHAR"},
645 {"ERROR_", "ERROR", "ERROR"},
646 {"FAIL_", "FAIL", "FAIL"},
647 {"INCONC_", "INCONC", "INCONC"},
648 {"NONE_", "NONE", "NONE"},
649 {"PASS_", "PASS", "PASS"},
650 {"PORT_", "PORT", "PORT"},
651 {"TIMER_", "TIMER", "TIMER"},
652 {"main_", "main", "main"},
653 {"stderr_", "stderr", "stderr"}, // temporary hack
654 {"stdin_", "stdin", "stdin"}, // temporary hack
655 {"stdout_", "stdout", "stdout"}, // temporary hack
656 {"TTCN3_", "TTCN3", "TTCN3"},
657 /* built-in types. this is the ASN/TTCN -> C++ name mapping */
658 {"ADDRESS", 0, "address"},
659 {"ASN_NULL", "NULL", 0},
660 {"BITSTRING", "BIT STRING", "bitstring"},
661 {"BOOLEAN", "BOOLEAN", "boolean"},
662 {"BMPString", "BMPString", 0},
663 {"CHARSTRING", 0, "charstring"},
664 {"CHARACTER_STRING", "CHARACTER STRING", 0},
665 {"COMPONENT", 0, "component"},
666 {"DEFAULT", 0, "default"},
667 {"EMBEDDED_PDV", "EMBEDDED PDV", 0},
668 {"EXTERNAL", "EXTERNAL", 0},
669 {"FLOAT", "REAL", "float"},
670 {"GraphicString", "GraphicString", 0},
671 {"HEXSTRING", 0, "hexstring"},
672 {"IA5String", "IA5String", 0},
673 {"INTEGER", "INTEGER", "integer"},
674 {"ISO646String", "ISO646String", 0},
675 {"NumericString", "NumericString", 0},
676 {"OBJID", "OBJECT IDENTIFIER", "objid"},
677 {"OCTETSTRING", "OCTET STRING", "octetstring"},
678 {"ObjectDescriptor", "ObjectDescriptor", 0},
679 {"PrintableString", "PrintableString", 0},
680 {"T61String", "T61String", 0},
681 {"TeletexString", "TeletexString", 0},
682 {"UTF8String", "UTF8String", 0},
683 {"UniversalString", "UniversalString", 0},
684 {"UNIVERSAL_CHARSTRING", 0, "universal charstring"},
685 {"VERDICTTYPE", 0, "verdicttype"},
686 {"VideotexString", "VideotexString", 0},
687 {"VisibleString", "VisibleString", 0},
688 /* reserved names of built-in types - valid ASN.1/TTCN names */
689 {"ADDRESS_", "ADDRESS", "ADDRESS"},
690 {"BITSTRING_", "BITSTRING", "BITSTRING"},
691 {"BOOLEAN_", 0, "BOOLEAN"},
692 {"BMPString_", 0, "BMPString"},
693 {"CHARSTRING_", "CHARSTRING", "CHARSTRING"},
694 {"COMPONENT_", "COMPONENT", "COMPONENT"},
695 {"DEFAULT_", 0, "DEFAULT"},
696 {"EXTERNAL_", 0, "EXTERNAL"},
697 {"FLOAT_", "FLOAT", "FLOAT"},
698 {"GraphicString_", 0, "GraphicString"},
699 {"HEXSTRING_", "HEXSTRING", "HEXSTRING"},
700 {"IA5String_", 0, "IA5String"},
701 {"INTEGER_", 0, "INTEGER"},
702 {"ISO646String_", 0, "ISO646String"},
703 {"NumericString_", 0, "NumericString"},
704 {"OBJID_", "OBJID", "OBJID"},
705 {"OCTETSTRING_", "OCTETSTRING", "OCTETSTRING"},
706 {"ObjectDescriptor_", 0, "ObjectDescriptor"},
707 {"PrintableString_", 0, "PrintableString"},
708 {"T61String_", 0, "T61String"},
709 {"TeletexString_", 0, "TeletexString"},
710 {"UTF8String_", 0, "UTF8String"},
711 {"UniversalString_", 0, "UniversalString"},
712 {"VERDICTTYPE_", "VERDICTTYPE", "VERDICTTYPE"},
713 {"VideotexString_", 0, "VideotexString"},
714 {"VisibleString_", 0, "VisibleString"},
715 /* keywords in TTCN-3, not reserved words in C++, postfixed in TTCN */
716 {"action__", "action", "action_"},
717 {"activate__", "activate", "activate_"},
718 {"address__", "address", "address_"},
719 {"alive__", "alive", "alive_"},
720 {"all__", "all", "all_"},
721 {"alt__", "alt", "alt_"},
722 {"altstep__", "altstep", "altstep_"},
723 {"and4b__", "and4b", "and4b_"},
724 {"any__", "any", "any_"},
725 {"anytype__", "anytype", "anytype_"},
726 {"apply__", "apply", "apply_"},
727 {"bitstring__", "bitstring", "bitstring_"},
728 {"call__", "call", "call_"},
729 {"charstring__", "charstring", "charstring_"},
730 {"check__", "check", "check_"},
731 {"clear__", "clear", "clear_"},
732 {"complement__", "complement", "complement_"},
733 {"connect__", "connect", "connect_"},
734 {"control__", "control", "control_"},
735 {"create__", "create", "create_"},
736 {"deactivate__", "deactivate", "deactivate_"},
737 {"derefers__", "derefers", "derefers_"},
738 {"disconnect__", "disconnect", "disconnect_"},
739 {"display__", "display", "display_"},
740 {"done__", "done", "done_"},
741 {"encode__", "encode", "encode_"},
742 {"enumerated__", "enumerated", "enumerated_"},
743 {"error__", "error", "error_"},
744 {"except__", "except", "except_"},
745 {"exception__", "exception", "exception_"},
746 {"execute__", "execute", "execute_"},
747 {"extends__", "extends", "extends_"},
748 {"extension__", "extension", "extension_"},
749 {"external__", "external", "external_"},
750 {"fail__", "fail", "fail_"},
751 {"from__", "from", "from_"},
752 {"function__", "function", "function_"},
753 {"getcall__", "getcall", "getcall_"},
754 {"getreply__", "getreply", "getreply_"},
755 {"getverdict__", "getverdict", "getverdict_"},
756 {"group__", "group", "group_"},
757 {"halt__", "halt", "halt_"},
758 {"hexstring__", "hexstring", "hexstring_"},
759 {"ifpresent__", "ifpresent", "ifpresent_"},
760 {"import__", "import", "import_"},
761 {"in__", "in", "in_"},
762 {"inconc__", "inconc", "inconc_"},
763 {"infinity__", "infinity", "infinity_"},
764 {"inout__", "inout", "inout_"},
765 {"integer__", "integer", "integer_"},
766 {"interleave__", "interleave", "interleave_"},
767 {"kill__", "kill", "kill_"},
768 {"killed__", "killed", "killed_"},
769 {"label__", "label", "label_"},
770 {"language__", "language", "language_"},
771 {"length__", "length", "length_"},
772 {"map__", "map", "map_"},
773 {"message__", "message", "message_"},
774 {"mixed__", "mixed", "mixed_"},
775 {"modifies__", "modifies", "modifies_"},
776 {"module__", "module", "module_"},
777 {"modulepar__", "modulepar", "modulepar_"},
778 {"mtc__", "mtc", "mtc_"},
779 {"noblock__", "noblock", "noblock_"},
780 {"none__", "none", "none_"},
781 {"not4b__", "not4b", "not4b_"},
782 {"nowait__", "nowait", "nowait_"},
783 {"null__", "null", "null_"},
784 {"objid__", "objid", "objid_"},
785 {"octetstring__", "octetstring", "octetstring_"},
786 {"of__", "of", "of_"},
787 {"omit__", "omit", "omit_"},
788 {"on__", "on", "on_"},
789 {"optional__", "optional", "optional_"},
790 {"or4b__", "or4b", "or4b_"},
791 {"out__", "out", "out_"},
792 {"override__", "override", "override_"},
793 {"param__", "param", "param_"},
794 {"pass__", "pass", "pass_"},
795 {"pattern__", "pattern", "pattern_"},
796 {"permutation__", "permutation", "permutation_"},
797 {"port__", "port", "port_"},
798 {"procedure__", "procedure", "procedure_"},
799 {"raise__", "raise", "raise_"},
800 {"read__", "read", "read_"},
801 {"receive__", "receive", "receive_"},
802 {"record__", "record", "record_"},
803 {"recursive__", "recursive", "recursive_"},
804 {"refers__", "refers", "refers_"},
805 {"repeat__", "repeat", "repeat_"},
806 {"reply__", "reply", "reply_"},
807 {"running__", "running", "running_"},
808 {"runs__", "runs", "runs_"},
809 {"select__", "select", "select_"},
810 {"send__", "send", "send_"},
811 {"sender__", "sender", "sender_"},
812 {"set__", "set", "set_"},
813 {"setverdict__", "setverdict", "setverdict_"},
814 {"signature__", "signature", "signature_"},
815 {"start__", "start", "start_"},
816 {"stop__", "stop", "stop_"},
817 {"subset__", "subset", "subset_"},
818 {"superset__", "superset", "superset_"},
819 {"system__", "system", "system_"},
820 {"testcase__", "testcase", "testcase_"},
821 {"timeout__", "timeout", "timeout_"},
822 {"timer__", "timer", "timer_"},
823 {"to__", "to", "to_"},
824 {"trigger__", "trigger", "trigger_"},
825 {"type__", "type", "type_"},
826 {"universal__", "universal", "universal_"},
827 {"unmap__", "unmap", "unmap_"},
828 {"value__", "value", "value_"},
829 {"present__", "present", "present_"},
830 {"var__", "var", "var_"},
831 {"variant__", "variant", "variant_"},
832 {"with__", "with", "with_"},
833 {"xor4b__", "xor4b", "xor4b_"},
834 /* other names that need to be mapped in a non-uniform manner */
835 /* major and minor are macros on some platforms; avoid generating
836 * a potentially troublesome C++ identifier */
837 {"major_", "major", "major"},
838 {"minor_", "minor", "minor"},
839 /* internal / error */
840 {"<error>", "<error>", "<error>"},
841 {"TTCN_internal_", "<internal>", "<internal>"},
842 /* the last must be all zeros */
846 internal_data_t::internal_data_t()
847 : identifier_counter(0), string_invalid("<invalid>"), id_map_name(),
848 id_map_asn(), id_map_ttcn()
852 internal_data_t::~internal_data_t()
854 for(size_t i
=0; i
<id_map_name
.size(); i
++)
855 Identifier::id_data_t::delete_this(id_map_name
.get_nth_elem(i
));
857 for(size_t i
=0; i
<id_map_asn
.size(); i
++)
858 Identifier::id_data_t::delete_this(id_map_asn
.get_nth_elem(i
));
860 for(size_t i
=0; i
<id_map_ttcn
.size(); i
++)
861 Identifier::id_data_t::delete_this(id_map_ttcn
.get_nth_elem(i
));
865 void internal_data_t::add_keyword(const char* const keyword
[3])
867 Identifier::id_data_t
*id_data
868 =new Identifier::id_data_t(string(keyword
[0]));
870 // Pointers to already added (conflicting) keyword
871 const Identifier::id_data_t
*id_data_name
=0;
872 const Identifier::id_data_t
*id_data_asn
=0;
873 const Identifier::id_data_t
*id_data_ttcn
=0;
874 if(id_map_name
.has_key(id_data
->name
)) {
876 id_data_name
=id_map_name
[id_data
->name
];
879 id_map_name
.add(id_data
->name
, id_data
);
880 id_data
->ref_count
++;
884 id_data
->asnname
=string_invalid
;
887 // copy the string if possible to avoid memory allocation
888 if (id_data
->name
== keyword
[1]) id_data
->asnname
= id_data
->name
;
889 else id_data
->asnname
= keyword
[1];
890 if(id_map_asn
.has_key(id_data
->asnname
)) {
892 id_data_asn
=id_map_asn
[id_data
->asnname
];
895 id_map_asn
.add(id_data
->asnname
, id_data
);
896 id_data
->ref_count
++;
901 id_data
->ttcnname
=string_invalid
;
904 // copy the string if possible to avoid memory allocation
905 if (id_data
->name
== keyword
[2]) id_data
->ttcnname
= id_data
->name
;
906 else if (id_data
->asnname
== keyword
[2])
907 id_data
->ttcnname
= id_data
->asnname
;
908 else id_data
->ttcnname
= keyword
[2];
909 if(id_map_ttcn
.has_key(id_data
->ttcnname
)) {
911 id_data_ttcn
=id_map_ttcn
[id_data
->ttcnname
];
914 id_map_ttcn
.add(id_data
->ttcnname
, id_data
);
915 id_data
->ref_count
++;
922 ("This pre-defined identifier: %s",
923 id_data
->get_names().c_str());
925 ("conflicts with previous:");
929 id_data_name
->get_names().c_str());
933 id_data_asn
->get_names().c_str());
937 id_data_ttcn
->get_names().c_str());
939 Identifier::id_data_t::delete_this(id_data
);
942 void internal_data_t::add_keywords()
946 Error_Context
cntx(&loc
, "While adding keywords");
947 for(size_t i
=0; keywords
[i
][0]; i
++)
948 add_keyword(keywords
[i
]);
950 /* Perhaps it were good to read a file which contains
951 user-defined mappings :) */
954 internal_data_t
*internal_data_t::Instance()
957 instance
=new internal_data_t();
958 instance
->add_keywords();
963 void internal_data_t::increase_counter()
965 identifier_counter
++;
968 void internal_data_t::decrease_counter()
970 identifier_counter
--;
971 if(identifier_counter
==0) {
974 } // if last Identifier instance
977 // =================================
979 // =================================
981 bool Identifier::is_reserved_word(const string
& p_name
, id_t p_id_t
)
984 FATAL_ERROR("Identifier::is_reserved_word(): empty name");
985 internal_data_t
*d
= internal_data_t::Instance();
988 if (d
->id_map_name
.has_key(p_name
)) {
989 id_data_t
*id_data_p
= d
->id_map_name
[p_name
];
990 if (id_data_p
->asnname
== d
->string_invalid
&&
991 id_data_p
->ttcnname
== d
->string_invalid
) return true;
995 if (p_name
[0] == '&' || d
->id_map_asn
.has_key(p_name
)) return false;
998 id_data_t::asn_2_name(name
, p_name
);
999 if (d
->id_map_name
.has_key(name
)) {
1000 id_data_t
*id_data_p
= d
->id_map_name
[name
];
1001 if (id_data_p
->asnname
.empty()) {
1002 id_data_p
->asnname
= p_name
;
1003 d
->id_map_asn
.add(p_name
, id_data_p
);
1004 id_data_p
->ref_count
++;
1006 } else if (id_data_p
->asnname
== p_name
) return false;
1008 } else return false;
1011 if (d
->id_map_ttcn
.has_key(p_name
)) return false;
1014 id_data_t::ttcn_2_name(name
, p_name
);
1015 if (d
->id_map_name
.has_key(name
)) {
1016 id_data_t
*id_data_p
= d
->id_map_name
[name
];
1017 if (id_data_p
->ttcnname
.empty()) {
1018 id_data_p
->ttcnname
= p_name
;
1019 d
->id_map_ttcn
.add(p_name
, id_data_p
);
1020 id_data_p
->ref_count
++;
1022 } else if (id_data_p
->ttcnname
== p_name
) return false;
1024 } else return false;
1027 FATAL_ERROR("Identifier::is_reserved_word(): invalid language");
1032 string
Identifier::asn_2_name(const string
& p_name
)
1034 internal_data_t
*d
= internal_data_t::Instance();
1035 if (d
->id_map_asn
.has_key(p_name
)) {
1036 id_data_t
*id_data_p
= d
->id_map_asn
[p_name
];
1037 if (id_data_p
->name
.empty()) {
1038 id_data_t::asn_2_name(id_data_p
->name
, p_name
);
1039 d
->id_map_name
.add(id_data_p
->name
, id_data_p
);
1040 id_data_p
->ref_count
++;
1042 return id_data_p
->name
;
1045 id_data_t::asn_2_name(name
, p_name
);
1046 if (d
->id_map_name
.has_key(name
)) {
1047 id_data_t
*id_data_p
= d
->id_map_name
[name
];
1048 if (id_data_p
->asnname
.empty()) {
1049 id_data_p
->asnname
= p_name
;
1050 d
->id_map_asn
.add(p_name
, id_data_p
);
1051 id_data_p
->ref_count
++;
1058 string
Identifier::name_2_asn(const string
& p_name
)
1060 internal_data_t
*d
= internal_data_t::Instance();
1061 if (d
->id_map_name
.has_key(p_name
)) {
1062 id_data_t
*id_data_p
= d
->id_map_name
[p_name
];
1063 if (id_data_p
->asnname
.empty()) {
1064 id_data_t::name_2_asn(id_data_p
->asnname
, p_name
);
1065 d
->id_map_asn
.add(id_data_p
->asnname
, id_data_p
);
1066 id_data_p
->ref_count
++;
1068 return id_data_p
->asnname
;
1071 id_data_t::name_2_asn(asnname
, p_name
);
1072 if (d
->id_map_asn
.has_key(asnname
)) {
1073 id_data_t
*id_data_p
= d
->id_map_asn
[asnname
];
1074 if (id_data_p
->name
.empty()) {
1075 id_data_p
->name
= p_name
;
1076 d
->id_map_name
.add(p_name
, id_data_p
);
1077 id_data_p
->ref_count
++;
1084 string
Identifier::ttcn_2_name(const string
& p_name
)
1086 internal_data_t
*d
= internal_data_t::Instance();
1087 if (d
->id_map_ttcn
.has_key(p_name
)) {
1088 id_data_t
*id_data_p
= d
->id_map_ttcn
[p_name
];
1089 if (id_data_p
->name
.empty()) {
1090 id_data_t::ttcn_2_name(id_data_p
->name
, p_name
);
1091 d
->id_map_name
.add(id_data_p
->name
, id_data_p
);
1092 id_data_p
->ref_count
++;
1094 return id_data_p
->name
;
1097 id_data_t::ttcn_2_name(name
, p_name
);
1098 if (d
->id_map_name
.has_key(name
)) {
1099 id_data_t
*id_data_p
= d
->id_map_name
[name
];
1100 if (id_data_p
->ttcnname
.empty()) {
1101 id_data_p
->ttcnname
= p_name
;
1102 d
->id_map_ttcn
.add(p_name
, id_data_p
);
1103 id_data_p
->ref_count
++;
1110 string
Identifier::name_2_ttcn(const string
& p_name
)
1112 internal_data_t
*d
= internal_data_t::Instance();
1113 if (d
->id_map_name
.has_key(p_name
)) {
1114 id_data_t
*id_data_p
= d
->id_map_name
[p_name
];
1115 if (id_data_p
->ttcnname
.empty()) {
1116 id_data_t::name_2_ttcn(id_data_p
->ttcnname
, p_name
);
1117 d
->id_map_ttcn
.add(id_data_p
->ttcnname
, id_data_p
);
1118 id_data_p
->ref_count
++;
1120 return id_data_p
->ttcnname
;
1123 id_data_t::name_2_ttcn(ttcnname
, p_name
);
1124 if (d
->id_map_ttcn
.has_key(ttcnname
)) {
1125 id_data_t
*id_data_p
= d
->id_map_ttcn
[ttcnname
];
1126 if (id_data_p
->name
.empty()) {
1127 id_data_p
->name
= p_name
;
1128 d
->id_map_name
.add(p_name
, id_data_p
);
1129 id_data_p
->ref_count
++;
1136 Identifier::Identifier(id_t p_id_t
, const string
& p_name
, bool dontreg
)
1137 : id_data(0), origin(p_id_t
)
1139 if (p_name
.empty()) FATAL_ERROR("Identifier::Identifier(): empty name");
1140 internal_data_t
*d
=internal_data_t::Instance();
1141 d
->increase_counter();
1144 if(d
->id_map_name
.has_key(p_name
)) {
1145 id_data
=d
->id_map_name
[p_name
];
1146 id_data
->ref_count
++;
1149 id_data
=new id_data_t(p_name
);
1151 d
->id_map_name
.add(p_name
, id_data
);
1152 id_data
->ref_count
++;
1157 if(d
->id_map_asn
.has_key(p_name
)) {
1158 id_data
=d
->id_map_asn
[p_name
];
1159 id_data
->ref_count
++;
1161 else if(p_name
[0]=='&') { // special amp-identifiers (&)
1162 string p_name2
=p_name
.substr(1);
1164 if(d
->id_map_asn
.has_key(p_name2
))
1165 name2
=d
->id_map_asn
[p_name2
]->get_name();
1167 id_data_t::asn_2_name(name2
, p_name2
);
1168 id_data
=new id_data_t(name2
);
1169 id_data
->asnname
=p_name
;
1170 id_data
->ttcnname
=d
->string_invalid
;
1172 d
->id_map_asn
.add(p_name
, id_data
);
1173 id_data
->ref_count
++;
1175 /* this id_data should NOT be added to id_map_name. */
1179 id_data_t::asn_2_name(name
, p_name
);
1180 if(!dontreg
&& d
->id_map_name
.has_key(name
)) {
1181 id_data
=d
->id_map_name
[name
];
1182 id_data
->ref_count
++;
1183 if(id_data
->asnname
.empty()) {
1184 id_data
->asnname
=p_name
;
1186 d
->id_map_asn
.add(p_name
, id_data
);
1187 id_data
->ref_count
++;
1190 else if(id_data
->asnname
!=p_name
) {
1193 ("The ASN identifier `%s' clashes with this id: %s",
1194 p_name
.c_str(), id_data
->get_names().c_str());
1198 id_data
=new id_data_t(name
);
1199 id_data
->asnname
=p_name
;
1201 d
->id_map_name
.add(name
, id_data
);
1202 d
->id_map_asn
.add(p_name
, id_data
);
1203 id_data
->ref_count
+=2;
1209 if(d
->id_map_ttcn
.has_key(p_name
)) {
1210 id_data
=d
->id_map_ttcn
[p_name
];
1211 id_data
->ref_count
++;
1215 id_data_t::ttcn_2_name(name
, p_name
);
1216 if(!dontreg
&& d
->id_map_name
.has_key(name
)) {
1217 id_data
=d
->id_map_name
[name
];
1218 id_data
->ref_count
++;
1219 if(id_data
->ttcnname
.empty()) {
1220 id_data
->ttcnname
=p_name
;
1222 d
->id_map_ttcn
.add(p_name
, id_data
);
1223 id_data
->ref_count
++;
1226 else if(id_data
->ttcnname
!=p_name
) {
1229 ("The TTCN identifier `%s' clashes with this id: %s",
1230 p_name
.c_str(), id_data
->get_names().c_str());
1234 id_data
=new id_data_t(name
);
1235 id_data
->ttcnname
=p_name
;
1237 d
->id_map_name
.add(name
, id_data
);
1238 d
->id_map_ttcn
.add(p_name
, id_data
);
1239 id_data
->ref_count
+=2;
1245 FATAL_ERROR("Identifier::Identifier()");
1249 Identifier::Identifier(const Identifier
& p
)
1250 : id_data(p
.id_data
), origin(p
.origin
)
1252 internal_data_t::Instance()->increase_counter();
1253 id_data
->ref_count
++;
1256 Identifier::~Identifier()
1258 id_data_t::delete_this(id_data
);
1259 /* I don't want to free the id_data structs here. They will be
1260 deleted in decrease_counter() when the maps are destructed. */
1261 internal_data_t::Instance()->decrease_counter();
1264 Identifier
& Identifier::operator=(const Identifier
& p
)
1267 id_data_t::delete_this(id_data
);
1269 id_data
->ref_count
++;
1275 bool Identifier::operator==(const Identifier
& p
) const
1277 return id_data
->name
==p
.id_data
->name
;
1280 bool Identifier::operator<(const Identifier
& p
) const
1282 return id_data
->name
<p
.id_data
->name
;
1285 const string
& Identifier::get_name() const
1287 return id_data
->get_name();
1290 const string
& Identifier::get_dispname() const
1294 return id_data
->get_name();
1296 return id_data
->get_asnname();
1298 return id_data
->get_ttcnname();
1300 FATAL_ERROR("Identifier::get_dispname()");
1301 return id_data
->get_name();
1305 const string
& Identifier::get_asnname() const
1307 return id_data
->get_asnname();
1310 const string
& Identifier::get_ttcnname() const
1312 return id_data
->get_ttcnname();
1315 bool Identifier::get_has_valid(id_t p_id_t
) const
1317 return id_data
->get_has_valid(p_id_t
);
1320 string
Identifier::get_names() const
1322 return id_data
->get_names();
1325 bool Identifier::isvalid_asn_modref() const
1327 return id_data
->isvalid_asn_modref();
1330 bool Identifier::isvalid_asn_typeref() const
1332 return id_data
->isvalid_asn_typeref();
1335 bool Identifier::isvalid_asn_valref() const
1337 return id_data
->isvalid_asn_valref();
1340 bool Identifier::isvalid_asn_valsetref() const
1342 return id_data
->isvalid_asn_valsetref();
1345 bool Identifier::isvalid_asn_objclassref() const
1347 return id_data
->isvalid_asn_objclassref();
1350 bool Identifier::isvalid_asn_objref() const
1352 return id_data
->isvalid_asn_objref();
1355 bool Identifier::isvalid_asn_objsetref() const
1357 return id_data
->isvalid_asn_objsetref();
1360 bool Identifier::isvalid_asn_typefieldref() const
1362 return id_data
->isvalid_asn_typefieldref();
1365 bool Identifier::isvalid_asn_valfieldref() const
1367 return id_data
->isvalid_asn_valfieldref();
1370 bool Identifier::isvalid_asn_valsetfieldref() const
1372 return id_data
->isvalid_asn_valsetfieldref();
1375 bool Identifier::isvalid_asn_objfieldref() const
1377 return id_data
->isvalid_asn_objfieldref();
1380 bool Identifier::isvalid_asn_objsetfieldref() const
1382 return id_data
->isvalid_asn_objsetfieldref();
1385 bool Identifier::isvalid_asn_word() const
1387 return id_data
->isvalid_asn_word();
1390 void Identifier::dump(unsigned level
) const
1392 DEBUG(level
, "Identifier: %s", id_data
->get_names().c_str());
1395 const Identifier
underscore_zero(Identifier::ID_TTCN
, string("_0"));
1397 } // namespace Common
This page took 0.133081 seconds and 5 git commands to generate.