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
17 * Szabo, Janos Zoltan – initial implementation
19 ******************************************************************************/
20 #include "../common/dbgnew.hh"
21 #include "Identifier.hh"
24 #include "CompilerError.hh"
28 // =================================
29 // ===== Identifier::id_data_t
30 // =================================
32 struct Identifier::id_data_t
{
34 string name
, asnname
, ttcnname
;
35 /** ASN kind of the identifier. */
37 ASN_UNDEF
, /**< undefined */
38 ASN_LOWER
, /**< LOWERIDENTIFIER [a-z](-?[A-Za-z0-9]+)* */
39 ASN_UPPER
, /**< UPPERIDENTIFIER [A-Z](-?[A-Za-z0-9]+)* */
40 ASN_ALLUPPER
, /**< ALLUPPERIDENTIFIER [A-Z](-?[A-Z0-9]+)* */
41 ASN_WORD
, /**< WORD [A-Z](-?[A-Z]+)* */
42 ASN_ampUPPER
, /**< ampUPPERIDENTIFIER \\\&{UPPERIDENTIFIER} */
43 ASN_ampLOWER
/**< ampLOWERIDENTIFIER \\\&{LOWERIDENTIFIER} */
45 static void asn_2_name(string
& p_to
, const string
& p_from
);
46 static void name_2_asn(string
& p_to
, const string
& p_from
);
47 static void ttcn_2_name(string
& p_to
, const string
& p_from
);
48 static void name_2_ttcn(string
& p_to
, const string
& p_from
);
49 id_data_t(const string
& p_name
)
50 : ref_count(1), name(p_name
), asnname(), ttcnname(), asn_kind(ASN_UNDEF
){}
51 static void delete_this(id_data_t
*p_id_data_t
);
52 /** Gets the internal (and C++) name. */
53 const string
& get_name() const {return name
;}
54 /** Gets the ASN display name. */
55 const string
& get_asnname();
56 /** Gets the TTCN display name. */
57 const string
& get_ttcnname();
58 bool get_has_valid(id_t p_id_t
);
59 string
get_names() const;
60 /** True if it is a valid ASN modulereference. */
61 bool isvalid_asn_modref();
62 /** True if it is a valid ASN typereference. */
63 bool isvalid_asn_typeref();
64 /** True if it is a valid ASN valuereference. */
65 bool isvalid_asn_valref();
66 /** True if it is a valid ASN valuesetreference. */
67 bool isvalid_asn_valsetref();
68 /** True if it is a valid ASN objectclassreference. */
69 bool isvalid_asn_objclassref();
70 /** True if it is a valid ASN objectreference. */
71 bool isvalid_asn_objref();
72 /** True if it is a valid ASN objectsetreference. */
73 bool isvalid_asn_objsetref();
74 /** True if it is a valid ASN typefieldreference. */
75 bool isvalid_asn_typefieldref();
76 /** True if it is a valid ASN valuefieldreference. */
77 bool isvalid_asn_valfieldref();
78 /** True if it is a valid ASN valuesetfieldreference. */
79 bool isvalid_asn_valsetfieldref();
80 /** True if it is a valid ASN objectfieldreference. */
81 bool isvalid_asn_objfieldref();
82 /** True if it is a valid ASN objectsetfieldreference. */
83 bool isvalid_asn_objsetfieldref();
84 /** True if it is a valid ASN "word". */
85 bool isvalid_asn_word();
88 void decide_asn_kind();
91 // =================================
92 // ===== internal_data_t
93 // =================================
95 class internal_data_t
{
97 static internal_data_t
*instance
;
98 static const char* const keywords
[][3];
99 size_t identifier_counter
;
101 const string string_invalid
;
102 /** Container for identifiers, indexed by ID_NAME. */
103 map
<string
, Identifier::id_data_t
> id_map_name
;
104 /** Container for identifiers, indexed by ID_ASN. */
105 map
<string
, Identifier::id_data_t
> id_map_asn
;
106 /** Container for identifiers, indexed by ID_TTCN. */
107 map
<string
, Identifier::id_data_t
> id_map_ttcn
;
110 internal_data_t(const internal_data_t
&);
112 void add_keyword(const char* const keyword
[3]);
115 static internal_data_t
*Instance();
116 /** Increases the instance counter. Initializes the keywords if
117 * this is the first instance. Must be called in every Identifier
119 void increase_counter();
120 /** Decreases the instance counter. Finalizes the keywords if this
121 * is the last instance. Must be called in Identifier
123 void decrease_counter();
126 // ======================================================================
127 // ======================================================================
129 // =================================
130 // ===== Identifier::id_data_t
131 // =================================
133 void Identifier::id_data_t::asn_2_name(string
& p_to
, const string
& p_from
)
136 /* "@aaa" -> "_root_aaa" */
137 if (p_to
.size() > 0 && p_to
[0] == '@') p_to
.replace(0, 1, "_root_");
138 /* "aa.<xxxx>.bb" -> "aa.bb" */
140 while ((pos
= p_to
.find(".<", pos
)) < p_to
.size()) {
141 size_t pos2
= p_to
.find(">.", pos
);
142 if (pos2
< p_to
.size()) p_to
.replace(pos
, pos2
+ 1 - pos
, "");
147 while ((pos
= p_to
.find('-', pos
)) < p_to
.size()) {
148 p_to
.replace(pos
, 1, "__");
153 while ((pos
= p_to
.find('.', pos
)) < p_to
.size()) {
159 while ((pos
= p_to
.find('&', pos
)) < p_to
.size())
160 p_to
.replace(pos
, 1, "");
163 void Identifier::id_data_t::name_2_asn(string
& p_to
, const string
& p_from
)
166 /* remove leading '_'s */
168 while (pos
< p_to
.size() && p_to
[pos
] == '_') pos
++;
169 if (pos
> 0) p_to
.replace(0, pos
, "");
170 /* remove trailing '_'s */
172 while (pos
> 0 && p_to
[pos
- 1] == '_') pos
--;
173 if (pos
< p_to
.size()) p_to
.resize(pos
);
176 while ((pos
= p_to
.find("__", pos
)) < p_to
.size()) {
177 p_to
.replace(pos
, 2, "-");
182 while ((pos
= p_to
.find('_', pos
)) < p_to
.size()) {
188 void Identifier::id_data_t::ttcn_2_name(string
& p_to
, const string
& p_from
)
193 while ((pos
= p_to
.find('_', pos
)) < p_to
.size()) {
194 p_to
.replace(pos
, 1, "__");
199 void Identifier::id_data_t::name_2_ttcn(string
& p_to
, const string
& p_from
)
202 /* remove leading '_'s */
204 while (pos
< p_to
.size() && p_to
[pos
] == '_') pos
++;
205 if (pos
> 0) p_to
.replace(0, pos
, "");
206 /* remove trailing '_'s */
208 while (pos
> 0 && p_to
[pos
- 1] == '_') pos
--;
209 if (pos
< p_to
.size()) p_to
.resize(pos
);
212 while ((pos
= p_to
.find("__", pos
)) < p_to
.size()) {
213 p_to
.replace(pos
, 1, "");
218 const string
& Identifier::id_data_t::get_asnname()
220 if (asnname
.empty()) name_2_asn(asnname
, name
);
224 const string
& Identifier::id_data_t::get_ttcnname()
226 if (ttcnname
.empty()) name_2_ttcn(ttcnname
, name
);
230 bool Identifier::id_data_t::get_has_valid(id_t p_id_t
)
232 const string
& inval
=internal_data_t::Instance()->string_invalid
;
235 return get_name()!=inval
;
237 return get_asnname()!=inval
;
239 return get_ttcnname()!=inval
;
241 FATAL_ERROR("Identifier::id_data_t::get_has_valid()");
246 void Identifier::id_data_t::delete_this(id_data_t
*p_id_data_t
)
248 p_id_data_t
->ref_count
--;
249 if(p_id_data_t
->ref_count
==0)
253 string
Identifier::id_data_t::get_names() const
255 const string
& inval
=internal_data_t::Instance()->string_invalid
;
256 string s
="(C++: `"+name
+"'";
257 if(!asnname
.empty() && asnname
!=inval
)
258 s
+=", ASN: `"+asnname
+"'";
259 if(!ttcnname
.empty() && ttcnname
!=inval
)
260 s
+=", TTCN: `"+ttcnname
+"'";
265 void Identifier::id_data_t::decide_asn_kind()
267 if(asn_kind
!=ASN_UNDEF
) return;
269 if(asnname
==internal_data_t::Instance()->string_invalid
) return;
270 if(asnname
[0]=='&') {
271 if(asnname
.size()>=2) {
272 if(isupper(asnname
[1]))
273 asn_kind
=ASN_ampUPPER
;
274 else if(islower(asnname
[1]))
275 asn_kind
=ASN_ampLOWER
;
278 else if(islower(asnname
[0])) {
281 else if(isupper(asnname
[0])) {
283 if(asnname
.find_if(0, asnname
.size(), islower
)==asnname
.size()) {
284 asn_kind
=ASN_ALLUPPER
;
285 if(asnname
.find_if(0, asnname
.size(), isdigit
)==asnname
.size()) {
292 bool Identifier::id_data_t::isvalid_asn_modref()
294 return isvalid_asn_typeref();
297 bool Identifier::id_data_t::isvalid_asn_typeref()
300 return (asn_kind
==ASN_UPPER
301 || asn_kind
==ASN_ALLUPPER
302 || asn_kind
==ASN_WORD
);
305 bool Identifier::id_data_t::isvalid_asn_valref()
308 return (asn_kind
==ASN_LOWER
);
311 bool Identifier::id_data_t::isvalid_asn_valsetref()
313 return isvalid_asn_typeref();
316 bool Identifier::id_data_t::isvalid_asn_objclassref()
319 return (asn_kind
==ASN_ALLUPPER
320 || asn_kind
==ASN_WORD
);
323 bool Identifier::id_data_t::isvalid_asn_objref()
326 return (asn_kind
==ASN_LOWER
);
329 bool Identifier::id_data_t::isvalid_asn_objsetref()
331 return isvalid_asn_typeref();
334 bool Identifier::id_data_t::isvalid_asn_typefieldref()
337 return (asn_kind
==ASN_ampUPPER
);
340 bool Identifier::id_data_t::isvalid_asn_valfieldref()
343 return (asn_kind
==ASN_ampLOWER
);
346 bool Identifier::id_data_t::isvalid_asn_valsetfieldref()
349 return (asn_kind
==ASN_ampUPPER
);
352 bool Identifier::id_data_t::isvalid_asn_objfieldref()
355 return (asn_kind
==ASN_ampLOWER
);
358 bool Identifier::id_data_t::isvalid_asn_objsetfieldref()
361 return (asn_kind
==ASN_ampUPPER
);
364 bool Identifier::id_data_t::isvalid_asn_word()
367 return (asn_kind
==ASN_WORD
);
370 // =================================
371 // ===== internal_data_t
372 // =================================
374 internal_data_t
*internal_data_t::instance
=0;
376 /* format: c++ - asn - ttcn */
377 const char* const internal_data_t::keywords
[][3] = {
378 /* C++ keywords - never can be used */
393 {"const_cast", 0, 0},
399 {"dynamic_cast", 0, 0},
426 {"reinterpret_cast", 0, 0},
432 {"static_cast", 0, 0},
453 /* C++ keywords postfixed, avoiding conflicts from valid ASN/TTCN names */
454 {"asm_", "asm", "asm"},
455 {"auto_", "auto", "auto"},
456 {"bitand_", "bitand", "bitand"},
457 {"bitor_", "bitor", "bitor"},
458 {"bool_", "bool", "bool"},
459 {"class_", "class", "class"},
460 {"compl_", "compl", "compl"},
461 {"delete_", "delete", "delete"},
462 {"double_", "double", "double"},
463 {"enum_", "enum", "enum"},
464 {"explicit_", "explicit", "explicit"},
465 {"export_", "export", "export"},
466 {"extern_", "extern", "extern"},
467 {"friend__", "friend", "friend_"},
468 {"inline_", "inline", "inline"},
469 {"int_", "int", "int"},
470 {"long_", "long", "long"},
471 {"mutable_", "mutable", "mutable"},
472 {"namespace_", "namespace", "namespace"},
473 {"new_", "new", "new"},
474 {"operator_", "operator", "operator"},
475 {"private__", "private", "private_"},
476 {"protected_", "protected", "protected"},
477 {"public__", "public", "public_"},
478 {"register_", "register", "register"},
479 {"short_", "short", "short"},
480 {"signed_", "signed", "signed"},
481 {"static_", "static", "static"},
482 {"struct_", "struct", "struct"},
483 {"switch_", "switch", "switch"},
484 {"this_", "this", "this"},
485 {"throw_", "throw", "throw"},
486 {"try_", "try", "try"},
487 {"typedef_", "typedef", "typedef"},
488 {"typeid_", "typeid", "typeid"},
489 {"typename_", "typename", "typename"},
490 {"unsigned_", "unsigned", "unsigned"},
491 {"using_", "using", "using"},
492 {"virtual_", "virtual", "virtual"},
493 {"void_", "void", "void"},
494 {"volatile_", "volatile", "volatile"},
495 /* C++ keywords postfixed - keywords in TTCN */
496 {"and__", "and", "and_"},
497 {"break__", "break", "break_"},
498 {"case__", "case", "case_"},
499 {"catch__", "catch", "catch_"},
500 {"char__", "char", "char_"},
501 {"const__", "const", "const_"},
502 {"continue__", "continue", "continue_"},
503 {"default__", "default", "default_"},
504 {"do__", "do", "do_"},
505 {"else__", "else", "else_"},
506 {"false__", "false", "false_"},
507 {"float__", "float", "float_"},
508 {"for__", "for", "for_"},
509 {"goto__", "goto", "goto_"},
510 {"if__", "if", "if_"},
511 {"not__", "not", "not_"},
512 {"or__", "or", "or_"},
513 {"return__", "return", "return_"},
514 {"sizeof__", "sizeof", "sizeof_"},
515 {"template__", "template", "template_"},
516 {"true__", "true", "true_"},
517 {"union__", "union", "union_"},
518 {"while__", "while", "while_"},
519 {"xor__", "xor", "xor_"},
520 /* reserved names of base library */
553 {"int2unichar", 0, 0},
573 {"stderr", 0, 0}, // temporary hack
574 {"stdin", 0, 0}, // temporary hack
575 {"stdout", 0, 0}, // temporary hack
582 {"unichar2int", 0, 0},
583 {"unichar2char", 0, 0},
585 {"verdicttype", 0, 0},
586 {"unichar2oct", 0, 0},
587 {"oct2unichar", 0, 0},
588 {"get_stringencoding", 0, 0},
589 {"remove_bom", 0, 0},
590 {"encode_base64", 0, 0},
591 {"decode_base64", 0, 0},
592 /* reserved names of base library - keywords in TTCN - valid ASN.1 */
593 {"bit2hex__", "bit2hex", "bit2hex_"},
594 {"bit2int__", "bit2int", "bit2int_"},
595 {"bit2oct__", "bit2oct", "bit2oct_"},
596 {"bit2str__", "bit2str", "bit2str_"},
597 {"boolean__", "boolean", "boolean_"},
598 {"char2int__", "char2int", "char2int_"},
599 {"char2oct__", "char2oct", "char2oct_"},
600 {"component__", "component", "component_"},
601 {"decomp__", "decomp", "decomp_"},
602 {"float2int__", "float2int", "float2int_"},
603 {"float2str__", "float2str", "float2str_"},
604 {"hex2bit__", "hex2bit", "hex2bit_"},
605 {"hex2int__", "hex2int", "hex2int_"},
606 {"hex2oct__", "hex2oct", "hex2oct_"},
607 {"hex2str__", "hex2str", "hex2str_"},
608 {"int2bit__", "int2bit", "int2bit_"},
609 {"int2char__", "int2char", "int2char_"},
610 {"int2float__", "int2float", "int2float_"},
611 {"int2hex__", "int2hex", "int2hex_"},
612 {"int2oct__", "int2oct", "int2oct_"},
613 {"int2str__", "int2str", "int2str_"},
614 {"int2unichar__", "int2unichar", "int2unichar_"},
615 {"ischosen__", "ischosen", "ischosen_"},
616 {"ispresent__", "ispresent", "ispresent_"},
617 {"isvalue__", "isvalue", "isvalue_"},
618 {"lengthof__", "lengthof", "lengthof_"},
619 {"log__", "log", "log_"},
620 {"log2str__", "log2str", "log2str_"},
621 {"match__", "match", "match_"},
622 {"mod__", "mod", "mod_"},
623 {"oct2bit__", "oct2bit", "oct2bit_"},
624 {"oct2char__", "oct2char", "oct2char_"},
625 {"oct2hex__", "oct2hex", "oct2hex_"},
626 {"oct2int__", "oct2int", "oct2int_"},
627 {"oct2str__", "oct2str", "oct2str_"},
628 {"regexp__", "regexp", "regexp_"},
629 {"replace__", "replace", "replace_"},
630 {"rem__", "rem", "rem_"},
631 {"rnd__", "rnd", "rnd_"},
632 {"self__", "self", "self_"},
633 {"str2bit__", "str2bit", "str2bit_"},
634 {"str2float__", "str2float", "str2float_"},
635 {"str2hex__", "str2hex", "str2hex_"},
636 {"str2int__", "str2int", "str2int_"},
637 {"str2oct__", "str2oct", "str2oct_"},
638 {"substr__", "substr", "substr_"},
639 {"unichar2int__", "unichar2int", "unichar2int_"},
640 {"unichar2char__", "unichar2char", "unichar2char_"},
641 {"valueof__", "valueof", "valueof_"},
642 {"verdicttype__", "verdicttype", "verdicttype_"},
643 {"ttcn2string__", "ttcn2string", "ttcn2string_"},
644 {"string2ttcn__", "string2ttcn", "string2ttcn_"},
645 {"unichar2oct__", "unichar2oct", "unichar2oct_"},
646 {"oct2unichar__", "oct2unichar", "oct2unichar_"},
647 {"remove__bom__", "remove_bom", "remove_bom_"},
648 {"encode__base64__", "encode_base64", "encode_base64_"},
649 {"decode__base64__", "decode_base64", "decode_base64_"},
650 {"get__stringencoding__", "get_stringencoding", "get_stringencoding_"},
651 /* reserved names of base library - keywords in ASN.1 */
652 {"FALSE_", 0, "FALSE"},
653 {"OPTIONAL_", 0, "OPTIONAL"},
654 {"TRUE_", 0, "TRUE"},
655 /* reserved names of base library - not keywords */
656 {"CHAR_", "CHAR", "CHAR"},
657 {"ERROR_", "ERROR", "ERROR"},
658 {"FAIL_", "FAIL", "FAIL"},
659 {"INCONC_", "INCONC", "INCONC"},
660 {"NONE_", "NONE", "NONE"},
661 {"PASS_", "PASS", "PASS"},
662 {"PORT_", "PORT", "PORT"},
663 {"TIMER_", "TIMER", "TIMER"},
664 {"main_", "main", "main"},
665 {"stderr_", "stderr", "stderr"}, // temporary hack
666 {"stdin_", "stdin", "stdin"}, // temporary hack
667 {"stdout_", "stdout", "stdout"}, // temporary hack
668 {"TTCN3_", "TTCN3", "TTCN3"},
669 /* built-in types. this is the ASN/TTCN -> C++ name mapping */
670 {"ADDRESS", 0, "address"},
671 {"ASN_NULL", "NULL", 0},
672 {"BITSTRING", "BIT STRING", "bitstring"},
673 {"BOOLEAN", "BOOLEAN", "boolean"},
674 {"BMPString", "BMPString", 0},
675 {"CHARSTRING", 0, "charstring"},
676 {"CHARACTER_STRING", "CHARACTER STRING", 0},
677 {"COMPONENT", 0, "component"},
678 {"DEFAULT", 0, "default"},
679 {"EMBEDDED_PDV", "EMBEDDED PDV", 0},
680 {"EXTERNAL", "EXTERNAL", 0},
681 {"FLOAT", "REAL", "float"},
682 {"GraphicString", "GraphicString", 0},
683 {"HEXSTRING", 0, "hexstring"},
684 {"IA5String", "IA5String", 0},
685 {"INTEGER", "INTEGER", "integer"},
686 {"ISO646String", "ISO646String", 0},
687 {"NumericString", "NumericString", 0},
688 {"OBJID", "OBJECT IDENTIFIER", "objid"},
689 {"OCTETSTRING", "OCTET STRING", "octetstring"},
690 {"ObjectDescriptor", "ObjectDescriptor", 0},
691 {"PrintableString", "PrintableString", 0},
692 {"T61String", "T61String", 0},
693 {"TeletexString", "TeletexString", 0},
694 {"UTF8String", "UTF8String", 0},
695 {"UniversalString", "UniversalString", 0},
696 {"UNIVERSAL_CHARSTRING", 0, "universal charstring"},
697 {"VERDICTTYPE", 0, "verdicttype"},
698 {"VideotexString", "VideotexString", 0},
699 {"VisibleString", "VisibleString", 0},
700 /* reserved names of built-in types - valid ASN.1/TTCN names */
701 {"ADDRESS_", "ADDRESS", "ADDRESS"},
702 {"BITSTRING_", "BITSTRING", "BITSTRING"},
703 {"BOOLEAN_", 0, "BOOLEAN"},
704 {"BMPString_", 0, "BMPString"},
705 {"CHARSTRING_", "CHARSTRING", "CHARSTRING"},
706 {"COMPONENT_", "COMPONENT", "COMPONENT"},
707 {"DEFAULT_", 0, "DEFAULT"},
708 {"EXTERNAL_", 0, "EXTERNAL"},
709 {"FLOAT_", "FLOAT", "FLOAT"},
710 {"GraphicString_", 0, "GraphicString"},
711 {"HEXSTRING_", "HEXSTRING", "HEXSTRING"},
712 {"IA5String_", 0, "IA5String"},
713 {"INTEGER_", 0, "INTEGER"},
714 {"ISO646String_", 0, "ISO646String"},
715 {"NumericString_", 0, "NumericString"},
716 {"OBJID_", "OBJID", "OBJID"},
717 {"OCTETSTRING_", "OCTETSTRING", "OCTETSTRING"},
718 {"ObjectDescriptor_", 0, "ObjectDescriptor"},
719 {"PrintableString_", 0, "PrintableString"},
720 {"T61String_", 0, "T61String"},
721 {"TeletexString_", 0, "TeletexString"},
722 {"UTF8String_", 0, "UTF8String"},
723 {"UniversalString_", 0, "UniversalString"},
724 {"VERDICTTYPE_", "VERDICTTYPE", "VERDICTTYPE"},
725 {"VideotexString_", 0, "VideotexString"},
726 {"VisibleString_", 0, "VisibleString"},
727 /* keywords in TTCN-3, not reserved words in C++, postfixed in TTCN */
728 {"action__", "action", "action_"},
729 {"activate__", "activate", "activate_"},
730 {"address__", "address", "address_"},
731 {"alive__", "alive", "alive_"},
732 {"all__", "all", "all_"},
733 {"alt__", "alt", "alt_"},
734 {"altstep__", "altstep", "altstep_"},
735 {"and4b__", "and4b", "and4b_"},
736 {"any__", "any", "any_"},
737 {"anytype__", "anytype", "anytype_"},
738 {"apply__", "apply", "apply_"},
739 {"bitstring__", "bitstring", "bitstring_"},
740 {"call__", "call", "call_"},
741 {"charstring__", "charstring", "charstring_"},
742 {"check__", "check", "check_"},
743 {"clear__", "clear", "clear_"},
744 {"complement__", "complement", "complement_"},
745 {"connect__", "connect", "connect_"},
746 {"control__", "control", "control_"},
747 {"create__", "create", "create_"},
748 {"deactivate__", "deactivate", "deactivate_"},
749 {"derefers__", "derefers", "derefers_"},
750 {"disconnect__", "disconnect", "disconnect_"},
751 {"display__", "display", "display_"},
752 {"done__", "done", "done_"},
753 {"encode__", "encode", "encode_"},
754 {"enumerated__", "enumerated", "enumerated_"},
755 {"error__", "error", "error_"},
756 {"except__", "except", "except_"},
757 {"exception__", "exception", "exception_"},
758 {"execute__", "execute", "execute_"},
759 {"extends__", "extends", "extends_"},
760 {"extension__", "extension", "extension_"},
761 {"external__", "external", "external_"},
762 {"fail__", "fail", "fail_"},
763 {"from__", "from", "from_"},
764 {"function__", "function", "function_"},
765 {"getcall__", "getcall", "getcall_"},
766 {"getreply__", "getreply", "getreply_"},
767 {"getverdict__", "getverdict", "getverdict_"},
768 {"group__", "group", "group_"},
769 {"halt__", "halt", "halt_"},
770 {"hexstring__", "hexstring", "hexstring_"},
771 {"ifpresent__", "ifpresent", "ifpresent_"},
772 {"import__", "import", "import_"},
773 {"in__", "in", "in_"},
774 {"inconc__", "inconc", "inconc_"},
775 {"infinity__", "infinity", "infinity_"},
776 {"inout__", "inout", "inout_"},
777 {"integer__", "integer", "integer_"},
778 {"interleave__", "interleave", "interleave_"},
779 {"kill__", "kill", "kill_"},
780 {"killed__", "killed", "killed_"},
781 {"label__", "label", "label_"},
782 {"language__", "language", "language_"},
783 {"length__", "length", "length_"},
784 {"map__", "map", "map_"},
785 {"message__", "message", "message_"},
786 {"mixed__", "mixed", "mixed_"},
787 {"modifies__", "modifies", "modifies_"},
788 {"module__", "module", "module_"},
789 {"modulepar__", "modulepar", "modulepar_"},
790 {"mtc__", "mtc", "mtc_"},
791 {"noblock__", "noblock", "noblock_"},
792 {"none__", "none", "none_"},
793 {"not4b__", "not4b", "not4b_"},
794 {"nowait__", "nowait", "nowait_"},
795 {"null__", "null", "null_"},
796 {"objid__", "objid", "objid_"},
797 {"octetstring__", "octetstring", "octetstring_"},
798 {"of__", "of", "of_"},
799 {"omit__", "omit", "omit_"},
800 {"on__", "on", "on_"},
801 {"optional__", "optional", "optional_"},
802 {"or4b__", "or4b", "or4b_"},
803 {"out__", "out", "out_"},
804 {"override__", "override", "override_"},
805 {"param__", "param", "param_"},
806 {"pass__", "pass", "pass_"},
807 {"pattern__", "pattern", "pattern_"},
808 {"permutation__", "permutation", "permutation_"},
809 {"port__", "port", "port_"},
810 {"procedure__", "procedure", "procedure_"},
811 {"raise__", "raise", "raise_"},
812 {"read__", "read", "read_"},
813 {"receive__", "receive", "receive_"},
814 {"record__", "record", "record_"},
815 {"recursive__", "recursive", "recursive_"},
816 {"refers__", "refers", "refers_"},
817 {"repeat__", "repeat", "repeat_"},
818 {"reply__", "reply", "reply_"},
819 {"running__", "running", "running_"},
820 {"runs__", "runs", "runs_"},
821 {"select__", "select", "select_"},
822 {"send__", "send", "send_"},
823 {"sender__", "sender", "sender_"},
824 {"set__", "set", "set_"},
825 {"setverdict__", "setverdict", "setverdict_"},
826 {"signature__", "signature", "signature_"},
827 {"start__", "start", "start_"},
828 {"stop__", "stop", "stop_"},
829 {"subset__", "subset", "subset_"},
830 {"superset__", "superset", "superset_"},
831 {"system__", "system", "system_"},
832 {"testcase__", "testcase", "testcase_"},
833 {"timeout__", "timeout", "timeout_"},
834 {"timer__", "timer", "timer_"},
835 {"to__", "to", "to_"},
836 {"trigger__", "trigger", "trigger_"},
837 {"type__", "type", "type_"},
838 {"universal__", "universal", "universal_"},
839 {"unmap__", "unmap", "unmap_"},
840 {"value__", "value", "value_"},
841 {"present__", "present", "present_"},
842 {"var__", "var", "var_"},
843 {"variant__", "variant", "variant_"},
844 {"with__", "with", "with_"},
845 {"xor4b__", "xor4b", "xor4b_"},
846 /* other names that need to be mapped in a non-uniform manner */
847 /* major and minor are macros on some platforms; avoid generating
848 * a potentially troublesome C++ identifier */
849 {"major_", "major", "major"},
850 {"minor_", "minor", "minor"},
851 /* internal / error */
852 {"<error>", "<error>", "<error>"},
853 {"TTCN_internal_", "<internal>", "<internal>"},
854 /* the last must be all zeros */
858 internal_data_t::internal_data_t()
859 : identifier_counter(0), string_invalid("<invalid>"), id_map_name(),
860 id_map_asn(), id_map_ttcn()
864 internal_data_t::~internal_data_t()
866 for(size_t i
=0; i
<id_map_name
.size(); i
++)
867 Identifier::id_data_t::delete_this(id_map_name
.get_nth_elem(i
));
869 for(size_t i
=0; i
<id_map_asn
.size(); i
++)
870 Identifier::id_data_t::delete_this(id_map_asn
.get_nth_elem(i
));
872 for(size_t i
=0; i
<id_map_ttcn
.size(); i
++)
873 Identifier::id_data_t::delete_this(id_map_ttcn
.get_nth_elem(i
));
877 void internal_data_t::add_keyword(const char* const keyword
[3])
879 Identifier::id_data_t
*id_data
880 =new Identifier::id_data_t(string(keyword
[0]));
882 // Pointers to already added (conflicting) keyword
883 const Identifier::id_data_t
*id_data_name
=0;
884 const Identifier::id_data_t
*id_data_asn
=0;
885 const Identifier::id_data_t
*id_data_ttcn
=0;
886 if(id_map_name
.has_key(id_data
->name
)) {
888 id_data_name
=id_map_name
[id_data
->name
];
891 id_map_name
.add(id_data
->name
, id_data
);
892 id_data
->ref_count
++;
896 id_data
->asnname
=string_invalid
;
899 // copy the string if possible to avoid memory allocation
900 if (id_data
->name
== keyword
[1]) id_data
->asnname
= id_data
->name
;
901 else id_data
->asnname
= keyword
[1];
902 if(id_map_asn
.has_key(id_data
->asnname
)) {
904 id_data_asn
=id_map_asn
[id_data
->asnname
];
907 id_map_asn
.add(id_data
->asnname
, id_data
);
908 id_data
->ref_count
++;
913 id_data
->ttcnname
=string_invalid
;
916 // copy the string if possible to avoid memory allocation
917 if (id_data
->name
== keyword
[2]) id_data
->ttcnname
= id_data
->name
;
918 else if (id_data
->asnname
== keyword
[2])
919 id_data
->ttcnname
= id_data
->asnname
;
920 else id_data
->ttcnname
= keyword
[2];
921 if(id_map_ttcn
.has_key(id_data
->ttcnname
)) {
923 id_data_ttcn
=id_map_ttcn
[id_data
->ttcnname
];
926 id_map_ttcn
.add(id_data
->ttcnname
, id_data
);
927 id_data
->ref_count
++;
934 ("This pre-defined identifier: %s",
935 id_data
->get_names().c_str());
937 ("conflicts with previous:");
941 id_data_name
->get_names().c_str());
945 id_data_asn
->get_names().c_str());
949 id_data_ttcn
->get_names().c_str());
951 Identifier::id_data_t::delete_this(id_data
);
954 void internal_data_t::add_keywords()
958 Error_Context
cntx(&loc
, "While adding keywords");
959 for(size_t i
=0; keywords
[i
][0]; i
++)
960 add_keyword(keywords
[i
]);
962 /* Perhaps it were good to read a file which contains
963 user-defined mappings :) */
966 internal_data_t
*internal_data_t::Instance()
969 instance
=new internal_data_t();
970 instance
->add_keywords();
975 void internal_data_t::increase_counter()
977 identifier_counter
++;
980 void internal_data_t::decrease_counter()
982 identifier_counter
--;
983 if(identifier_counter
==0) {
986 } // if last Identifier instance
989 // =================================
991 // =================================
993 bool Identifier::is_reserved_word(const string
& p_name
, id_t p_id_t
)
996 FATAL_ERROR("Identifier::is_reserved_word(): empty name");
997 internal_data_t
*d
= internal_data_t::Instance();
1000 if (d
->id_map_name
.has_key(p_name
)) {
1001 id_data_t
*id_data_p
= d
->id_map_name
[p_name
];
1002 if (id_data_p
->asnname
== d
->string_invalid
&&
1003 id_data_p
->ttcnname
== d
->string_invalid
) return true;
1005 } else return false;
1007 if (p_name
[0] == '&' || d
->id_map_asn
.has_key(p_name
)) return false;
1010 id_data_t::asn_2_name(name
, p_name
);
1011 if (d
->id_map_name
.has_key(name
)) {
1012 id_data_t
*id_data_p
= d
->id_map_name
[name
];
1013 if (id_data_p
->asnname
.empty()) {
1014 id_data_p
->asnname
= p_name
;
1015 d
->id_map_asn
.add(p_name
, id_data_p
);
1016 id_data_p
->ref_count
++;
1018 } else if (id_data_p
->asnname
== p_name
) return false;
1020 } else return false;
1023 if (d
->id_map_ttcn
.has_key(p_name
)) return false;
1026 id_data_t::ttcn_2_name(name
, p_name
);
1027 if (d
->id_map_name
.has_key(name
)) {
1028 id_data_t
*id_data_p
= d
->id_map_name
[name
];
1029 if (id_data_p
->ttcnname
.empty()) {
1030 id_data_p
->ttcnname
= p_name
;
1031 d
->id_map_ttcn
.add(p_name
, id_data_p
);
1032 id_data_p
->ref_count
++;
1034 } else if (id_data_p
->ttcnname
== p_name
) return false;
1036 } else return false;
1039 FATAL_ERROR("Identifier::is_reserved_word(): invalid language");
1044 string
Identifier::asn_2_name(const string
& p_name
)
1046 internal_data_t
*d
= internal_data_t::Instance();
1047 if (d
->id_map_asn
.has_key(p_name
)) {
1048 id_data_t
*id_data_p
= d
->id_map_asn
[p_name
];
1049 if (id_data_p
->name
.empty()) {
1050 id_data_t::asn_2_name(id_data_p
->name
, p_name
);
1051 d
->id_map_name
.add(id_data_p
->name
, id_data_p
);
1052 id_data_p
->ref_count
++;
1054 return id_data_p
->name
;
1057 id_data_t::asn_2_name(name
, p_name
);
1058 if (d
->id_map_name
.has_key(name
)) {
1059 id_data_t
*id_data_p
= d
->id_map_name
[name
];
1060 if (id_data_p
->asnname
.empty()) {
1061 id_data_p
->asnname
= p_name
;
1062 d
->id_map_asn
.add(p_name
, id_data_p
);
1063 id_data_p
->ref_count
++;
1070 string
Identifier::name_2_asn(const string
& p_name
)
1072 internal_data_t
*d
= internal_data_t::Instance();
1073 if (d
->id_map_name
.has_key(p_name
)) {
1074 id_data_t
*id_data_p
= d
->id_map_name
[p_name
];
1075 if (id_data_p
->asnname
.empty()) {
1076 id_data_t::name_2_asn(id_data_p
->asnname
, p_name
);
1077 d
->id_map_asn
.add(id_data_p
->asnname
, id_data_p
);
1078 id_data_p
->ref_count
++;
1080 return id_data_p
->asnname
;
1083 id_data_t::name_2_asn(asnname
, p_name
);
1084 if (d
->id_map_asn
.has_key(asnname
)) {
1085 id_data_t
*id_data_p
= d
->id_map_asn
[asnname
];
1086 if (id_data_p
->name
.empty()) {
1087 id_data_p
->name
= p_name
;
1088 d
->id_map_name
.add(p_name
, id_data_p
);
1089 id_data_p
->ref_count
++;
1096 string
Identifier::ttcn_2_name(const string
& p_name
)
1098 internal_data_t
*d
= internal_data_t::Instance();
1099 if (d
->id_map_ttcn
.has_key(p_name
)) {
1100 id_data_t
*id_data_p
= d
->id_map_ttcn
[p_name
];
1101 if (id_data_p
->name
.empty()) {
1102 id_data_t::ttcn_2_name(id_data_p
->name
, p_name
);
1103 d
->id_map_name
.add(id_data_p
->name
, id_data_p
);
1104 id_data_p
->ref_count
++;
1106 return id_data_p
->name
;
1109 id_data_t::ttcn_2_name(name
, p_name
);
1110 if (d
->id_map_name
.has_key(name
)) {
1111 id_data_t
*id_data_p
= d
->id_map_name
[name
];
1112 if (id_data_p
->ttcnname
.empty()) {
1113 id_data_p
->ttcnname
= p_name
;
1114 d
->id_map_ttcn
.add(p_name
, id_data_p
);
1115 id_data_p
->ref_count
++;
1122 string
Identifier::name_2_ttcn(const string
& p_name
)
1124 internal_data_t
*d
= internal_data_t::Instance();
1125 if (d
->id_map_name
.has_key(p_name
)) {
1126 id_data_t
*id_data_p
= d
->id_map_name
[p_name
];
1127 if (id_data_p
->ttcnname
.empty()) {
1128 id_data_t::name_2_ttcn(id_data_p
->ttcnname
, p_name
);
1129 d
->id_map_ttcn
.add(id_data_p
->ttcnname
, id_data_p
);
1130 id_data_p
->ref_count
++;
1132 return id_data_p
->ttcnname
;
1135 id_data_t::name_2_ttcn(ttcnname
, p_name
);
1136 if (d
->id_map_ttcn
.has_key(ttcnname
)) {
1137 id_data_t
*id_data_p
= d
->id_map_ttcn
[ttcnname
];
1138 if (id_data_p
->name
.empty()) {
1139 id_data_p
->name
= p_name
;
1140 d
->id_map_name
.add(p_name
, id_data_p
);
1141 id_data_p
->ref_count
++;
1148 Identifier::Identifier(id_t p_id_t
, const string
& p_name
, bool dontreg
)
1149 : id_data(0), origin(p_id_t
)
1151 if (p_name
.empty()) FATAL_ERROR("Identifier::Identifier(): empty name");
1152 internal_data_t
*d
=internal_data_t::Instance();
1153 d
->increase_counter();
1156 if(d
->id_map_name
.has_key(p_name
)) {
1157 id_data
=d
->id_map_name
[p_name
];
1158 id_data
->ref_count
++;
1161 id_data
=new id_data_t(p_name
);
1163 d
->id_map_name
.add(p_name
, id_data
);
1164 id_data
->ref_count
++;
1169 if(d
->id_map_asn
.has_key(p_name
)) {
1170 id_data
=d
->id_map_asn
[p_name
];
1171 id_data
->ref_count
++;
1173 else if(p_name
[0]=='&') { // special amp-identifiers (&)
1174 string p_name2
=p_name
.substr(1);
1176 if(d
->id_map_asn
.has_key(p_name2
))
1177 name2
=d
->id_map_asn
[p_name2
]->get_name();
1179 id_data_t::asn_2_name(name2
, p_name2
);
1180 id_data
=new id_data_t(name2
);
1181 id_data
->asnname
=p_name
;
1182 id_data
->ttcnname
=d
->string_invalid
;
1184 d
->id_map_asn
.add(p_name
, id_data
);
1185 id_data
->ref_count
++;
1187 /* this id_data should NOT be added to id_map_name. */
1191 id_data_t::asn_2_name(name
, p_name
);
1192 if(!dontreg
&& d
->id_map_name
.has_key(name
)) {
1193 id_data
=d
->id_map_name
[name
];
1194 id_data
->ref_count
++;
1195 if(id_data
->asnname
.empty()) {
1196 id_data
->asnname
=p_name
;
1198 d
->id_map_asn
.add(p_name
, id_data
);
1199 id_data
->ref_count
++;
1202 else if(id_data
->asnname
!=p_name
) {
1205 ("The ASN identifier `%s' clashes with this id: %s",
1206 p_name
.c_str(), id_data
->get_names().c_str());
1210 id_data
=new id_data_t(name
);
1211 id_data
->asnname
=p_name
;
1213 d
->id_map_name
.add(name
, id_data
);
1214 d
->id_map_asn
.add(p_name
, id_data
);
1215 id_data
->ref_count
+=2;
1221 if(d
->id_map_ttcn
.has_key(p_name
)) {
1222 id_data
=d
->id_map_ttcn
[p_name
];
1223 id_data
->ref_count
++;
1227 id_data_t::ttcn_2_name(name
, p_name
);
1228 if(!dontreg
&& d
->id_map_name
.has_key(name
)) {
1229 id_data
=d
->id_map_name
[name
];
1230 id_data
->ref_count
++;
1231 if(id_data
->ttcnname
.empty()) {
1232 id_data
->ttcnname
=p_name
;
1234 d
->id_map_ttcn
.add(p_name
, id_data
);
1235 id_data
->ref_count
++;
1238 else if(id_data
->ttcnname
!=p_name
) {
1241 ("The TTCN identifier `%s' clashes with this id: %s",
1242 p_name
.c_str(), id_data
->get_names().c_str());
1246 id_data
=new id_data_t(name
);
1247 id_data
->ttcnname
=p_name
;
1249 d
->id_map_name
.add(name
, id_data
);
1250 d
->id_map_ttcn
.add(p_name
, id_data
);
1251 id_data
->ref_count
+=2;
1257 FATAL_ERROR("Identifier::Identifier()");
1261 Identifier::Identifier(const Identifier
& p
)
1262 : id_data(p
.id_data
), origin(p
.origin
)
1264 internal_data_t::Instance()->increase_counter();
1265 id_data
->ref_count
++;
1268 Identifier::~Identifier()
1270 id_data_t::delete_this(id_data
);
1271 /* I don't want to free the id_data structs here. They will be
1272 deleted in decrease_counter() when the maps are destructed. */
1273 internal_data_t::Instance()->decrease_counter();
1276 Identifier
& Identifier::operator=(const Identifier
& p
)
1279 id_data_t::delete_this(id_data
);
1281 id_data
->ref_count
++;
1287 bool Identifier::operator==(const Identifier
& p
) const
1289 return id_data
->name
==p
.id_data
->name
;
1292 bool Identifier::operator<(const Identifier
& p
) const
1294 return id_data
->name
<p
.id_data
->name
;
1297 const string
& Identifier::get_name() const
1299 return id_data
->get_name();
1302 const string
& Identifier::get_dispname() const
1306 return id_data
->get_name();
1308 return id_data
->get_asnname();
1310 return id_data
->get_ttcnname();
1312 FATAL_ERROR("Identifier::get_dispname()");
1313 return id_data
->get_name();
1317 const string
& Identifier::get_asnname() const
1319 return id_data
->get_asnname();
1322 const string
& Identifier::get_ttcnname() const
1324 return id_data
->get_ttcnname();
1327 bool Identifier::get_has_valid(id_t p_id_t
) const
1329 return id_data
->get_has_valid(p_id_t
);
1332 string
Identifier::get_names() const
1334 return id_data
->get_names();
1337 bool Identifier::isvalid_asn_modref() const
1339 return id_data
->isvalid_asn_modref();
1342 bool Identifier::isvalid_asn_typeref() const
1344 return id_data
->isvalid_asn_typeref();
1347 bool Identifier::isvalid_asn_valref() const
1349 return id_data
->isvalid_asn_valref();
1352 bool Identifier::isvalid_asn_valsetref() const
1354 return id_data
->isvalid_asn_valsetref();
1357 bool Identifier::isvalid_asn_objclassref() const
1359 return id_data
->isvalid_asn_objclassref();
1362 bool Identifier::isvalid_asn_objref() const
1364 return id_data
->isvalid_asn_objref();
1367 bool Identifier::isvalid_asn_objsetref() const
1369 return id_data
->isvalid_asn_objsetref();
1372 bool Identifier::isvalid_asn_typefieldref() const
1374 return id_data
->isvalid_asn_typefieldref();
1377 bool Identifier::isvalid_asn_valfieldref() const
1379 return id_data
->isvalid_asn_valfieldref();
1382 bool Identifier::isvalid_asn_valsetfieldref() const
1384 return id_data
->isvalid_asn_valsetfieldref();
1387 bool Identifier::isvalid_asn_objfieldref() const
1389 return id_data
->isvalid_asn_objfieldref();
1392 bool Identifier::isvalid_asn_objsetfieldref() const
1394 return id_data
->isvalid_asn_objsetfieldref();
1397 bool Identifier::isvalid_asn_word() const
1399 return id_data
->isvalid_asn_word();
1402 void Identifier::dump(unsigned level
) const
1404 DEBUG(level
, "Identifier: %s", id_data
->get_names().c_str());
1407 const Identifier
underscore_zero(Identifier::ID_TTCN
, string("_0"));
1409 } // namespace Common
This page took 0.079326 seconds and 5 git commands to generate.