implemented decmatch (artf724241)
[deliverable/titan.core.git] / compiler2 / Identifier.cc
CommitLineData
d44e3c4f 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
7 *
8 * Contributors:
9 * Baji, Laszlo
10 * Balasko, Jeno
11 * Delic, Adam
12 * Feher, Csaba
13 * Forstner, Matyas
14 * Kovacs, Ferenc
15 * Raduly, Csaba
16 * Szabados, Kristof
17 * Szabo, Janos Zoltan – initial implementation
18 *
19 ******************************************************************************/
970ed795
EL
20#include "../common/dbgnew.hh"
21#include "Identifier.hh"
22#include <ctype.h>
23#include "Setting.hh"
24#include "CompilerError.hh"
25
26namespace Common {
27
28 // =================================
29 // ===== Identifier::id_data_t
30 // =================================
31
32 struct Identifier::id_data_t {
33 size_t ref_count;
34 string name, asnname, ttcnname;
35 /** ASN kind of the identifier. */
36 enum asn_kind_t {
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} */
44 } asn_kind;
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();
86 private:
87 ~id_data_t() {}
88 void decide_asn_kind();
89 };
90
91 // =================================
92 // ===== internal_data_t
93 // =================================
94
95 class internal_data_t {
96 private:
97 static internal_data_t *instance;
98 static const char* const keywords[][3];
99 size_t identifier_counter;
100 public:
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;
108 private:
109 internal_data_t();
110 internal_data_t(const internal_data_t&);
111 ~internal_data_t();
112 void add_keyword(const char* const keyword[3]);
113 void add_keywords();
114 public:
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
118 * constructor. */
119 void increase_counter();
120 /** Decreases the instance counter. Finalizes the keywords if this
121 * is the last instance. Must be called in Identifier
122 * destructor. */
123 void decrease_counter();
124 };
125
126 // ======================================================================
127 // ======================================================================
128
129 // =================================
130 // ===== Identifier::id_data_t
131 // =================================
132
133 void Identifier::id_data_t::asn_2_name(string& p_to, const string& p_from)
134 {
135 p_to = 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" */
139 size_t pos = 0;
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, "");
143 else break;
144 }
145 /* "-" -> "__" */
146 pos = 0;
147 while ((pos = p_to.find('-', pos)) < p_to.size()) {
148 p_to.replace(pos, 1, "__");
149 pos += 2;
150 }
151 /* "." -> "_" */
152 pos = 0;
153 while ((pos = p_to.find('.', pos)) < p_to.size()) {
154 p_to[pos] = '_';
155 pos++;
156 }
157 /* "&" -> "" */
158 pos = 0;
159 while ((pos = p_to.find('&', pos)) < p_to.size())
160 p_to.replace(pos, 1, "");
161 }
162
163 void Identifier::id_data_t::name_2_asn(string& p_to, const string& p_from)
164 {
165 p_to = p_from;
166 /* remove leading '_'s */
167 size_t pos = 0;
168 while (pos < p_to.size() && p_to[pos] == '_') pos++;
169 if (pos > 0) p_to.replace(0, pos, "");
170 /* remove trailing '_'s */
171 pos = p_to.size();
172 while (pos > 0 && p_to[pos - 1] == '_') pos--;
173 if (pos < p_to.size()) p_to.resize(pos);
174 /* "__" -> "-" */
175 pos = 0;
176 while ((pos = p_to.find("__", pos)) < p_to.size()) {
177 p_to.replace(pos, 2, "-");
178 pos++;
179 }
180 /* "_" -> "-" */
181 pos = 0;
182 while ((pos = p_to.find('_', pos)) < p_to.size()) {
183 p_to[pos] = '-';
184 pos++;
185 }
186 }
187
188 void Identifier::id_data_t::ttcn_2_name(string& p_to, const string& p_from)
189 {
190 p_to = p_from;
191 /* "_" -> "__" */
192 size_t pos = 0;
193 while ((pos = p_to.find('_', pos)) < p_to.size()) {
194 p_to.replace(pos, 1, "__");
195 pos += 2;
196 }
197 }
198
199 void Identifier::id_data_t::name_2_ttcn(string& p_to, const string& p_from)
200 {
201 p_to = p_from;
202 /* remove leading '_'s */
203 size_t pos = 0;
204 while (pos < p_to.size() && p_to[pos] == '_') pos++;
205 if (pos > 0) p_to.replace(0, pos, "");
206 /* remove trailing '_'s */
207 pos = p_to.size();
208 while (pos > 0 && p_to[pos - 1] == '_') pos--;
209 if (pos < p_to.size()) p_to.resize(pos);
210 /* "__" -> "_" */
211 pos = 0;
212 while ((pos = p_to.find("__", pos)) < p_to.size()) {
213 p_to.replace(pos, 1, "");
214 pos++;
215 }
216 }
217
218 const string& Identifier::id_data_t::get_asnname()
219 {
220 if (asnname.empty()) name_2_asn(asnname, name);
221 return asnname;
222 }
223
224 const string& Identifier::id_data_t::get_ttcnname()
225 {
226 if (ttcnname.empty()) name_2_ttcn(ttcnname, name);
227 return ttcnname;
228 }
229
230 bool Identifier::id_data_t::get_has_valid(id_t p_id_t)
231 {
232 const string& inval=internal_data_t::Instance()->string_invalid;
233 switch(p_id_t) {
234 case ID_NAME:
235 return get_name()!=inval;
236 case ID_ASN:
237 return get_asnname()!=inval;
238 case ID_TTCN:
239 return get_ttcnname()!=inval;
240 default:
241 FATAL_ERROR("Identifier::id_data_t::get_has_valid()");
242 return false;
243 }
244 }
245
246 void Identifier::id_data_t::delete_this(id_data_t *p_id_data_t)
247 {
248 p_id_data_t->ref_count--;
249 if(p_id_data_t->ref_count==0)
250 delete p_id_data_t;
251 }
252
253 string Identifier::id_data_t::get_names() const
254 {
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+"'";
261 s+=")";
262 return s;
263 }
264
265 void Identifier::id_data_t::decide_asn_kind()
266 {
267 if(asn_kind!=ASN_UNDEF) return;
268 get_asnname();
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;
276 }
277 }
278 else if(islower(asnname[0])) {
279 asn_kind=ASN_LOWER;
280 }
281 else if(isupper(asnname[0])) {
282 asn_kind=ASN_UPPER;
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()) {
286 asn_kind=ASN_WORD;
287 }
288 }
289 }
290 }
291
292 bool Identifier::id_data_t::isvalid_asn_modref()
293 {
294 return isvalid_asn_typeref();
295 }
296
297 bool Identifier::id_data_t::isvalid_asn_typeref()
298 {
299 decide_asn_kind();
300 return (asn_kind==ASN_UPPER
301 || asn_kind==ASN_ALLUPPER
302 || asn_kind==ASN_WORD);
303 }
304
305 bool Identifier::id_data_t::isvalid_asn_valref()
306 {
307 decide_asn_kind();
308 return (asn_kind==ASN_LOWER);
309 }
310
311 bool Identifier::id_data_t::isvalid_asn_valsetref()
312 {
313 return isvalid_asn_typeref();
314 }
315
316 bool Identifier::id_data_t::isvalid_asn_objclassref()
317 {
318 decide_asn_kind();
319 return (asn_kind==ASN_ALLUPPER
320 || asn_kind==ASN_WORD);
321 }
322
323 bool Identifier::id_data_t::isvalid_asn_objref()
324 {
325 decide_asn_kind();
326 return (asn_kind==ASN_LOWER);
327 }
328
329 bool Identifier::id_data_t::isvalid_asn_objsetref()
330 {
331 return isvalid_asn_typeref();
332 }
333
334 bool Identifier::id_data_t::isvalid_asn_typefieldref()
335 {
336 decide_asn_kind();
337 return (asn_kind==ASN_ampUPPER);
338 }
339
340 bool Identifier::id_data_t::isvalid_asn_valfieldref()
341 {
342 decide_asn_kind();
343 return (asn_kind==ASN_ampLOWER);
344 }
345
346 bool Identifier::id_data_t::isvalid_asn_valsetfieldref()
347 {
348 decide_asn_kind();
349 return (asn_kind==ASN_ampUPPER);
350 }
351
352 bool Identifier::id_data_t::isvalid_asn_objfieldref()
353 {
354 decide_asn_kind();
355 return (asn_kind==ASN_ampLOWER);
356 }
357
358 bool Identifier::id_data_t::isvalid_asn_objsetfieldref()
359 {
360 decide_asn_kind();
361 return (asn_kind==ASN_ampUPPER);
362 }
363
364 bool Identifier::id_data_t::isvalid_asn_word()
365 {
366 decide_asn_kind();
367 return (asn_kind==ASN_WORD);
368 }
369
370 // =================================
371 // ===== internal_data_t
372 // =================================
373
374 internal_data_t *internal_data_t::instance=0;
375
376 /* format: c++ - asn - ttcn */
377 const char* const internal_data_t::keywords[][3] = {
378 /* C++ keywords - never can be used */
379 {"and", 0, 0},
380 {"and_eq", 0, 0},
381 {"asm", 0, 0},
382 {"auto", 0, 0},
383 {"bitand", 0, 0},
384 {"bitor", 0, 0},
385 {"bool", 0, 0},
386 {"break", 0, 0},
387 {"case", 0, 0},
388 {"catch", 0, 0},
389 {"char", 0, 0},
390 {"class", 0, 0},
391 {"compl", 0, 0},
392 {"const", 0, 0},
393 {"const_cast", 0, 0},
394 {"continue", 0, 0},
395 {"default", 0, 0},
396 {"delete", 0, 0},
397 {"do", 0, 0},
398 {"double", 0, 0},
399 {"dynamic_cast", 0, 0},
400 {"else", 0, 0},
401 {"enum", 0, 0},
402 {"explicit", 0, 0},
403 {"export", 0, 0},
404 {"extern", 0, 0},
405 {"false", 0, 0},
406 {"float", 0, 0},
407 {"for", 0, 0},
408 {"friend", 0, 0},
409 {"goto", 0, 0},
410 {"if", 0, 0},
411 {"inline", 0, 0},
412 {"int", 0, 0},
413 {"long", 0, 0},
414 {"mutable", 0, 0},
415 {"namespace", 0, 0},
416 {"new", 0, 0},
417 {"not", 0, 0},
418 {"not_eq", 0, 0},
419 {"operator", 0, 0},
420 {"or", 0, 0},
421 {"or_eq", 0, 0},
422 {"private", 0, 0},
423 {"protected", 0, 0},
424 {"public", 0, 0},
425 {"register", 0, 0},
426 {"reinterpret_cast", 0, 0},
427 {"return", 0, 0},
428 {"short", 0, 0},
429 {"signed", 0, 0},
430 {"sizeof", 0, 0},
431 {"static", 0, 0},
432 {"static_cast", 0, 0},
433 {"struct", 0, 0},
434 {"switch", 0, 0},
435 {"template", 0, 0},
436 {"this", 0, 0},
437 {"throw", 0, 0},
438 {"true", 0, 0},
439 {"try", 0, 0},
440 {"typedef", 0, 0},
441 {"typeid", 0, 0},
442 {"typename", 0, 0},
443 {"union", 0, 0},
444 {"unsigned", 0, 0},
445 {"using", 0, 0},
446 {"virtual", 0, 0},
447 {"void", 0, 0},
448 {"volatile", 0, 0},
449 {"wchar_t", 0, 0},
450 {"while", 0, 0},
451 {"xor", 0, 0},
452 {"xor_eq", 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 */
521 {"CHAR", 0, 0},
522 {"ERROR", 0, 0},
523 {"FAIL", 0, 0},
524 {"INCONC", 0, 0},
525 {"FALSE", 0, 0},
526 {"NONE", 0, 0},
527 {"OPTIONAL", 0, 0},
528 {"PASS", 0, 0},
529 {"PORT", 0, 0},
530 {"TIMER", 0, 0},
531 {"TRUE", 0, 0},
532 {"bit2hex", 0, 0},
533 {"bit2int", 0, 0},
534 {"bit2oct", 0, 0},
535 {"bit2str", 0, 0},
536 {"boolean", 0, 0},
537 {"char2int", 0, 0},
538 {"char2oct", 0, 0},
539 {"component", 0, 0},
540 {"decomp", 0, 0},
541 {"float2int", 0, 0},
542 {"float2str", 0, 0},
543 {"hex2bit", 0, 0},
544 {"hex2int", 0, 0},
545 {"hex2oct", 0, 0},
546 {"hex2str", 0, 0},
547 {"int2bit", 0, 0},
548 {"int2char", 0, 0},
549 {"int2float", 0, 0},
550 {"int2hex", 0, 0},
551 {"int2oct", 0, 0},
552 {"int2str", 0, 0},
553 {"int2unichar", 0, 0},
554 {"ischosen", 0, 0},
555 {"ispresent", 0, 0},
556 {"isvalue", 0, 0},
557 {"lengthof", 0, 0},
558 {"log", 0, 0},
559 {"log2str", 0, 0},
560 {"main", 0, 0},
561 {"match", 0, 0},
562 {"mod", 0, 0},
563 {"oct2bit", 0, 0},
564 {"oct2char", 0, 0},
565 {"oct2hex", 0, 0},
566 {"oct2int", 0, 0},
567 {"oct2str", 0, 0},
568 {"regexp", 0, 0},
569 {"replace", 0, 0},
570 {"rem", 0, 0},
571 {"rnd", 0, 0},
572 {"self", 0, 0},
573 {"stderr", 0, 0}, // temporary hack
574 {"stdin", 0, 0}, // temporary hack
575 {"stdout", 0, 0}, // temporary hack
576 {"str2bit", 0, 0},
577 {"str2float", 0, 0},
578 {"str2hex", 0, 0},
579 {"str2int", 0, 0},
580 {"str2oct", 0, 0},
581 {"substr", 0, 0},
582 {"unichar2int", 0, 0},
583 {"unichar2char", 0, 0},
584 {"valueof", 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_"},
28352dbd 601 {"decmatch__", "decmatch", "decmatch_"},
970ed795
EL
602 {"decomp__", "decomp", "decomp_"},
603 {"float2int__", "float2int", "float2int_"},
604 {"float2str__", "float2str", "float2str_"},
605 {"hex2bit__", "hex2bit", "hex2bit_"},
606 {"hex2int__", "hex2int", "hex2int_"},
607 {"hex2oct__", "hex2oct", "hex2oct_"},
608 {"hex2str__", "hex2str", "hex2str_"},
609 {"int2bit__", "int2bit", "int2bit_"},
610 {"int2char__", "int2char", "int2char_"},
611 {"int2float__", "int2float", "int2float_"},
612 {"int2hex__", "int2hex", "int2hex_"},
613 {"int2oct__", "int2oct", "int2oct_"},
614 {"int2str__", "int2str", "int2str_"},
615 {"int2unichar__", "int2unichar", "int2unichar_"},
616 {"ischosen__", "ischosen", "ischosen_"},
617 {"ispresent__", "ispresent", "ispresent_"},
618 {"isvalue__", "isvalue", "isvalue_"},
619 {"lengthof__", "lengthof", "lengthof_"},
620 {"log__", "log", "log_"},
621 {"log2str__", "log2str", "log2str_"},
622 {"match__", "match", "match_"},
623 {"mod__", "mod", "mod_"},
624 {"oct2bit__", "oct2bit", "oct2bit_"},
625 {"oct2char__", "oct2char", "oct2char_"},
626 {"oct2hex__", "oct2hex", "oct2hex_"},
627 {"oct2int__", "oct2int", "oct2int_"},
628 {"oct2str__", "oct2str", "oct2str_"},
629 {"regexp__", "regexp", "regexp_"},
630 {"replace__", "replace", "replace_"},
631 {"rem__", "rem", "rem_"},
632 {"rnd__", "rnd", "rnd_"},
633 {"self__", "self", "self_"},
634 {"str2bit__", "str2bit", "str2bit_"},
635 {"str2float__", "str2float", "str2float_"},
636 {"str2hex__", "str2hex", "str2hex_"},
637 {"str2int__", "str2int", "str2int_"},
638 {"str2oct__", "str2oct", "str2oct_"},
639 {"substr__", "substr", "substr_"},
640 {"unichar2int__", "unichar2int", "unichar2int_"},
641 {"unichar2char__", "unichar2char", "unichar2char_"},
642 {"valueof__", "valueof", "valueof_"},
643 {"verdicttype__", "verdicttype", "verdicttype_"},
644 {"ttcn2string__", "ttcn2string", "ttcn2string_"},
645 {"string2ttcn__", "string2ttcn", "string2ttcn_"},
646 {"unichar2oct__", "unichar2oct", "unichar2oct_"},
647 {"oct2unichar__", "oct2unichar", "oct2unichar_"},
648 {"remove__bom__", "remove_bom", "remove_bom_"},
649 {"encode__base64__", "encode_base64", "encode_base64_"},
650 {"decode__base64__", "decode_base64", "decode_base64_"},
651 {"get__stringencoding__", "get_stringencoding", "get_stringencoding_"},
652 /* reserved names of base library - keywords in ASN.1 */
653 {"FALSE_", 0, "FALSE"},
654 {"OPTIONAL_", 0, "OPTIONAL"},
655 {"TRUE_", 0, "TRUE"},
656 /* reserved names of base library - not keywords */
657 {"CHAR_", "CHAR", "CHAR"},
658 {"ERROR_", "ERROR", "ERROR"},
659 {"FAIL_", "FAIL", "FAIL"},
660 {"INCONC_", "INCONC", "INCONC"},
661 {"NONE_", "NONE", "NONE"},
662 {"PASS_", "PASS", "PASS"},
663 {"PORT_", "PORT", "PORT"},
664 {"TIMER_", "TIMER", "TIMER"},
665 {"main_", "main", "main"},
666 {"stderr_", "stderr", "stderr"}, // temporary hack
667 {"stdin_", "stdin", "stdin"}, // temporary hack
668 {"stdout_", "stdout", "stdout"}, // temporary hack
669 {"TTCN3_", "TTCN3", "TTCN3"},
670 /* built-in types. this is the ASN/TTCN -> C++ name mapping */
671 {"ADDRESS", 0, "address"},
672 {"ASN_NULL", "NULL", 0},
673 {"BITSTRING", "BIT STRING", "bitstring"},
674 {"BOOLEAN", "BOOLEAN", "boolean"},
675 {"BMPString", "BMPString", 0},
676 {"CHARSTRING", 0, "charstring"},
677 {"CHARACTER_STRING", "CHARACTER STRING", 0},
678 {"COMPONENT", 0, "component"},
679 {"DEFAULT", 0, "default"},
680 {"EMBEDDED_PDV", "EMBEDDED PDV", 0},
681 {"EXTERNAL", "EXTERNAL", 0},
682 {"FLOAT", "REAL", "float"},
683 {"GraphicString", "GraphicString", 0},
684 {"HEXSTRING", 0, "hexstring"},
685 {"IA5String", "IA5String", 0},
686 {"INTEGER", "INTEGER", "integer"},
687 {"ISO646String", "ISO646String", 0},
688 {"NumericString", "NumericString", 0},
689 {"OBJID", "OBJECT IDENTIFIER", "objid"},
690 {"OCTETSTRING", "OCTET STRING", "octetstring"},
691 {"ObjectDescriptor", "ObjectDescriptor", 0},
692 {"PrintableString", "PrintableString", 0},
693 {"T61String", "T61String", 0},
694 {"TeletexString", "TeletexString", 0},
695 {"UTF8String", "UTF8String", 0},
696 {"UniversalString", "UniversalString", 0},
697 {"UNIVERSAL_CHARSTRING", 0, "universal charstring"},
698 {"VERDICTTYPE", 0, "verdicttype"},
699 {"VideotexString", "VideotexString", 0},
700 {"VisibleString", "VisibleString", 0},
701 /* reserved names of built-in types - valid ASN.1/TTCN names */
702 {"ADDRESS_", "ADDRESS", "ADDRESS"},
703 {"BITSTRING_", "BITSTRING", "BITSTRING"},
704 {"BOOLEAN_", 0, "BOOLEAN"},
705 {"BMPString_", 0, "BMPString"},
706 {"CHARSTRING_", "CHARSTRING", "CHARSTRING"},
707 {"COMPONENT_", "COMPONENT", "COMPONENT"},
708 {"DEFAULT_", 0, "DEFAULT"},
709 {"EXTERNAL_", 0, "EXTERNAL"},
710 {"FLOAT_", "FLOAT", "FLOAT"},
711 {"GraphicString_", 0, "GraphicString"},
712 {"HEXSTRING_", "HEXSTRING", "HEXSTRING"},
713 {"IA5String_", 0, "IA5String"},
714 {"INTEGER_", 0, "INTEGER"},
715 {"ISO646String_", 0, "ISO646String"},
716 {"NumericString_", 0, "NumericString"},
717 {"OBJID_", "OBJID", "OBJID"},
718 {"OCTETSTRING_", "OCTETSTRING", "OCTETSTRING"},
719 {"ObjectDescriptor_", 0, "ObjectDescriptor"},
720 {"PrintableString_", 0, "PrintableString"},
721 {"T61String_", 0, "T61String"},
722 {"TeletexString_", 0, "TeletexString"},
723 {"UTF8String_", 0, "UTF8String"},
724 {"UniversalString_", 0, "UniversalString"},
725 {"VERDICTTYPE_", "VERDICTTYPE", "VERDICTTYPE"},
726 {"VideotexString_", 0, "VideotexString"},
727 {"VisibleString_", 0, "VisibleString"},
728 /* keywords in TTCN-3, not reserved words in C++, postfixed in TTCN */
729 {"action__", "action", "action_"},
730 {"activate__", "activate", "activate_"},
731 {"address__", "address", "address_"},
732 {"alive__", "alive", "alive_"},
733 {"all__", "all", "all_"},
734 {"alt__", "alt", "alt_"},
735 {"altstep__", "altstep", "altstep_"},
736 {"and4b__", "and4b", "and4b_"},
737 {"any__", "any", "any_"},
738 {"anytype__", "anytype", "anytype_"},
739 {"apply__", "apply", "apply_"},
740 {"bitstring__", "bitstring", "bitstring_"},
741 {"call__", "call", "call_"},
742 {"charstring__", "charstring", "charstring_"},
743 {"check__", "check", "check_"},
744 {"clear__", "clear", "clear_"},
745 {"complement__", "complement", "complement_"},
746 {"connect__", "connect", "connect_"},
747 {"control__", "control", "control_"},
748 {"create__", "create", "create_"},
749 {"deactivate__", "deactivate", "deactivate_"},
750 {"derefers__", "derefers", "derefers_"},
751 {"disconnect__", "disconnect", "disconnect_"},
752 {"display__", "display", "display_"},
753 {"done__", "done", "done_"},
754 {"encode__", "encode", "encode_"},
755 {"enumerated__", "enumerated", "enumerated_"},
756 {"error__", "error", "error_"},
757 {"except__", "except", "except_"},
758 {"exception__", "exception", "exception_"},
759 {"execute__", "execute", "execute_"},
760 {"extends__", "extends", "extends_"},
761 {"extension__", "extension", "extension_"},
762 {"external__", "external", "external_"},
763 {"fail__", "fail", "fail_"},
764 {"from__", "from", "from_"},
765 {"function__", "function", "function_"},
766 {"getcall__", "getcall", "getcall_"},
767 {"getreply__", "getreply", "getreply_"},
768 {"getverdict__", "getverdict", "getverdict_"},
769 {"group__", "group", "group_"},
770 {"halt__", "halt", "halt_"},
771 {"hexstring__", "hexstring", "hexstring_"},
772 {"ifpresent__", "ifpresent", "ifpresent_"},
773 {"import__", "import", "import_"},
774 {"in__", "in", "in_"},
775 {"inconc__", "inconc", "inconc_"},
776 {"infinity__", "infinity", "infinity_"},
777 {"inout__", "inout", "inout_"},
778 {"integer__", "integer", "integer_"},
779 {"interleave__", "interleave", "interleave_"},
780 {"kill__", "kill", "kill_"},
781 {"killed__", "killed", "killed_"},
782 {"label__", "label", "label_"},
783 {"language__", "language", "language_"},
784 {"length__", "length", "length_"},
785 {"map__", "map", "map_"},
786 {"message__", "message", "message_"},
787 {"mixed__", "mixed", "mixed_"},
788 {"modifies__", "modifies", "modifies_"},
789 {"module__", "module", "module_"},
790 {"modulepar__", "modulepar", "modulepar_"},
791 {"mtc__", "mtc", "mtc_"},
792 {"noblock__", "noblock", "noblock_"},
793 {"none__", "none", "none_"},
794 {"not4b__", "not4b", "not4b_"},
795 {"nowait__", "nowait", "nowait_"},
796 {"null__", "null", "null_"},
797 {"objid__", "objid", "objid_"},
798 {"octetstring__", "octetstring", "octetstring_"},
799 {"of__", "of", "of_"},
800 {"omit__", "omit", "omit_"},
801 {"on__", "on", "on_"},
802 {"optional__", "optional", "optional_"},
803 {"or4b__", "or4b", "or4b_"},
804 {"out__", "out", "out_"},
805 {"override__", "override", "override_"},
806 {"param__", "param", "param_"},
807 {"pass__", "pass", "pass_"},
808 {"pattern__", "pattern", "pattern_"},
809 {"permutation__", "permutation", "permutation_"},
810 {"port__", "port", "port_"},
811 {"procedure__", "procedure", "procedure_"},
812 {"raise__", "raise", "raise_"},
813 {"read__", "read", "read_"},
814 {"receive__", "receive", "receive_"},
815 {"record__", "record", "record_"},
816 {"recursive__", "recursive", "recursive_"},
817 {"refers__", "refers", "refers_"},
818 {"repeat__", "repeat", "repeat_"},
819 {"reply__", "reply", "reply_"},
820 {"running__", "running", "running_"},
821 {"runs__", "runs", "runs_"},
822 {"select__", "select", "select_"},
823 {"send__", "send", "send_"},
824 {"sender__", "sender", "sender_"},
825 {"set__", "set", "set_"},
826 {"setverdict__", "setverdict", "setverdict_"},
827 {"signature__", "signature", "signature_"},
828 {"start__", "start", "start_"},
829 {"stop__", "stop", "stop_"},
830 {"subset__", "subset", "subset_"},
831 {"superset__", "superset", "superset_"},
832 {"system__", "system", "system_"},
833 {"testcase__", "testcase", "testcase_"},
834 {"timeout__", "timeout", "timeout_"},
835 {"timer__", "timer", "timer_"},
836 {"to__", "to", "to_"},
837 {"trigger__", "trigger", "trigger_"},
838 {"type__", "type", "type_"},
839 {"universal__", "universal", "universal_"},
840 {"unmap__", "unmap", "unmap_"},
841 {"value__", "value", "value_"},
842 {"present__", "present", "present_"},
843 {"var__", "var", "var_"},
844 {"variant__", "variant", "variant_"},
845 {"with__", "with", "with_"},
846 {"xor4b__", "xor4b", "xor4b_"},
847 /* other names that need to be mapped in a non-uniform manner */
848 /* major and minor are macros on some platforms; avoid generating
849 * a potentially troublesome C++ identifier */
850 {"major_", "major", "major"},
851 {"minor_", "minor", "minor"},
852 /* internal / error */
853 {"<error>", "<error>", "<error>"},
854 {"TTCN_internal_", "<internal>", "<internal>"},
855 /* the last must be all zeros */
856 {0, 0, 0}
857 }; // keywords
858
859 internal_data_t::internal_data_t()
860 : identifier_counter(0), string_invalid("<invalid>"), id_map_name(),
861 id_map_asn(), id_map_ttcn()
862 {
863 }
864
865 internal_data_t::~internal_data_t()
866 {
867 for(size_t i=0; i<id_map_name.size(); i++)
868 Identifier::id_data_t::delete_this(id_map_name.get_nth_elem(i));
869 id_map_name.clear();
870 for(size_t i=0; i<id_map_asn.size(); i++)
871 Identifier::id_data_t::delete_this(id_map_asn.get_nth_elem(i));
872 id_map_asn.clear();
873 for(size_t i=0; i<id_map_ttcn.size(); i++)
874 Identifier::id_data_t::delete_this(id_map_ttcn.get_nth_elem(i));
875 id_map_ttcn.clear();
876 }
877
878 void internal_data_t::add_keyword(const char* const keyword[3])
879 {
880 Identifier::id_data_t *id_data
881 =new Identifier::id_data_t(string(keyword[0]));
882 bool conflict=false;
883 // Pointers to already added (conflicting) keyword
884 const Identifier::id_data_t *id_data_name=0;
885 const Identifier::id_data_t *id_data_asn=0;
886 const Identifier::id_data_t *id_data_ttcn=0;
887 if(id_map_name.has_key(id_data->name)) {
888 conflict=true;
889 id_data_name=id_map_name[id_data->name];
890 }
891 else {
892 id_map_name.add(id_data->name, id_data);
893 id_data->ref_count++;
894 }
895
896 if(keyword[1]==0) {
897 id_data->asnname=string_invalid;
898 }
899 else {
900 // copy the string if possible to avoid memory allocation
901 if (id_data->name == keyword[1]) id_data->asnname = id_data->name;
902 else id_data->asnname = keyword[1];
903 if(id_map_asn.has_key(id_data->asnname)) {
904 conflict=true;
905 id_data_asn=id_map_asn[id_data->asnname];
906 }
907 else {
908 id_map_asn.add(id_data->asnname, id_data);
909 id_data->ref_count++;
910 }
911 }
912
913 if(keyword[2]==0) {
914 id_data->ttcnname=string_invalid;
915 }
916 else {
917 // copy the string if possible to avoid memory allocation
918 if (id_data->name == keyword[2]) id_data->ttcnname = id_data->name;
919 else if (id_data->asnname == keyword[2])
920 id_data->ttcnname = id_data->asnname;
921 else id_data->ttcnname = keyword[2];
922 if(id_map_ttcn.has_key(id_data->ttcnname)) {
923 conflict=true;
924 id_data_ttcn=id_map_ttcn[id_data->ttcnname];
925 }
926 else {
927 id_map_ttcn.add(id_data->ttcnname, id_data);
928 id_data->ref_count++;
929 }
930 }
931
932 if(conflict) {
933 Location loc;
934 loc.error
935 ("This pre-defined identifier: %s",
936 id_data->get_names().c_str());
937 loc.error
938 ("conflicts with previous:");
939 if(id_data_name)
940 loc.error
941 ("[C++:] %s",
942 id_data_name->get_names().c_str());
943 if(id_data_asn)
944 loc.error
945 ("[ASN:] %s",
946 id_data_asn->get_names().c_str());
947 if(id_data_ttcn)
948 loc.error
949 ("[TTCN:] %s",
950 id_data_ttcn->get_names().c_str());
951 } // if conflict
952 Identifier::id_data_t::delete_this(id_data);
953 }
954
955 void internal_data_t::add_keywords()
956 {
957 {
958 Location loc;
959 Error_Context cntx(&loc, "While adding keywords");
960 for(size_t i=0; keywords[i][0]; i++)
961 add_keyword(keywords[i]);
962 }
963 /* Perhaps it were good to read a file which contains
964 user-defined mappings :) */
965 }
966
967 internal_data_t *internal_data_t::Instance()
968 {
969 if(!instance) {
970 instance=new internal_data_t();
971 instance->add_keywords();
972 }
973 return instance;
974 }
975
976 void internal_data_t::increase_counter()
977 {
978 identifier_counter++;
979 }
980
981 void internal_data_t::decrease_counter()
982 {
983 identifier_counter--;
984 if(identifier_counter==0) {
985 delete instance;
986 instance=0;
987 } // if last Identifier instance
988 }
989
990 // =================================
991 // ===== Identifier
992 // =================================
993
994 bool Identifier::is_reserved_word(const string& p_name, id_t p_id_t)
995 {
996 if (p_name.empty())
997 FATAL_ERROR("Identifier::is_reserved_word(): empty name");
998 internal_data_t *d = internal_data_t::Instance();
999 switch (p_id_t) {
1000 case ID_NAME:
1001 if (d->id_map_name.has_key(p_name)) {
1002 id_data_t *id_data_p = d->id_map_name[p_name];
1003 if (id_data_p->asnname == d->string_invalid &&
1004 id_data_p->ttcnname == d->string_invalid) return true;
1005 else return false;
1006 } else return false;
1007 case ID_ASN:
1008 if (p_name[0] == '&' || d->id_map_asn.has_key(p_name)) return false;
1009 else {
1010 string name;
1011 id_data_t::asn_2_name(name, p_name);
1012 if (d->id_map_name.has_key(name)) {
1013 id_data_t *id_data_p = d->id_map_name[name];
1014 if (id_data_p->asnname.empty()) {
1015 id_data_p->asnname = p_name;
1016 d->id_map_asn.add(p_name, id_data_p);
1017 id_data_p->ref_count++;
1018 return false;
1019 } else if (id_data_p->asnname == p_name) return false;
1020 else return true;
1021 } else return false;
1022 }
1023 case ID_TTCN:
1024 if (d->id_map_ttcn.has_key(p_name)) return false;
1025 else {
1026 string name;
1027 id_data_t::ttcn_2_name(name, p_name);
1028 if (d->id_map_name.has_key(name)) {
1029 id_data_t *id_data_p = d->id_map_name[name];
1030 if (id_data_p->ttcnname.empty()) {
1031 id_data_p->ttcnname = p_name;
1032 d->id_map_ttcn.add(p_name, id_data_p);
1033 id_data_p->ref_count++;
1034 return false;
1035 } else if (id_data_p->ttcnname == p_name) return false;
1036 else return true;
1037 } else return false;
1038 }
1039 default:
1040 FATAL_ERROR("Identifier::is_reserved_word(): invalid language");
1041 return false;
1042 }
1043 }
1044
1045 string Identifier::asn_2_name(const string& p_name)
1046 {
1047 internal_data_t *d = internal_data_t::Instance();
1048 if (d->id_map_asn.has_key(p_name)) {
1049 id_data_t *id_data_p = d->id_map_asn[p_name];
1050 if (id_data_p->name.empty()) {
1051 id_data_t::asn_2_name(id_data_p->name, p_name);
1052 d->id_map_name.add(id_data_p->name, id_data_p);
1053 id_data_p->ref_count++;
1054 }
1055 return id_data_p->name;
1056 } else {
1057 string name;
1058 id_data_t::asn_2_name(name, p_name);
1059 if (d->id_map_name.has_key(name)) {
1060 id_data_t *id_data_p = d->id_map_name[name];
1061 if (id_data_p->asnname.empty()) {
1062 id_data_p->asnname = p_name;
1063 d->id_map_asn.add(p_name, id_data_p);
1064 id_data_p->ref_count++;
1065 }
1066 }
1067 return name;
1068 }
1069 }
1070
1071 string Identifier::name_2_asn(const string& p_name)
1072 {
1073 internal_data_t *d = internal_data_t::Instance();
1074 if (d->id_map_name.has_key(p_name)) {
1075 id_data_t *id_data_p = d->id_map_name[p_name];
1076 if (id_data_p->asnname.empty()) {
1077 id_data_t::name_2_asn(id_data_p->asnname, p_name);
1078 d->id_map_asn.add(id_data_p->asnname, id_data_p);
1079 id_data_p->ref_count++;
1080 }
1081 return id_data_p->asnname;
1082 } else {
1083 string asnname;
1084 id_data_t::name_2_asn(asnname, p_name);
1085 if (d->id_map_asn.has_key(asnname)) {
1086 id_data_t *id_data_p = d->id_map_asn[asnname];
1087 if (id_data_p->name.empty()) {
1088 id_data_p->name = p_name;
1089 d->id_map_name.add(p_name, id_data_p);
1090 id_data_p->ref_count++;
1091 }
1092 }
1093 return asnname;
1094 }
1095 }
1096
1097 string Identifier::ttcn_2_name(const string& p_name)
1098 {
1099 internal_data_t *d = internal_data_t::Instance();
1100 if (d->id_map_ttcn.has_key(p_name)) {
1101 id_data_t *id_data_p = d->id_map_ttcn[p_name];
1102 if (id_data_p->name.empty()) {
1103 id_data_t::ttcn_2_name(id_data_p->name, p_name);
1104 d->id_map_name.add(id_data_p->name, id_data_p);
1105 id_data_p->ref_count++;
1106 }
1107 return id_data_p->name;
1108 } else {
1109 string name;
1110 id_data_t::ttcn_2_name(name, p_name);
1111 if (d->id_map_name.has_key(name)) {
1112 id_data_t *id_data_p = d->id_map_name[name];
1113 if (id_data_p->ttcnname.empty()) {
1114 id_data_p->ttcnname = p_name;
1115 d->id_map_ttcn.add(p_name, id_data_p);
1116 id_data_p->ref_count++;
1117 }
1118 }
1119 return name;
1120 }
1121 }
1122
1123 string Identifier::name_2_ttcn(const string& p_name)
1124 {
1125 internal_data_t *d = internal_data_t::Instance();
1126 if (d->id_map_name.has_key(p_name)) {
1127 id_data_t *id_data_p = d->id_map_name[p_name];
1128 if (id_data_p->ttcnname.empty()) {
1129 id_data_t::name_2_ttcn(id_data_p->ttcnname, p_name);
1130 d->id_map_ttcn.add(id_data_p->ttcnname, id_data_p);
1131 id_data_p->ref_count++;
1132 }
1133 return id_data_p->ttcnname;
1134 } else {
1135 string ttcnname;
1136 id_data_t::name_2_ttcn(ttcnname, p_name);
1137 if (d->id_map_ttcn.has_key(ttcnname)) {
1138 id_data_t *id_data_p = d->id_map_ttcn[ttcnname];
1139 if (id_data_p->name.empty()) {
1140 id_data_p->name = p_name;
1141 d->id_map_name.add(p_name, id_data_p);
1142 id_data_p->ref_count++;
1143 }
1144 }
1145 return ttcnname;
1146 }
1147 }
1148
1149 Identifier::Identifier(id_t p_id_t, const string& p_name, bool dontreg)
1150 : id_data(0), origin(p_id_t)
1151 {
1152 if (p_name.empty()) FATAL_ERROR("Identifier::Identifier(): empty name");
1153 internal_data_t *d=internal_data_t::Instance();
1154 d->increase_counter();
1155 switch(p_id_t) {
1156 case ID_NAME:
1157 if(d->id_map_name.has_key(p_name)) {
1158 id_data=d->id_map_name[p_name];
1159 id_data->ref_count++;
1160 }
1161 else {
1162 id_data=new id_data_t(p_name);
1163 if(!dontreg) {
1164 d->id_map_name.add(p_name, id_data);
1165 id_data->ref_count++;
1166 }
1167 }
1168 break;
1169 case ID_ASN:
1170 if(d->id_map_asn.has_key(p_name)) {
1171 id_data=d->id_map_asn[p_name];
1172 id_data->ref_count++;
1173 }
1174 else if(p_name[0]=='&') { // special amp-identifiers (&)
1175 string p_name2=p_name.substr(1);
1176 string name2;
1177 if(d->id_map_asn.has_key(p_name2))
1178 name2=d->id_map_asn[p_name2]->get_name();
1179 else
1180 id_data_t::asn_2_name(name2, p_name2);
1181 id_data=new id_data_t(name2);
1182 id_data->asnname=p_name;
1183 id_data->ttcnname=d->string_invalid;
1184 if(!dontreg) {
1185 d->id_map_asn.add(p_name, id_data);
1186 id_data->ref_count++;
1187 }
1188 /* this id_data should NOT be added to id_map_name. */
1189 } // if &identifier
1190 else {
1191 string name;
1192 id_data_t::asn_2_name(name, p_name);
1193 if(!dontreg && d->id_map_name.has_key(name)) {
1194 id_data=d->id_map_name[name];
1195 id_data->ref_count++;
1196 if(id_data->asnname.empty()) {
1197 id_data->asnname=p_name;
1198 if(!dontreg) {
1199 d->id_map_asn.add(p_name, id_data);
1200 id_data->ref_count++;
1201 }
1202 }
1203 else if(id_data->asnname!=p_name) {
1204 Location loc;
1205 loc.error
1206 ("The ASN identifier `%s' clashes with this id: %s",
1207 p_name.c_str(), id_data->get_names().c_str());
1208 }
1209 }
1210 else {
1211 id_data=new id_data_t(name);
1212 id_data->asnname=p_name;
1213 if(!dontreg) {
1214 d->id_map_name.add(name, id_data);
1215 d->id_map_asn.add(p_name, id_data);
1216 id_data->ref_count+=2;
1217 }
1218 }
1219 }
1220 break;
1221 case ID_TTCN:
1222 if(d->id_map_ttcn.has_key(p_name)) {
1223 id_data=d->id_map_ttcn[p_name];
1224 id_data->ref_count++;
1225 }
1226 else {
1227 string name;
1228 id_data_t::ttcn_2_name(name, p_name);
1229 if(!dontreg && d->id_map_name.has_key(name)) {
1230 id_data=d->id_map_name[name];
1231 id_data->ref_count++;
1232 if(id_data->ttcnname.empty()) {
1233 id_data->ttcnname=p_name;
1234 if(!dontreg) {
1235 d->id_map_ttcn.add(p_name, id_data);
1236 id_data->ref_count++;
1237 }
1238 }
1239 else if(id_data->ttcnname!=p_name) {
1240 Location loc;
1241 loc.error
1242 ("The TTCN identifier `%s' clashes with this id: %s",
1243 p_name.c_str(), id_data->get_names().c_str());
1244 }
1245 }
1246 else {
1247 id_data=new id_data_t(name);
1248 id_data->ttcnname=p_name;
1249 if(!dontreg) {
1250 d->id_map_name.add(name, id_data);
1251 d->id_map_ttcn.add(p_name, id_data);
1252 id_data->ref_count+=2;
1253 }
1254 }
1255 }
1256 break;
1257 default:
1258 FATAL_ERROR("Identifier::Identifier()");
1259 } // switch p_id_t
1260 }
1261
1262 Identifier::Identifier(const Identifier& p)
1263 : id_data(p.id_data), origin(p.origin)
1264 {
1265 internal_data_t::Instance()->increase_counter();
1266 id_data->ref_count++;
1267 }
1268
1269 Identifier::~Identifier()
1270 {
1271 id_data_t::delete_this(id_data);
1272 /* I don't want to free the id_data structs here. They will be
1273 deleted in decrease_counter() when the maps are destructed. */
1274 internal_data_t::Instance()->decrease_counter();
1275 }
1276
1277 Identifier& Identifier::operator=(const Identifier& p)
1278 {
1279 if(&p!=this) {
1280 id_data_t::delete_this(id_data);
1281 id_data=p.id_data;
1282 id_data->ref_count++;
1283 origin=p.origin;
1284 }
1285 return *this;
1286 }
1287
1288 bool Identifier::operator==(const Identifier& p) const
1289 {
1290 return id_data->name==p.id_data->name;
1291 }
1292
1293 bool Identifier::operator<(const Identifier& p) const
1294 {
1295 return id_data->name<p.id_data->name;
1296 }
1297
1298 const string& Identifier::get_name() const
1299 {
1300 return id_data->get_name();
1301 }
1302
1303 const string& Identifier::get_dispname() const
1304 {
1305 switch(origin) {
1306 case ID_NAME:
1307 return id_data->get_name();
1308 case ID_ASN:
1309 return id_data->get_asnname();
1310 case ID_TTCN:
1311 return id_data->get_ttcnname();
1312 default:
1313 FATAL_ERROR("Identifier::get_dispname()");
1314 return id_data->get_name();
1315 }
1316 }
1317
1318 const string& Identifier::get_asnname() const
1319 {
1320 return id_data->get_asnname();
1321 }
1322
1323 const string& Identifier::get_ttcnname() const
1324 {
1325 return id_data->get_ttcnname();
1326 }
1327
1328 bool Identifier::get_has_valid(id_t p_id_t) const
1329 {
1330 return id_data->get_has_valid(p_id_t);
1331 }
1332
1333 string Identifier::get_names() const
1334 {
1335 return id_data->get_names();
1336 }
1337
1338 bool Identifier::isvalid_asn_modref() const
1339 {
1340 return id_data->isvalid_asn_modref();
1341 }
1342
1343 bool Identifier::isvalid_asn_typeref() const
1344 {
1345 return id_data->isvalid_asn_typeref();
1346 }
1347
1348 bool Identifier::isvalid_asn_valref() const
1349 {
1350 return id_data->isvalid_asn_valref();
1351 }
1352
1353 bool Identifier::isvalid_asn_valsetref() const
1354 {
1355 return id_data->isvalid_asn_valsetref();
1356 }
1357
1358 bool Identifier::isvalid_asn_objclassref() const
1359 {
1360 return id_data->isvalid_asn_objclassref();
1361 }
1362
1363 bool Identifier::isvalid_asn_objref() const
1364 {
1365 return id_data->isvalid_asn_objref();
1366 }
1367
1368 bool Identifier::isvalid_asn_objsetref() const
1369 {
1370 return id_data->isvalid_asn_objsetref();
1371 }
1372
1373 bool Identifier::isvalid_asn_typefieldref() const
1374 {
1375 return id_data->isvalid_asn_typefieldref();
1376 }
1377
1378 bool Identifier::isvalid_asn_valfieldref() const
1379 {
1380 return id_data->isvalid_asn_valfieldref();
1381 }
1382
1383 bool Identifier::isvalid_asn_valsetfieldref() const
1384 {
1385 return id_data->isvalid_asn_valsetfieldref();
1386 }
1387
1388 bool Identifier::isvalid_asn_objfieldref() const
1389 {
1390 return id_data->isvalid_asn_objfieldref();
1391 }
1392
1393 bool Identifier::isvalid_asn_objsetfieldref() const
1394 {
1395 return id_data->isvalid_asn_objsetfieldref();
1396 }
1397
1398 bool Identifier::isvalid_asn_word() const
1399 {
1400 return id_data->isvalid_asn_word();
1401 }
1402
1403 void Identifier::dump(unsigned level) const
1404 {
1405 DEBUG(level, "Identifier: %s", id_data->get_names().c_str());
1406 }
1407
1408 const Identifier underscore_zero(Identifier::ID_TTCN, string("_0"));
1409
1410} // namespace Common
This page took 0.078071 seconds and 5 git commands to generate.