Sync with 5.4.2
[deliverable/titan.core.git] / compiler2 / Identifier.cc
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"
10 #include <ctype.h>
11 #include "Setting.hh"
12 #include "CompilerError.hh"
13
14 namespace Common {
15
16 // =================================
17 // ===== Identifier::id_data_t
18 // =================================
19
20 struct Identifier::id_data_t {
21 size_t ref_count;
22 string name, asnname, ttcnname;
23 /** ASN kind of the identifier. */
24 enum asn_kind_t {
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} */
32 } asn_kind;
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();
74 private:
75 ~id_data_t() {}
76 void decide_asn_kind();
77 };
78
79 // =================================
80 // ===== internal_data_t
81 // =================================
82
83 class internal_data_t {
84 private:
85 static internal_data_t *instance;
86 static const char* const keywords[][3];
87 size_t identifier_counter;
88 public:
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;
96 private:
97 internal_data_t();
98 internal_data_t(const internal_data_t&);
99 ~internal_data_t();
100 void add_keyword(const char* const keyword[3]);
101 void add_keywords();
102 public:
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
106 * constructor. */
107 void increase_counter();
108 /** Decreases the instance counter. Finalizes the keywords if this
109 * is the last instance. Must be called in Identifier
110 * destructor. */
111 void decrease_counter();
112 };
113
114 // ======================================================================
115 // ======================================================================
116
117 // =================================
118 // ===== Identifier::id_data_t
119 // =================================
120
121 void Identifier::id_data_t::asn_2_name(string& p_to, const string& p_from)
122 {
123 p_to = 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" */
127 size_t pos = 0;
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, "");
131 else break;
132 }
133 /* "-" -> "__" */
134 pos = 0;
135 while ((pos = p_to.find('-', pos)) < p_to.size()) {
136 p_to.replace(pos, 1, "__");
137 pos += 2;
138 }
139 /* "." -> "_" */
140 pos = 0;
141 while ((pos = p_to.find('.', pos)) < p_to.size()) {
142 p_to[pos] = '_';
143 pos++;
144 }
145 /* "&" -> "" */
146 pos = 0;
147 while ((pos = p_to.find('&', pos)) < p_to.size())
148 p_to.replace(pos, 1, "");
149 }
150
151 void Identifier::id_data_t::name_2_asn(string& p_to, const string& p_from)
152 {
153 p_to = p_from;
154 /* remove leading '_'s */
155 size_t pos = 0;
156 while (pos < p_to.size() && p_to[pos] == '_') pos++;
157 if (pos > 0) p_to.replace(0, pos, "");
158 /* remove trailing '_'s */
159 pos = p_to.size();
160 while (pos > 0 && p_to[pos - 1] == '_') pos--;
161 if (pos < p_to.size()) p_to.resize(pos);
162 /* "__" -> "-" */
163 pos = 0;
164 while ((pos = p_to.find("__", pos)) < p_to.size()) {
165 p_to.replace(pos, 2, "-");
166 pos++;
167 }
168 /* "_" -> "-" */
169 pos = 0;
170 while ((pos = p_to.find('_', pos)) < p_to.size()) {
171 p_to[pos] = '-';
172 pos++;
173 }
174 }
175
176 void Identifier::id_data_t::ttcn_2_name(string& p_to, const string& p_from)
177 {
178 p_to = p_from;
179 /* "_" -> "__" */
180 size_t pos = 0;
181 while ((pos = p_to.find('_', pos)) < p_to.size()) {
182 p_to.replace(pos, 1, "__");
183 pos += 2;
184 }
185 }
186
187 void Identifier::id_data_t::name_2_ttcn(string& p_to, const string& p_from)
188 {
189 p_to = p_from;
190 /* remove leading '_'s */
191 size_t pos = 0;
192 while (pos < p_to.size() && p_to[pos] == '_') pos++;
193 if (pos > 0) p_to.replace(0, pos, "");
194 /* remove trailing '_'s */
195 pos = p_to.size();
196 while (pos > 0 && p_to[pos - 1] == '_') pos--;
197 if (pos < p_to.size()) p_to.resize(pos);
198 /* "__" -> "_" */
199 pos = 0;
200 while ((pos = p_to.find("__", pos)) < p_to.size()) {
201 p_to.replace(pos, 1, "");
202 pos++;
203 }
204 }
205
206 const string& Identifier::id_data_t::get_asnname()
207 {
208 if (asnname.empty()) name_2_asn(asnname, name);
209 return asnname;
210 }
211
212 const string& Identifier::id_data_t::get_ttcnname()
213 {
214 if (ttcnname.empty()) name_2_ttcn(ttcnname, name);
215 return ttcnname;
216 }
217
218 bool Identifier::id_data_t::get_has_valid(id_t p_id_t)
219 {
220 const string& inval=internal_data_t::Instance()->string_invalid;
221 switch(p_id_t) {
222 case ID_NAME:
223 return get_name()!=inval;
224 case ID_ASN:
225 return get_asnname()!=inval;
226 case ID_TTCN:
227 return get_ttcnname()!=inval;
228 default:
229 FATAL_ERROR("Identifier::id_data_t::get_has_valid()");
230 return false;
231 }
232 }
233
234 void Identifier::id_data_t::delete_this(id_data_t *p_id_data_t)
235 {
236 p_id_data_t->ref_count--;
237 if(p_id_data_t->ref_count==0)
238 delete p_id_data_t;
239 }
240
241 string Identifier::id_data_t::get_names() const
242 {
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+"'";
249 s+=")";
250 return s;
251 }
252
253 void Identifier::id_data_t::decide_asn_kind()
254 {
255 if(asn_kind!=ASN_UNDEF) return;
256 get_asnname();
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;
264 }
265 }
266 else if(islower(asnname[0])) {
267 asn_kind=ASN_LOWER;
268 }
269 else if(isupper(asnname[0])) {
270 asn_kind=ASN_UPPER;
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()) {
274 asn_kind=ASN_WORD;
275 }
276 }
277 }
278 }
279
280 bool Identifier::id_data_t::isvalid_asn_modref()
281 {
282 return isvalid_asn_typeref();
283 }
284
285 bool Identifier::id_data_t::isvalid_asn_typeref()
286 {
287 decide_asn_kind();
288 return (asn_kind==ASN_UPPER
289 || asn_kind==ASN_ALLUPPER
290 || asn_kind==ASN_WORD);
291 }
292
293 bool Identifier::id_data_t::isvalid_asn_valref()
294 {
295 decide_asn_kind();
296 return (asn_kind==ASN_LOWER);
297 }
298
299 bool Identifier::id_data_t::isvalid_asn_valsetref()
300 {
301 return isvalid_asn_typeref();
302 }
303
304 bool Identifier::id_data_t::isvalid_asn_objclassref()
305 {
306 decide_asn_kind();
307 return (asn_kind==ASN_ALLUPPER
308 || asn_kind==ASN_WORD);
309 }
310
311 bool Identifier::id_data_t::isvalid_asn_objref()
312 {
313 decide_asn_kind();
314 return (asn_kind==ASN_LOWER);
315 }
316
317 bool Identifier::id_data_t::isvalid_asn_objsetref()
318 {
319 return isvalid_asn_typeref();
320 }
321
322 bool Identifier::id_data_t::isvalid_asn_typefieldref()
323 {
324 decide_asn_kind();
325 return (asn_kind==ASN_ampUPPER);
326 }
327
328 bool Identifier::id_data_t::isvalid_asn_valfieldref()
329 {
330 decide_asn_kind();
331 return (asn_kind==ASN_ampLOWER);
332 }
333
334 bool Identifier::id_data_t::isvalid_asn_valsetfieldref()
335 {
336 decide_asn_kind();
337 return (asn_kind==ASN_ampUPPER);
338 }
339
340 bool Identifier::id_data_t::isvalid_asn_objfieldref()
341 {
342 decide_asn_kind();
343 return (asn_kind==ASN_ampLOWER);
344 }
345
346 bool Identifier::id_data_t::isvalid_asn_objsetfieldref()
347 {
348 decide_asn_kind();
349 return (asn_kind==ASN_ampUPPER);
350 }
351
352 bool Identifier::id_data_t::isvalid_asn_word()
353 {
354 decide_asn_kind();
355 return (asn_kind==ASN_WORD);
356 }
357
358 // =================================
359 // ===== internal_data_t
360 // =================================
361
362 internal_data_t *internal_data_t::instance=0;
363
364 /* format: c++ - asn - ttcn */
365 const char* const internal_data_t::keywords[][3] = {
366 /* C++ keywords - never can be used */
367 {"and", 0, 0},
368 {"and_eq", 0, 0},
369 {"asm", 0, 0},
370 {"auto", 0, 0},
371 {"bitand", 0, 0},
372 {"bitor", 0, 0},
373 {"bool", 0, 0},
374 {"break", 0, 0},
375 {"case", 0, 0},
376 {"catch", 0, 0},
377 {"char", 0, 0},
378 {"class", 0, 0},
379 {"compl", 0, 0},
380 {"const", 0, 0},
381 {"const_cast", 0, 0},
382 {"continue", 0, 0},
383 {"default", 0, 0},
384 {"delete", 0, 0},
385 {"do", 0, 0},
386 {"double", 0, 0},
387 {"dynamic_cast", 0, 0},
388 {"else", 0, 0},
389 {"enum", 0, 0},
390 {"explicit", 0, 0},
391 {"export", 0, 0},
392 {"extern", 0, 0},
393 {"false", 0, 0},
394 {"float", 0, 0},
395 {"for", 0, 0},
396 {"friend", 0, 0},
397 {"goto", 0, 0},
398 {"if", 0, 0},
399 {"inline", 0, 0},
400 {"int", 0, 0},
401 {"long", 0, 0},
402 {"mutable", 0, 0},
403 {"namespace", 0, 0},
404 {"new", 0, 0},
405 {"not", 0, 0},
406 {"not_eq", 0, 0},
407 {"operator", 0, 0},
408 {"or", 0, 0},
409 {"or_eq", 0, 0},
410 {"private", 0, 0},
411 {"protected", 0, 0},
412 {"public", 0, 0},
413 {"register", 0, 0},
414 {"reinterpret_cast", 0, 0},
415 {"return", 0, 0},
416 {"short", 0, 0},
417 {"signed", 0, 0},
418 {"sizeof", 0, 0},
419 {"static", 0, 0},
420 {"static_cast", 0, 0},
421 {"struct", 0, 0},
422 {"switch", 0, 0},
423 {"template", 0, 0},
424 {"this", 0, 0},
425 {"throw", 0, 0},
426 {"true", 0, 0},
427 {"try", 0, 0},
428 {"typedef", 0, 0},
429 {"typeid", 0, 0},
430 {"typename", 0, 0},
431 {"union", 0, 0},
432 {"unsigned", 0, 0},
433 {"using", 0, 0},
434 {"virtual", 0, 0},
435 {"void", 0, 0},
436 {"volatile", 0, 0},
437 {"wchar_t", 0, 0},
438 {"while", 0, 0},
439 {"xor", 0, 0},
440 {"xor_eq", 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 */
509 {"CHAR", 0, 0},
510 {"ERROR", 0, 0},
511 {"FAIL", 0, 0},
512 {"INCONC", 0, 0},
513 {"FALSE", 0, 0},
514 {"NONE", 0, 0},
515 {"OPTIONAL", 0, 0},
516 {"PASS", 0, 0},
517 {"PORT", 0, 0},
518 {"TIMER", 0, 0},
519 {"TRUE", 0, 0},
520 {"bit2hex", 0, 0},
521 {"bit2int", 0, 0},
522 {"bit2oct", 0, 0},
523 {"bit2str", 0, 0},
524 {"boolean", 0, 0},
525 {"char2int", 0, 0},
526 {"char2oct", 0, 0},
527 {"component", 0, 0},
528 {"decomp", 0, 0},
529 {"float2int", 0, 0},
530 {"float2str", 0, 0},
531 {"hex2bit", 0, 0},
532 {"hex2int", 0, 0},
533 {"hex2oct", 0, 0},
534 {"hex2str", 0, 0},
535 {"int2bit", 0, 0},
536 {"int2char", 0, 0},
537 {"int2float", 0, 0},
538 {"int2hex", 0, 0},
539 {"int2oct", 0, 0},
540 {"int2str", 0, 0},
541 {"int2unichar", 0, 0},
542 {"ischosen", 0, 0},
543 {"ispresent", 0, 0},
544 {"isvalue", 0, 0},
545 {"lengthof", 0, 0},
546 {"log", 0, 0},
547 {"log2str", 0, 0},
548 {"main", 0, 0},
549 {"match", 0, 0},
550 {"mod", 0, 0},
551 {"oct2bit", 0, 0},
552 {"oct2char", 0, 0},
553 {"oct2hex", 0, 0},
554 {"oct2int", 0, 0},
555 {"oct2str", 0, 0},
556 {"regexp", 0, 0},
557 {"replace", 0, 0},
558 {"rem", 0, 0},
559 {"rnd", 0, 0},
560 {"self", 0, 0},
561 {"stderr", 0, 0}, // temporary hack
562 {"stdin", 0, 0}, // temporary hack
563 {"stdout", 0, 0}, // temporary hack
564 {"str2bit", 0, 0},
565 {"str2float", 0, 0},
566 {"str2hex", 0, 0},
567 {"str2int", 0, 0},
568 {"str2oct", 0, 0},
569 {"substr", 0, 0},
570 {"unichar2int", 0, 0},
571 {"unichar2char", 0, 0},
572 {"valueof", 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 */
843 {0, 0, 0}
844 }; // keywords
845
846 internal_data_t::internal_data_t()
847 : identifier_counter(0), string_invalid("<invalid>"), id_map_name(),
848 id_map_asn(), id_map_ttcn()
849 {
850 }
851
852 internal_data_t::~internal_data_t()
853 {
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));
856 id_map_name.clear();
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));
859 id_map_asn.clear();
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));
862 id_map_ttcn.clear();
863 }
864
865 void internal_data_t::add_keyword(const char* const keyword[3])
866 {
867 Identifier::id_data_t *id_data
868 =new Identifier::id_data_t(string(keyword[0]));
869 bool conflict=false;
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)) {
875 conflict=true;
876 id_data_name=id_map_name[id_data->name];
877 }
878 else {
879 id_map_name.add(id_data->name, id_data);
880 id_data->ref_count++;
881 }
882
883 if(keyword[1]==0) {
884 id_data->asnname=string_invalid;
885 }
886 else {
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)) {
891 conflict=true;
892 id_data_asn=id_map_asn[id_data->asnname];
893 }
894 else {
895 id_map_asn.add(id_data->asnname, id_data);
896 id_data->ref_count++;
897 }
898 }
899
900 if(keyword[2]==0) {
901 id_data->ttcnname=string_invalid;
902 }
903 else {
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)) {
910 conflict=true;
911 id_data_ttcn=id_map_ttcn[id_data->ttcnname];
912 }
913 else {
914 id_map_ttcn.add(id_data->ttcnname, id_data);
915 id_data->ref_count++;
916 }
917 }
918
919 if(conflict) {
920 Location loc;
921 loc.error
922 ("This pre-defined identifier: %s",
923 id_data->get_names().c_str());
924 loc.error
925 ("conflicts with previous:");
926 if(id_data_name)
927 loc.error
928 ("[C++:] %s",
929 id_data_name->get_names().c_str());
930 if(id_data_asn)
931 loc.error
932 ("[ASN:] %s",
933 id_data_asn->get_names().c_str());
934 if(id_data_ttcn)
935 loc.error
936 ("[TTCN:] %s",
937 id_data_ttcn->get_names().c_str());
938 } // if conflict
939 Identifier::id_data_t::delete_this(id_data);
940 }
941
942 void internal_data_t::add_keywords()
943 {
944 {
945 Location loc;
946 Error_Context cntx(&loc, "While adding keywords");
947 for(size_t i=0; keywords[i][0]; i++)
948 add_keyword(keywords[i]);
949 }
950 /* Perhaps it were good to read a file which contains
951 user-defined mappings :) */
952 }
953
954 internal_data_t *internal_data_t::Instance()
955 {
956 if(!instance) {
957 instance=new internal_data_t();
958 instance->add_keywords();
959 }
960 return instance;
961 }
962
963 void internal_data_t::increase_counter()
964 {
965 identifier_counter++;
966 }
967
968 void internal_data_t::decrease_counter()
969 {
970 identifier_counter--;
971 if(identifier_counter==0) {
972 delete instance;
973 instance=0;
974 } // if last Identifier instance
975 }
976
977 // =================================
978 // ===== Identifier
979 // =================================
980
981 bool Identifier::is_reserved_word(const string& p_name, id_t p_id_t)
982 {
983 if (p_name.empty())
984 FATAL_ERROR("Identifier::is_reserved_word(): empty name");
985 internal_data_t *d = internal_data_t::Instance();
986 switch (p_id_t) {
987 case ID_NAME:
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;
992 else return false;
993 } else return false;
994 case ID_ASN:
995 if (p_name[0] == '&' || d->id_map_asn.has_key(p_name)) return false;
996 else {
997 string name;
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++;
1005 return false;
1006 } else if (id_data_p->asnname == p_name) return false;
1007 else return true;
1008 } else return false;
1009 }
1010 case ID_TTCN:
1011 if (d->id_map_ttcn.has_key(p_name)) return false;
1012 else {
1013 string name;
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++;
1021 return false;
1022 } else if (id_data_p->ttcnname == p_name) return false;
1023 else return true;
1024 } else return false;
1025 }
1026 default:
1027 FATAL_ERROR("Identifier::is_reserved_word(): invalid language");
1028 return false;
1029 }
1030 }
1031
1032 string Identifier::asn_2_name(const string& p_name)
1033 {
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++;
1041 }
1042 return id_data_p->name;
1043 } else {
1044 string 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++;
1052 }
1053 }
1054 return name;
1055 }
1056 }
1057
1058 string Identifier::name_2_asn(const string& p_name)
1059 {
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++;
1067 }
1068 return id_data_p->asnname;
1069 } else {
1070 string 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++;
1078 }
1079 }
1080 return asnname;
1081 }
1082 }
1083
1084 string Identifier::ttcn_2_name(const string& p_name)
1085 {
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++;
1093 }
1094 return id_data_p->name;
1095 } else {
1096 string 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++;
1104 }
1105 }
1106 return name;
1107 }
1108 }
1109
1110 string Identifier::name_2_ttcn(const string& p_name)
1111 {
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++;
1119 }
1120 return id_data_p->ttcnname;
1121 } else {
1122 string 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++;
1130 }
1131 }
1132 return ttcnname;
1133 }
1134 }
1135
1136 Identifier::Identifier(id_t p_id_t, const string& p_name, bool dontreg)
1137 : id_data(0), origin(p_id_t)
1138 {
1139 if (p_name.empty()) FATAL_ERROR("Identifier::Identifier(): empty name");
1140 internal_data_t *d=internal_data_t::Instance();
1141 d->increase_counter();
1142 switch(p_id_t) {
1143 case ID_NAME:
1144 if(d->id_map_name.has_key(p_name)) {
1145 id_data=d->id_map_name[p_name];
1146 id_data->ref_count++;
1147 }
1148 else {
1149 id_data=new id_data_t(p_name);
1150 if(!dontreg) {
1151 d->id_map_name.add(p_name, id_data);
1152 id_data->ref_count++;
1153 }
1154 }
1155 break;
1156 case ID_ASN:
1157 if(d->id_map_asn.has_key(p_name)) {
1158 id_data=d->id_map_asn[p_name];
1159 id_data->ref_count++;
1160 }
1161 else if(p_name[0]=='&') { // special amp-identifiers (&)
1162 string p_name2=p_name.substr(1);
1163 string name2;
1164 if(d->id_map_asn.has_key(p_name2))
1165 name2=d->id_map_asn[p_name2]->get_name();
1166 else
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;
1171 if(!dontreg) {
1172 d->id_map_asn.add(p_name, id_data);
1173 id_data->ref_count++;
1174 }
1175 /* this id_data should NOT be added to id_map_name. */
1176 } // if &identifier
1177 else {
1178 string 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;
1185 if(!dontreg) {
1186 d->id_map_asn.add(p_name, id_data);
1187 id_data->ref_count++;
1188 }
1189 }
1190 else if(id_data->asnname!=p_name) {
1191 Location loc;
1192 loc.error
1193 ("The ASN identifier `%s' clashes with this id: %s",
1194 p_name.c_str(), id_data->get_names().c_str());
1195 }
1196 }
1197 else {
1198 id_data=new id_data_t(name);
1199 id_data->asnname=p_name;
1200 if(!dontreg) {
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;
1204 }
1205 }
1206 }
1207 break;
1208 case ID_TTCN:
1209 if(d->id_map_ttcn.has_key(p_name)) {
1210 id_data=d->id_map_ttcn[p_name];
1211 id_data->ref_count++;
1212 }
1213 else {
1214 string name;
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;
1221 if(!dontreg) {
1222 d->id_map_ttcn.add(p_name, id_data);
1223 id_data->ref_count++;
1224 }
1225 }
1226 else if(id_data->ttcnname!=p_name) {
1227 Location loc;
1228 loc.error
1229 ("The TTCN identifier `%s' clashes with this id: %s",
1230 p_name.c_str(), id_data->get_names().c_str());
1231 }
1232 }
1233 else {
1234 id_data=new id_data_t(name);
1235 id_data->ttcnname=p_name;
1236 if(!dontreg) {
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;
1240 }
1241 }
1242 }
1243 break;
1244 default:
1245 FATAL_ERROR("Identifier::Identifier()");
1246 } // switch p_id_t
1247 }
1248
1249 Identifier::Identifier(const Identifier& p)
1250 : id_data(p.id_data), origin(p.origin)
1251 {
1252 internal_data_t::Instance()->increase_counter();
1253 id_data->ref_count++;
1254 }
1255
1256 Identifier::~Identifier()
1257 {
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();
1262 }
1263
1264 Identifier& Identifier::operator=(const Identifier& p)
1265 {
1266 if(&p!=this) {
1267 id_data_t::delete_this(id_data);
1268 id_data=p.id_data;
1269 id_data->ref_count++;
1270 origin=p.origin;
1271 }
1272 return *this;
1273 }
1274
1275 bool Identifier::operator==(const Identifier& p) const
1276 {
1277 return id_data->name==p.id_data->name;
1278 }
1279
1280 bool Identifier::operator<(const Identifier& p) const
1281 {
1282 return id_data->name<p.id_data->name;
1283 }
1284
1285 const string& Identifier::get_name() const
1286 {
1287 return id_data->get_name();
1288 }
1289
1290 const string& Identifier::get_dispname() const
1291 {
1292 switch(origin) {
1293 case ID_NAME:
1294 return id_data->get_name();
1295 case ID_ASN:
1296 return id_data->get_asnname();
1297 case ID_TTCN:
1298 return id_data->get_ttcnname();
1299 default:
1300 FATAL_ERROR("Identifier::get_dispname()");
1301 return id_data->get_name();
1302 }
1303 }
1304
1305 const string& Identifier::get_asnname() const
1306 {
1307 return id_data->get_asnname();
1308 }
1309
1310 const string& Identifier::get_ttcnname() const
1311 {
1312 return id_data->get_ttcnname();
1313 }
1314
1315 bool Identifier::get_has_valid(id_t p_id_t) const
1316 {
1317 return id_data->get_has_valid(p_id_t);
1318 }
1319
1320 string Identifier::get_names() const
1321 {
1322 return id_data->get_names();
1323 }
1324
1325 bool Identifier::isvalid_asn_modref() const
1326 {
1327 return id_data->isvalid_asn_modref();
1328 }
1329
1330 bool Identifier::isvalid_asn_typeref() const
1331 {
1332 return id_data->isvalid_asn_typeref();
1333 }
1334
1335 bool Identifier::isvalid_asn_valref() const
1336 {
1337 return id_data->isvalid_asn_valref();
1338 }
1339
1340 bool Identifier::isvalid_asn_valsetref() const
1341 {
1342 return id_data->isvalid_asn_valsetref();
1343 }
1344
1345 bool Identifier::isvalid_asn_objclassref() const
1346 {
1347 return id_data->isvalid_asn_objclassref();
1348 }
1349
1350 bool Identifier::isvalid_asn_objref() const
1351 {
1352 return id_data->isvalid_asn_objref();
1353 }
1354
1355 bool Identifier::isvalid_asn_objsetref() const
1356 {
1357 return id_data->isvalid_asn_objsetref();
1358 }
1359
1360 bool Identifier::isvalid_asn_typefieldref() const
1361 {
1362 return id_data->isvalid_asn_typefieldref();
1363 }
1364
1365 bool Identifier::isvalid_asn_valfieldref() const
1366 {
1367 return id_data->isvalid_asn_valfieldref();
1368 }
1369
1370 bool Identifier::isvalid_asn_valsetfieldref() const
1371 {
1372 return id_data->isvalid_asn_valsetfieldref();
1373 }
1374
1375 bool Identifier::isvalid_asn_objfieldref() const
1376 {
1377 return id_data->isvalid_asn_objfieldref();
1378 }
1379
1380 bool Identifier::isvalid_asn_objsetfieldref() const
1381 {
1382 return id_data->isvalid_asn_objsetfieldref();
1383 }
1384
1385 bool Identifier::isvalid_asn_word() const
1386 {
1387 return id_data->isvalid_asn_word();
1388 }
1389
1390 void Identifier::dump(unsigned level) const
1391 {
1392 DEBUG(level, "Identifier: %s", id_data->get_names().c_str());
1393 }
1394
1395 const Identifier underscore_zero(Identifier::ID_TTCN, string("_0"));
1396
1397 } // namespace Common
This page took 0.062846 seconds and 5 git commands to generate.