Commit | Line | Data |
---|---|---|
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 | ||
26 | namespace 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_"}, | |
601 | {"decomp__", "decomp", "decomp_"}, | |
602 | {"float2int__", "float2int", "float2int_"}, | |
603 | {"float2str__", "float2str", "float2str_"}, | |
604 | {"hex2bit__", "hex2bit", "hex2bit_"}, | |
605 | {"hex2int__", "hex2int", "hex2int_"}, | |
606 | {"hex2oct__", "hex2oct", "hex2oct_"}, | |
607 | {"hex2str__", "hex2str", "hex2str_"}, | |
608 | {"int2bit__", "int2bit", "int2bit_"}, | |
609 | {"int2char__", "int2char", "int2char_"}, | |
610 | {"int2float__", "int2float", "int2float_"}, | |
611 | {"int2hex__", "int2hex", "int2hex_"}, | |
612 | {"int2oct__", "int2oct", "int2oct_"}, | |
613 | {"int2str__", "int2str", "int2str_"}, | |
614 | {"int2unichar__", "int2unichar", "int2unichar_"}, | |
615 | {"ischosen__", "ischosen", "ischosen_"}, | |
616 | {"ispresent__", "ispresent", "ispresent_"}, | |
617 | {"isvalue__", "isvalue", "isvalue_"}, | |
618 | {"lengthof__", "lengthof", "lengthof_"}, | |
619 | {"log__", "log", "log_"}, | |
620 | {"log2str__", "log2str", "log2str_"}, | |
621 | {"match__", "match", "match_"}, | |
622 | {"mod__", "mod", "mod_"}, | |
623 | {"oct2bit__", "oct2bit", "oct2bit_"}, | |
624 | {"oct2char__", "oct2char", "oct2char_"}, | |
625 | {"oct2hex__", "oct2hex", "oct2hex_"}, | |
626 | {"oct2int__", "oct2int", "oct2int_"}, | |
627 | {"oct2str__", "oct2str", "oct2str_"}, | |
628 | {"regexp__", "regexp", "regexp_"}, | |
629 | {"replace__", "replace", "replace_"}, | |
630 | {"rem__", "rem", "rem_"}, | |
631 | {"rnd__", "rnd", "rnd_"}, | |
632 | {"self__", "self", "self_"}, | |
633 | {"str2bit__", "str2bit", "str2bit_"}, | |
634 | {"str2float__", "str2float", "str2float_"}, | |
635 | {"str2hex__", "str2hex", "str2hex_"}, | |
636 | {"str2int__", "str2int", "str2int_"}, | |
637 | {"str2oct__", "str2oct", "str2oct_"}, | |
638 | {"substr__", "substr", "substr_"}, | |
639 | {"unichar2int__", "unichar2int", "unichar2int_"}, | |
640 | {"unichar2char__", "unichar2char", "unichar2char_"}, | |
641 | {"valueof__", "valueof", "valueof_"}, | |
642 | {"verdicttype__", "verdicttype", "verdicttype_"}, | |
643 | {"ttcn2string__", "ttcn2string", "ttcn2string_"}, | |
644 | {"string2ttcn__", "string2ttcn", "string2ttcn_"}, | |
645 | {"unichar2oct__", "unichar2oct", "unichar2oct_"}, | |
646 | {"oct2unichar__", "oct2unichar", "oct2unichar_"}, | |
647 | {"remove__bom__", "remove_bom", "remove_bom_"}, | |
648 | {"encode__base64__", "encode_base64", "encode_base64_"}, | |
649 | {"decode__base64__", "decode_base64", "decode_base64_"}, | |
650 | {"get__stringencoding__", "get_stringencoding", "get_stringencoding_"}, | |
651 | /* reserved names of base library - keywords in ASN.1 */ | |
652 | {"FALSE_", 0, "FALSE"}, | |
653 | {"OPTIONAL_", 0, "OPTIONAL"}, | |
654 | {"TRUE_", 0, "TRUE"}, | |
655 | /* reserved names of base library - not keywords */ | |
656 | {"CHAR_", "CHAR", "CHAR"}, | |
657 | {"ERROR_", "ERROR", "ERROR"}, | |
658 | {"FAIL_", "FAIL", "FAIL"}, | |
659 | {"INCONC_", "INCONC", "INCONC"}, | |
660 | {"NONE_", "NONE", "NONE"}, | |
661 | {"PASS_", "PASS", "PASS"}, | |
662 | {"PORT_", "PORT", "PORT"}, | |
663 | {"TIMER_", "TIMER", "TIMER"}, | |
664 | {"main_", "main", "main"}, | |
665 | {"stderr_", "stderr", "stderr"}, // temporary hack | |
666 | {"stdin_", "stdin", "stdin"}, // temporary hack | |
667 | {"stdout_", "stdout", "stdout"}, // temporary hack | |
668 | {"TTCN3_", "TTCN3", "TTCN3"}, | |
669 | /* built-in types. this is the ASN/TTCN -> C++ name mapping */ | |
670 | {"ADDRESS", 0, "address"}, | |
671 | {"ASN_NULL", "NULL", 0}, | |
672 | {"BITSTRING", "BIT STRING", "bitstring"}, | |
673 | {"BOOLEAN", "BOOLEAN", "boolean"}, | |
674 | {"BMPString", "BMPString", 0}, | |
675 | {"CHARSTRING", 0, "charstring"}, | |
676 | {"CHARACTER_STRING", "CHARACTER STRING", 0}, | |
677 | {"COMPONENT", 0, "component"}, | |
678 | {"DEFAULT", 0, "default"}, | |
679 | {"EMBEDDED_PDV", "EMBEDDED PDV", 0}, | |
680 | {"EXTERNAL", "EXTERNAL", 0}, | |
681 | {"FLOAT", "REAL", "float"}, | |
682 | {"GraphicString", "GraphicString", 0}, | |
683 | {"HEXSTRING", 0, "hexstring"}, | |
684 | {"IA5String", "IA5String", 0}, | |
685 | {"INTEGER", "INTEGER", "integer"}, | |
686 | {"ISO646String", "ISO646String", 0}, | |
687 | {"NumericString", "NumericString", 0}, | |
688 | {"OBJID", "OBJECT IDENTIFIER", "objid"}, | |
689 | {"OCTETSTRING", "OCTET STRING", "octetstring"}, | |
690 | {"ObjectDescriptor", "ObjectDescriptor", 0}, | |
691 | {"PrintableString", "PrintableString", 0}, | |
692 | {"T61String", "T61String", 0}, | |
693 | {"TeletexString", "TeletexString", 0}, | |
694 | {"UTF8String", "UTF8String", 0}, | |
695 | {"UniversalString", "UniversalString", 0}, | |
696 | {"UNIVERSAL_CHARSTRING", 0, "universal charstring"}, | |
697 | {"VERDICTTYPE", 0, "verdicttype"}, | |
698 | {"VideotexString", "VideotexString", 0}, | |
699 | {"VisibleString", "VisibleString", 0}, | |
700 | /* reserved names of built-in types - valid ASN.1/TTCN names */ | |
701 | {"ADDRESS_", "ADDRESS", "ADDRESS"}, | |
702 | {"BITSTRING_", "BITSTRING", "BITSTRING"}, | |
703 | {"BOOLEAN_", 0, "BOOLEAN"}, | |
704 | {"BMPString_", 0, "BMPString"}, | |
705 | {"CHARSTRING_", "CHARSTRING", "CHARSTRING"}, | |
706 | {"COMPONENT_", "COMPONENT", "COMPONENT"}, | |
707 | {"DEFAULT_", 0, "DEFAULT"}, | |
708 | {"EXTERNAL_", 0, "EXTERNAL"}, | |
709 | {"FLOAT_", "FLOAT", "FLOAT"}, | |
710 | {"GraphicString_", 0, "GraphicString"}, | |
711 | {"HEXSTRING_", "HEXSTRING", "HEXSTRING"}, | |
712 | {"IA5String_", 0, "IA5String"}, | |
713 | {"INTEGER_", 0, "INTEGER"}, | |
714 | {"ISO646String_", 0, "ISO646String"}, | |
715 | {"NumericString_", 0, "NumericString"}, | |
716 | {"OBJID_", "OBJID", "OBJID"}, | |
717 | {"OCTETSTRING_", "OCTETSTRING", "OCTETSTRING"}, | |
718 | {"ObjectDescriptor_", 0, "ObjectDescriptor"}, | |
719 | {"PrintableString_", 0, "PrintableString"}, | |
720 | {"T61String_", 0, "T61String"}, | |
721 | {"TeletexString_", 0, "TeletexString"}, | |
722 | {"UTF8String_", 0, "UTF8String"}, | |
723 | {"UniversalString_", 0, "UniversalString"}, | |
724 | {"VERDICTTYPE_", "VERDICTTYPE", "VERDICTTYPE"}, | |
725 | {"VideotexString_", 0, "VideotexString"}, | |
726 | {"VisibleString_", 0, "VisibleString"}, | |
727 | /* keywords in TTCN-3, not reserved words in C++, postfixed in TTCN */ | |
728 | {"action__", "action", "action_"}, | |
729 | {"activate__", "activate", "activate_"}, | |
730 | {"address__", "address", "address_"}, | |
731 | {"alive__", "alive", "alive_"}, | |
732 | {"all__", "all", "all_"}, | |
733 | {"alt__", "alt", "alt_"}, | |
734 | {"altstep__", "altstep", "altstep_"}, | |
735 | {"and4b__", "and4b", "and4b_"}, | |
736 | {"any__", "any", "any_"}, | |
737 | {"anytype__", "anytype", "anytype_"}, | |
738 | {"apply__", "apply", "apply_"}, | |
739 | {"bitstring__", "bitstring", "bitstring_"}, | |
740 | {"call__", "call", "call_"}, | |
741 | {"charstring__", "charstring", "charstring_"}, | |
742 | {"check__", "check", "check_"}, | |
743 | {"clear__", "clear", "clear_"}, | |
744 | {"complement__", "complement", "complement_"}, | |
745 | {"connect__", "connect", "connect_"}, | |
746 | {"control__", "control", "control_"}, | |
747 | {"create__", "create", "create_"}, | |
748 | {"deactivate__", "deactivate", "deactivate_"}, | |
749 | {"derefers__", "derefers", "derefers_"}, | |
750 | {"disconnect__", "disconnect", "disconnect_"}, | |
751 | {"display__", "display", "display_"}, | |
752 | {"done__", "done", "done_"}, | |
753 | {"encode__", "encode", "encode_"}, | |
754 | {"enumerated__", "enumerated", "enumerated_"}, | |
755 | {"error__", "error", "error_"}, | |
756 | {"except__", "except", "except_"}, | |
757 | {"exception__", "exception", "exception_"}, | |
758 | {"execute__", "execute", "execute_"}, | |
759 | {"extends__", "extends", "extends_"}, | |
760 | {"extension__", "extension", "extension_"}, | |
761 | {"external__", "external", "external_"}, | |
762 | {"fail__", "fail", "fail_"}, | |
763 | {"from__", "from", "from_"}, | |
764 | {"function__", "function", "function_"}, | |
765 | {"getcall__", "getcall", "getcall_"}, | |
766 | {"getreply__", "getreply", "getreply_"}, | |
767 | {"getverdict__", "getverdict", "getverdict_"}, | |
768 | {"group__", "group", "group_"}, | |
769 | {"halt__", "halt", "halt_"}, | |
770 | {"hexstring__", "hexstring", "hexstring_"}, | |
771 | {"ifpresent__", "ifpresent", "ifpresent_"}, | |
772 | {"import__", "import", "import_"}, | |
773 | {"in__", "in", "in_"}, | |
774 | {"inconc__", "inconc", "inconc_"}, | |
775 | {"infinity__", "infinity", "infinity_"}, | |
776 | {"inout__", "inout", "inout_"}, | |
777 | {"integer__", "integer", "integer_"}, | |
778 | {"interleave__", "interleave", "interleave_"}, | |
779 | {"kill__", "kill", "kill_"}, | |
780 | {"killed__", "killed", "killed_"}, | |
781 | {"label__", "label", "label_"}, | |
782 | {"language__", "language", "language_"}, | |
783 | {"length__", "length", "length_"}, | |
784 | {"map__", "map", "map_"}, | |
785 | {"message__", "message", "message_"}, | |
786 | {"mixed__", "mixed", "mixed_"}, | |
787 | {"modifies__", "modifies", "modifies_"}, | |
788 | {"module__", "module", "module_"}, | |
789 | {"modulepar__", "modulepar", "modulepar_"}, | |
790 | {"mtc__", "mtc", "mtc_"}, | |
791 | {"noblock__", "noblock", "noblock_"}, | |
792 | {"none__", "none", "none_"}, | |
793 | {"not4b__", "not4b", "not4b_"}, | |
794 | {"nowait__", "nowait", "nowait_"}, | |
795 | {"null__", "null", "null_"}, | |
796 | {"objid__", "objid", "objid_"}, | |
797 | {"octetstring__", "octetstring", "octetstring_"}, | |
798 | {"of__", "of", "of_"}, | |
799 | {"omit__", "omit", "omit_"}, | |
800 | {"on__", "on", "on_"}, | |
801 | {"optional__", "optional", "optional_"}, | |
802 | {"or4b__", "or4b", "or4b_"}, | |
803 | {"out__", "out", "out_"}, | |
804 | {"override__", "override", "override_"}, | |
805 | {"param__", "param", "param_"}, | |
806 | {"pass__", "pass", "pass_"}, | |
807 | {"pattern__", "pattern", "pattern_"}, | |
808 | {"permutation__", "permutation", "permutation_"}, | |
809 | {"port__", "port", "port_"}, | |
810 | {"procedure__", "procedure", "procedure_"}, | |
811 | {"raise__", "raise", "raise_"}, | |
812 | {"read__", "read", "read_"}, | |
813 | {"receive__", "receive", "receive_"}, | |
814 | {"record__", "record", "record_"}, | |
815 | {"recursive__", "recursive", "recursive_"}, | |
816 | {"refers__", "refers", "refers_"}, | |
817 | {"repeat__", "repeat", "repeat_"}, | |
818 | {"reply__", "reply", "reply_"}, | |
819 | {"running__", "running", "running_"}, | |
820 | {"runs__", "runs", "runs_"}, | |
821 | {"select__", "select", "select_"}, | |
822 | {"send__", "send", "send_"}, | |
823 | {"sender__", "sender", "sender_"}, | |
824 | {"set__", "set", "set_"}, | |
825 | {"setverdict__", "setverdict", "setverdict_"}, | |
826 | {"signature__", "signature", "signature_"}, | |
827 | {"start__", "start", "start_"}, | |
828 | {"stop__", "stop", "stop_"}, | |
829 | {"subset__", "subset", "subset_"}, | |
830 | {"superset__", "superset", "superset_"}, | |
831 | {"system__", "system", "system_"}, | |
832 | {"testcase__", "testcase", "testcase_"}, | |
833 | {"timeout__", "timeout", "timeout_"}, | |
834 | {"timer__", "timer", "timer_"}, | |
835 | {"to__", "to", "to_"}, | |
836 | {"trigger__", "trigger", "trigger_"}, | |
837 | {"type__", "type", "type_"}, | |
838 | {"universal__", "universal", "universal_"}, | |
839 | {"unmap__", "unmap", "unmap_"}, | |
840 | {"value__", "value", "value_"}, | |
841 | {"present__", "present", "present_"}, | |
842 | {"var__", "var", "var_"}, | |
843 | {"variant__", "variant", "variant_"}, | |
844 | {"with__", "with", "with_"}, | |
845 | {"xor4b__", "xor4b", "xor4b_"}, | |
846 | /* other names that need to be mapped in a non-uniform manner */ | |
847 | /* major and minor are macros on some platforms; avoid generating | |
848 | * a potentially troublesome C++ identifier */ | |
849 | {"major_", "major", "major"}, | |
850 | {"minor_", "minor", "minor"}, | |
851 | /* internal / error */ | |
852 | {"<error>", "<error>", "<error>"}, | |
853 | {"TTCN_internal_", "<internal>", "<internal>"}, | |
854 | /* the last must be all zeros */ | |
855 | {0, 0, 0} | |
856 | }; // keywords | |
857 | ||
858 | internal_data_t::internal_data_t() | |
859 | : identifier_counter(0), string_invalid("<invalid>"), id_map_name(), | |
860 | id_map_asn(), id_map_ttcn() | |
861 | { | |
862 | } | |
863 | ||
864 | internal_data_t::~internal_data_t() | |
865 | { | |
866 | for(size_t i=0; i<id_map_name.size(); i++) | |
867 | Identifier::id_data_t::delete_this(id_map_name.get_nth_elem(i)); | |
868 | id_map_name.clear(); | |
869 | for(size_t i=0; i<id_map_asn.size(); i++) | |
870 | Identifier::id_data_t::delete_this(id_map_asn.get_nth_elem(i)); | |
871 | id_map_asn.clear(); | |
872 | for(size_t i=0; i<id_map_ttcn.size(); i++) | |
873 | Identifier::id_data_t::delete_this(id_map_ttcn.get_nth_elem(i)); | |
874 | id_map_ttcn.clear(); | |
875 | } | |
876 | ||
877 | void internal_data_t::add_keyword(const char* const keyword[3]) | |
878 | { | |
879 | Identifier::id_data_t *id_data | |
880 | =new Identifier::id_data_t(string(keyword[0])); | |
881 | bool conflict=false; | |
882 | // Pointers to already added (conflicting) keyword | |
883 | const Identifier::id_data_t *id_data_name=0; | |
884 | const Identifier::id_data_t *id_data_asn=0; | |
885 | const Identifier::id_data_t *id_data_ttcn=0; | |
886 | if(id_map_name.has_key(id_data->name)) { | |
887 | conflict=true; | |
888 | id_data_name=id_map_name[id_data->name]; | |
889 | } | |
890 | else { | |
891 | id_map_name.add(id_data->name, id_data); | |
892 | id_data->ref_count++; | |
893 | } | |
894 | ||
895 | if(keyword[1]==0) { | |
896 | id_data->asnname=string_invalid; | |
897 | } | |
898 | else { | |
899 | // copy the string if possible to avoid memory allocation | |
900 | if (id_data->name == keyword[1]) id_data->asnname = id_data->name; | |
901 | else id_data->asnname = keyword[1]; | |
902 | if(id_map_asn.has_key(id_data->asnname)) { | |
903 | conflict=true; | |
904 | id_data_asn=id_map_asn[id_data->asnname]; | |
905 | } | |
906 | else { | |
907 | id_map_asn.add(id_data->asnname, id_data); | |
908 | id_data->ref_count++; | |
909 | } | |
910 | } | |
911 | ||
912 | if(keyword[2]==0) { | |
913 | id_data->ttcnname=string_invalid; | |
914 | } | |
915 | else { | |
916 | // copy the string if possible to avoid memory allocation | |
917 | if (id_data->name == keyword[2]) id_data->ttcnname = id_data->name; | |
918 | else if (id_data->asnname == keyword[2]) | |
919 | id_data->ttcnname = id_data->asnname; | |
920 | else id_data->ttcnname = keyword[2]; | |
921 | if(id_map_ttcn.has_key(id_data->ttcnname)) { | |
922 | conflict=true; | |
923 | id_data_ttcn=id_map_ttcn[id_data->ttcnname]; | |
924 | } | |
925 | else { | |
926 | id_map_ttcn.add(id_data->ttcnname, id_data); | |
927 | id_data->ref_count++; | |
928 | } | |
929 | } | |
930 | ||
931 | if(conflict) { | |
932 | Location loc; | |
933 | loc.error | |
934 | ("This pre-defined identifier: %s", | |
935 | id_data->get_names().c_str()); | |
936 | loc.error | |
937 | ("conflicts with previous:"); | |
938 | if(id_data_name) | |
939 | loc.error | |
940 | ("[C++:] %s", | |
941 | id_data_name->get_names().c_str()); | |
942 | if(id_data_asn) | |
943 | loc.error | |
944 | ("[ASN:] %s", | |
945 | id_data_asn->get_names().c_str()); | |
946 | if(id_data_ttcn) | |
947 | loc.error | |
948 | ("[TTCN:] %s", | |
949 | id_data_ttcn->get_names().c_str()); | |
950 | } // if conflict | |
951 | Identifier::id_data_t::delete_this(id_data); | |
952 | } | |
953 | ||
954 | void internal_data_t::add_keywords() | |
955 | { | |
956 | { | |
957 | Location loc; | |
958 | Error_Context cntx(&loc, "While adding keywords"); | |
959 | for(size_t i=0; keywords[i][0]; i++) | |
960 | add_keyword(keywords[i]); | |
961 | } | |
962 | /* Perhaps it were good to read a file which contains | |
963 | user-defined mappings :) */ | |
964 | } | |
965 | ||
966 | internal_data_t *internal_data_t::Instance() | |
967 | { | |
968 | if(!instance) { | |
969 | instance=new internal_data_t(); | |
970 | instance->add_keywords(); | |
971 | } | |
972 | return instance; | |
973 | } | |
974 | ||
975 | void internal_data_t::increase_counter() | |
976 | { | |
977 | identifier_counter++; | |
978 | } | |
979 | ||
980 | void internal_data_t::decrease_counter() | |
981 | { | |
982 | identifier_counter--; | |
983 | if(identifier_counter==0) { | |
984 | delete instance; | |
985 | instance=0; | |
986 | } // if last Identifier instance | |
987 | } | |
988 | ||
989 | // ================================= | |
990 | // ===== Identifier | |
991 | // ================================= | |
992 | ||
993 | bool Identifier::is_reserved_word(const string& p_name, id_t p_id_t) | |
994 | { | |
995 | if (p_name.empty()) | |
996 | FATAL_ERROR("Identifier::is_reserved_word(): empty name"); | |
997 | internal_data_t *d = internal_data_t::Instance(); | |
998 | switch (p_id_t) { | |
999 | case ID_NAME: | |
1000 | if (d->id_map_name.has_key(p_name)) { | |
1001 | id_data_t *id_data_p = d->id_map_name[p_name]; | |
1002 | if (id_data_p->asnname == d->string_invalid && | |
1003 | id_data_p->ttcnname == d->string_invalid) return true; | |
1004 | else return false; | |
1005 | } else return false; | |
1006 | case ID_ASN: | |
1007 | if (p_name[0] == '&' || d->id_map_asn.has_key(p_name)) return false; | |
1008 | else { | |
1009 | string name; | |
1010 | id_data_t::asn_2_name(name, p_name); | |
1011 | if (d->id_map_name.has_key(name)) { | |
1012 | id_data_t *id_data_p = d->id_map_name[name]; | |
1013 | if (id_data_p->asnname.empty()) { | |
1014 | id_data_p->asnname = p_name; | |
1015 | d->id_map_asn.add(p_name, id_data_p); | |
1016 | id_data_p->ref_count++; | |
1017 | return false; | |
1018 | } else if (id_data_p->asnname == p_name) return false; | |
1019 | else return true; | |
1020 | } else return false; | |
1021 | } | |
1022 | case ID_TTCN: | |
1023 | if (d->id_map_ttcn.has_key(p_name)) return false; | |
1024 | else { | |
1025 | string name; | |
1026 | id_data_t::ttcn_2_name(name, p_name); | |
1027 | if (d->id_map_name.has_key(name)) { | |
1028 | id_data_t *id_data_p = d->id_map_name[name]; | |
1029 | if (id_data_p->ttcnname.empty()) { | |
1030 | id_data_p->ttcnname = p_name; | |
1031 | d->id_map_ttcn.add(p_name, id_data_p); | |
1032 | id_data_p->ref_count++; | |
1033 | return false; | |
1034 | } else if (id_data_p->ttcnname == p_name) return false; | |
1035 | else return true; | |
1036 | } else return false; | |
1037 | } | |
1038 | default: | |
1039 | FATAL_ERROR("Identifier::is_reserved_word(): invalid language"); | |
1040 | return false; | |
1041 | } | |
1042 | } | |
1043 | ||
1044 | string Identifier::asn_2_name(const string& p_name) | |
1045 | { | |
1046 | internal_data_t *d = internal_data_t::Instance(); | |
1047 | if (d->id_map_asn.has_key(p_name)) { | |
1048 | id_data_t *id_data_p = d->id_map_asn[p_name]; | |
1049 | if (id_data_p->name.empty()) { | |
1050 | id_data_t::asn_2_name(id_data_p->name, p_name); | |
1051 | d->id_map_name.add(id_data_p->name, id_data_p); | |
1052 | id_data_p->ref_count++; | |
1053 | } | |
1054 | return id_data_p->name; | |
1055 | } else { | |
1056 | string name; | |
1057 | id_data_t::asn_2_name(name, p_name); | |
1058 | if (d->id_map_name.has_key(name)) { | |
1059 | id_data_t *id_data_p = d->id_map_name[name]; | |
1060 | if (id_data_p->asnname.empty()) { | |
1061 | id_data_p->asnname = p_name; | |
1062 | d->id_map_asn.add(p_name, id_data_p); | |
1063 | id_data_p->ref_count++; | |
1064 | } | |
1065 | } | |
1066 | return name; | |
1067 | } | |
1068 | } | |
1069 | ||
1070 | string Identifier::name_2_asn(const string& p_name) | |
1071 | { | |
1072 | internal_data_t *d = internal_data_t::Instance(); | |
1073 | if (d->id_map_name.has_key(p_name)) { | |
1074 | id_data_t *id_data_p = d->id_map_name[p_name]; | |
1075 | if (id_data_p->asnname.empty()) { | |
1076 | id_data_t::name_2_asn(id_data_p->asnname, p_name); | |
1077 | d->id_map_asn.add(id_data_p->asnname, id_data_p); | |
1078 | id_data_p->ref_count++; | |
1079 | } | |
1080 | return id_data_p->asnname; | |
1081 | } else { | |
1082 | string asnname; | |
1083 | id_data_t::name_2_asn(asnname, p_name); | |
1084 | if (d->id_map_asn.has_key(asnname)) { | |
1085 | id_data_t *id_data_p = d->id_map_asn[asnname]; | |
1086 | if (id_data_p->name.empty()) { | |
1087 | id_data_p->name = p_name; | |
1088 | d->id_map_name.add(p_name, id_data_p); | |
1089 | id_data_p->ref_count++; | |
1090 | } | |
1091 | } | |
1092 | return asnname; | |
1093 | } | |
1094 | } | |
1095 | ||
1096 | string Identifier::ttcn_2_name(const string& p_name) | |
1097 | { | |
1098 | internal_data_t *d = internal_data_t::Instance(); | |
1099 | if (d->id_map_ttcn.has_key(p_name)) { | |
1100 | id_data_t *id_data_p = d->id_map_ttcn[p_name]; | |
1101 | if (id_data_p->name.empty()) { | |
1102 | id_data_t::ttcn_2_name(id_data_p->name, p_name); | |
1103 | d->id_map_name.add(id_data_p->name, id_data_p); | |
1104 | id_data_p->ref_count++; | |
1105 | } | |
1106 | return id_data_p->name; | |
1107 | } else { | |
1108 | string name; | |
1109 | id_data_t::ttcn_2_name(name, p_name); | |
1110 | if (d->id_map_name.has_key(name)) { | |
1111 | id_data_t *id_data_p = d->id_map_name[name]; | |
1112 | if (id_data_p->ttcnname.empty()) { | |
1113 | id_data_p->ttcnname = p_name; | |
1114 | d->id_map_ttcn.add(p_name, id_data_p); | |
1115 | id_data_p->ref_count++; | |
1116 | } | |
1117 | } | |
1118 | return name; | |
1119 | } | |
1120 | } | |
1121 | ||
1122 | string Identifier::name_2_ttcn(const string& p_name) | |
1123 | { | |
1124 | internal_data_t *d = internal_data_t::Instance(); | |
1125 | if (d->id_map_name.has_key(p_name)) { | |
1126 | id_data_t *id_data_p = d->id_map_name[p_name]; | |
1127 | if (id_data_p->ttcnname.empty()) { | |
1128 | id_data_t::name_2_ttcn(id_data_p->ttcnname, p_name); | |
1129 | d->id_map_ttcn.add(id_data_p->ttcnname, id_data_p); | |
1130 | id_data_p->ref_count++; | |
1131 | } | |
1132 | return id_data_p->ttcnname; | |
1133 | } else { | |
1134 | string ttcnname; | |
1135 | id_data_t::name_2_ttcn(ttcnname, p_name); | |
1136 | if (d->id_map_ttcn.has_key(ttcnname)) { | |
1137 | id_data_t *id_data_p = d->id_map_ttcn[ttcnname]; | |
1138 | if (id_data_p->name.empty()) { | |
1139 | id_data_p->name = p_name; | |
1140 | d->id_map_name.add(p_name, id_data_p); | |
1141 | id_data_p->ref_count++; | |
1142 | } | |
1143 | } | |
1144 | return ttcnname; | |
1145 | } | |
1146 | } | |
1147 | ||
1148 | Identifier::Identifier(id_t p_id_t, const string& p_name, bool dontreg) | |
1149 | : id_data(0), origin(p_id_t) | |
1150 | { | |
1151 | if (p_name.empty()) FATAL_ERROR("Identifier::Identifier(): empty name"); | |
1152 | internal_data_t *d=internal_data_t::Instance(); | |
1153 | d->increase_counter(); | |
1154 | switch(p_id_t) { | |
1155 | case ID_NAME: | |
1156 | if(d->id_map_name.has_key(p_name)) { | |
1157 | id_data=d->id_map_name[p_name]; | |
1158 | id_data->ref_count++; | |
1159 | } | |
1160 | else { | |
1161 | id_data=new id_data_t(p_name); | |
1162 | if(!dontreg) { | |
1163 | d->id_map_name.add(p_name, id_data); | |
1164 | id_data->ref_count++; | |
1165 | } | |
1166 | } | |
1167 | break; | |
1168 | case ID_ASN: | |
1169 | if(d->id_map_asn.has_key(p_name)) { | |
1170 | id_data=d->id_map_asn[p_name]; | |
1171 | id_data->ref_count++; | |
1172 | } | |
1173 | else if(p_name[0]=='&') { // special amp-identifiers (&) | |
1174 | string p_name2=p_name.substr(1); | |
1175 | string name2; | |
1176 | if(d->id_map_asn.has_key(p_name2)) | |
1177 | name2=d->id_map_asn[p_name2]->get_name(); | |
1178 | else | |
1179 | id_data_t::asn_2_name(name2, p_name2); | |
1180 | id_data=new id_data_t(name2); | |
1181 | id_data->asnname=p_name; | |
1182 | id_data->ttcnname=d->string_invalid; | |
1183 | if(!dontreg) { | |
1184 | d->id_map_asn.add(p_name, id_data); | |
1185 | id_data->ref_count++; | |
1186 | } | |
1187 | /* this id_data should NOT be added to id_map_name. */ | |
1188 | } // if &identifier | |
1189 | else { | |
1190 | string name; | |
1191 | id_data_t::asn_2_name(name, p_name); | |
1192 | if(!dontreg && d->id_map_name.has_key(name)) { | |
1193 | id_data=d->id_map_name[name]; | |
1194 | id_data->ref_count++; | |
1195 | if(id_data->asnname.empty()) { | |
1196 | id_data->asnname=p_name; | |
1197 | if(!dontreg) { | |
1198 | d->id_map_asn.add(p_name, id_data); | |
1199 | id_data->ref_count++; | |
1200 | } | |
1201 | } | |
1202 | else if(id_data->asnname!=p_name) { | |
1203 | Location loc; | |
1204 | loc.error | |
1205 | ("The ASN identifier `%s' clashes with this id: %s", | |
1206 | p_name.c_str(), id_data->get_names().c_str()); | |
1207 | } | |
1208 | } | |
1209 | else { | |
1210 | id_data=new id_data_t(name); | |
1211 | id_data->asnname=p_name; | |
1212 | if(!dontreg) { | |
1213 | d->id_map_name.add(name, id_data); | |
1214 | d->id_map_asn.add(p_name, id_data); | |
1215 | id_data->ref_count+=2; | |
1216 | } | |
1217 | } | |
1218 | } | |
1219 | break; | |
1220 | case ID_TTCN: | |
1221 | if(d->id_map_ttcn.has_key(p_name)) { | |
1222 | id_data=d->id_map_ttcn[p_name]; | |
1223 | id_data->ref_count++; | |
1224 | } | |
1225 | else { | |
1226 | string name; | |
1227 | id_data_t::ttcn_2_name(name, p_name); | |
1228 | if(!dontreg && d->id_map_name.has_key(name)) { | |
1229 | id_data=d->id_map_name[name]; | |
1230 | id_data->ref_count++; | |
1231 | if(id_data->ttcnname.empty()) { | |
1232 | id_data->ttcnname=p_name; | |
1233 | if(!dontreg) { | |
1234 | d->id_map_ttcn.add(p_name, id_data); | |
1235 | id_data->ref_count++; | |
1236 | } | |
1237 | } | |
1238 | else if(id_data->ttcnname!=p_name) { | |
1239 | Location loc; | |
1240 | loc.error | |
1241 | ("The TTCN identifier `%s' clashes with this id: %s", | |
1242 | p_name.c_str(), id_data->get_names().c_str()); | |
1243 | } | |
1244 | } | |
1245 | else { | |
1246 | id_data=new id_data_t(name); | |
1247 | id_data->ttcnname=p_name; | |
1248 | if(!dontreg) { | |
1249 | d->id_map_name.add(name, id_data); | |
1250 | d->id_map_ttcn.add(p_name, id_data); | |
1251 | id_data->ref_count+=2; | |
1252 | } | |
1253 | } | |
1254 | } | |
1255 | break; | |
1256 | default: | |
1257 | FATAL_ERROR("Identifier::Identifier()"); | |
1258 | } // switch p_id_t | |
1259 | } | |
1260 | ||
1261 | Identifier::Identifier(const Identifier& p) | |
1262 | : id_data(p.id_data), origin(p.origin) | |
1263 | { | |
1264 | internal_data_t::Instance()->increase_counter(); | |
1265 | id_data->ref_count++; | |
1266 | } | |
1267 | ||
1268 | Identifier::~Identifier() | |
1269 | { | |
1270 | id_data_t::delete_this(id_data); | |
1271 | /* I don't want to free the id_data structs here. They will be | |
1272 | deleted in decrease_counter() when the maps are destructed. */ | |
1273 | internal_data_t::Instance()->decrease_counter(); | |
1274 | } | |
1275 | ||
1276 | Identifier& Identifier::operator=(const Identifier& p) | |
1277 | { | |
1278 | if(&p!=this) { | |
1279 | id_data_t::delete_this(id_data); | |
1280 | id_data=p.id_data; | |
1281 | id_data->ref_count++; | |
1282 | origin=p.origin; | |
1283 | } | |
1284 | return *this; | |
1285 | } | |
1286 | ||
1287 | bool Identifier::operator==(const Identifier& p) const | |
1288 | { | |
1289 | return id_data->name==p.id_data->name; | |
1290 | } | |
1291 | ||
1292 | bool Identifier::operator<(const Identifier& p) const | |
1293 | { | |
1294 | return id_data->name<p.id_data->name; | |
1295 | } | |
1296 | ||
1297 | const string& Identifier::get_name() const | |
1298 | { | |
1299 | return id_data->get_name(); | |
1300 | } | |
1301 | ||
1302 | const string& Identifier::get_dispname() const | |
1303 | { | |
1304 | switch(origin) { | |
1305 | case ID_NAME: | |
1306 | return id_data->get_name(); | |
1307 | case ID_ASN: | |
1308 | return id_data->get_asnname(); | |
1309 | case ID_TTCN: | |
1310 | return id_data->get_ttcnname(); | |
1311 | default: | |
1312 | FATAL_ERROR("Identifier::get_dispname()"); | |
1313 | return id_data->get_name(); | |
1314 | } | |
1315 | } | |
1316 | ||
1317 | const string& Identifier::get_asnname() const | |
1318 | { | |
1319 | return id_data->get_asnname(); | |
1320 | } | |
1321 | ||
1322 | const string& Identifier::get_ttcnname() const | |
1323 | { | |
1324 | return id_data->get_ttcnname(); | |
1325 | } | |
1326 | ||
1327 | bool Identifier::get_has_valid(id_t p_id_t) const | |
1328 | { | |
1329 | return id_data->get_has_valid(p_id_t); | |
1330 | } | |
1331 | ||
1332 | string Identifier::get_names() const | |
1333 | { | |
1334 | return id_data->get_names(); | |
1335 | } | |
1336 | ||
1337 | bool Identifier::isvalid_asn_modref() const | |
1338 | { | |
1339 | return id_data->isvalid_asn_modref(); | |
1340 | } | |
1341 | ||
1342 | bool Identifier::isvalid_asn_typeref() const | |
1343 | { | |
1344 | return id_data->isvalid_asn_typeref(); | |
1345 | } | |
1346 | ||
1347 | bool Identifier::isvalid_asn_valref() const | |
1348 | { | |
1349 | return id_data->isvalid_asn_valref(); | |
1350 | } | |
1351 | ||
1352 | bool Identifier::isvalid_asn_valsetref() const | |
1353 | { | |
1354 | return id_data->isvalid_asn_valsetref(); | |
1355 | } | |
1356 | ||
1357 | bool Identifier::isvalid_asn_objclassref() const | |
1358 | { | |
1359 | return id_data->isvalid_asn_objclassref(); | |
1360 | } | |
1361 | ||
1362 | bool Identifier::isvalid_asn_objref() const | |
1363 | { | |
1364 | return id_data->isvalid_asn_objref(); | |
1365 | } | |
1366 | ||
1367 | bool Identifier::isvalid_asn_objsetref() const | |
1368 | { | |
1369 | return id_data->isvalid_asn_objsetref(); | |
1370 | } | |
1371 | ||
1372 | bool Identifier::isvalid_asn_typefieldref() const | |
1373 | { | |
1374 | return id_data->isvalid_asn_typefieldref(); | |
1375 | } | |
1376 | ||
1377 | bool Identifier::isvalid_asn_valfieldref() const | |
1378 | { | |
1379 | return id_data->isvalid_asn_valfieldref(); | |
1380 | } | |
1381 | ||
1382 | bool Identifier::isvalid_asn_valsetfieldref() const | |
1383 | { | |
1384 | return id_data->isvalid_asn_valsetfieldref(); | |
1385 | } | |
1386 | ||
1387 | bool Identifier::isvalid_asn_objfieldref() const | |
1388 | { | |
1389 | return id_data->isvalid_asn_objfieldref(); | |
1390 | } | |
1391 | ||
1392 | bool Identifier::isvalid_asn_objsetfieldref() const | |
1393 | { | |
1394 | return id_data->isvalid_asn_objsetfieldref(); | |
1395 | } | |
1396 | ||
1397 | bool Identifier::isvalid_asn_word() const | |
1398 | { | |
1399 | return id_data->isvalid_asn_word(); | |
1400 | } | |
1401 | ||
1402 | void Identifier::dump(unsigned level) const | |
1403 | { | |
1404 | DEBUG(level, "Identifier: %s", id_data->get_names().c_str()); | |
1405 | } | |
1406 | ||
1407 | const Identifier underscore_zero(Identifier::ID_TTCN, string("_0")); | |
1408 | ||
1409 | } // namespace Common |