Commit | Line | Data |
---|---|---|
970ed795 EL |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Copyright (c) 2000-2014 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 |