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 | * Balasko, Jeno | |
10 | * Baranyi, Botond | |
11 | * Beres, Szabolcs | |
12 | * Delic, Adam | |
13 | * | |
14 | ******************************************************************************/ | |
970ed795 EL |
15 | #include <string.h> |
16 | ||
17 | #include "../common/memory.h" | |
18 | #include "Types.h" | |
19 | #include "RInt.hh" | |
20 | #include "Error.hh" | |
21 | ||
22 | // Needed for logging | |
23 | #include "openssl/bn.h" | |
24 | #include "Integer.hh" | |
25 | #include "Float.hh" | |
26 | #include "Boolean.hh" | |
27 | #include "Objid.hh" | |
28 | #include "Verdicttype.hh" | |
29 | #include "Bitstring.hh" | |
30 | #include "Hexstring.hh" | |
31 | #include "Octetstring.hh" | |
32 | #include "Charstring.hh" | |
33 | #include "Universal_charstring.hh" | |
34 | #include "Logger.hh" | |
3abe9331 | 35 | #include "Module_list.hh" |
970ed795 EL |
36 | |
37 | ||
38 | size_t Module_Param_Id::get_index() const { | |
39 | TTCN_error("Internal error: Module_Param_Id::get_index()"); | |
40 | return 0; | |
41 | } | |
42 | ||
43 | char* Module_Param_Id::get_name() const { | |
44 | TTCN_error("Internal error: Module_Param_Id::get_name()"); | |
45 | return NULL; | |
46 | } | |
47 | ||
48 | char* Module_Param_Id::get_current_name() const { | |
49 | TTCN_error("Internal error: Module_Param_Id::get_current_name()"); | |
50 | return NULL; | |
51 | } | |
52 | ||
53 | bool Module_Param_Id::next_name(int offset) { | |
54 | TTCN_error("Internal error: Module_Param_Id::next_name()"); | |
55 | return false; | |
56 | } | |
57 | ||
58 | char* Module_Param_Name::get_str() const { | |
59 | char* result = NULL; | |
60 | for (size_t i = 0; i < names.size(); ++i) { | |
61 | bool is_index = names[i][0] >= '0' && names[i][0] <= '9'; | |
62 | if (i > 0 && !is_index) { | |
63 | result = mputc(result, '.'); | |
64 | } | |
65 | if (is_index) { | |
66 | result = mputc(result, '['); | |
67 | } | |
68 | result = mputstr(result, names[i]); | |
69 | if (is_index) { | |
70 | result = mputc(result, ']'); | |
71 | } | |
72 | } | |
73 | return result; | |
74 | } | |
75 | ||
76 | char* Module_Param_FieldName::get_str() const { | |
77 | return mcopystr(name); | |
78 | } | |
79 | ||
80 | char* Module_Param_Index::get_str() const { | |
81 | return mprintf("[%lu]", (unsigned long)index); | |
82 | } | |
83 | ||
3abe9331 | 84 | char* Module_Param_CustomName::get_str() const { |
85 | return mcopystr(name); | |
86 | } | |
87 | ||
970ed795 EL |
88 | void Module_Param_Length_Restriction::log() const { |
89 | TTCN_Logger::log_event(" length(%lu", (unsigned long)min); | |
90 | if (min!=max) { | |
91 | TTCN_Logger::log_event_str(".."); | |
92 | if (!has_max) TTCN_Logger::log_event_str("infinity"); | |
93 | else TTCN_Logger::log_event("%lu", (unsigned long)max); | |
94 | } | |
95 | TTCN_Logger::log_event_str(")"); | |
96 | } | |
97 | ||
98 | Module_Param_Id* Module_Param::get_id() const { | |
99 | return id; | |
100 | } | |
101 | ||
102 | const char* Module_Param::get_operation_type_str() const { | |
103 | switch (operation_type) { | |
104 | case OT_ASSIGN: return "assignment"; | |
105 | case OT_CONCAT: return "concatenation"; | |
106 | default: return "<unknown operation>"; | |
107 | } | |
108 | } | |
109 | ||
110 | const char* Module_Param::get_operation_type_sign_str() const { | |
111 | switch (operation_type) { | |
112 | case OT_ASSIGN: return ":="; | |
113 | case OT_CONCAT: return "&="; | |
114 | default: return "<unknown operation>"; | |
115 | } | |
116 | } | |
117 | ||
118 | void Module_Param::set_id(Module_Param_Id* p_id) { | |
119 | if (id) TTCN_error("Internal error: Module_Param::set_id()"); | |
120 | id = p_id; | |
121 | } | |
122 | ||
123 | void Module_Param::set_length_restriction(Module_Param_Length_Restriction* p_length_restriction) { | |
124 | if (length_restriction!=NULL) TTCN_error("Internal error: Module_Param::set_length_restriction()"); | |
125 | length_restriction = p_length_restriction; | |
126 | } | |
127 | ||
128 | void Module_Param::log(bool log_id) const { | |
129 | if (log_id && id && id->is_explicit()) { | |
130 | char* id_str = id->get_str(); | |
131 | TTCN_Logger::log_event_str(id_str); | |
132 | Free(id_str); | |
133 | TTCN_Logger::log_event_str(get_operation_type_sign_str()); | |
134 | } | |
135 | log_value(); | |
136 | if (has_ifpresent) { | |
137 | TTCN_Logger::log_event_str(" ifpresent"); | |
138 | } | |
139 | if (length_restriction!=NULL) { | |
140 | length_restriction->log(); | |
141 | } | |
142 | } | |
143 | ||
144 | void Module_Param::basic_check(int check_bits, const char* what) const { | |
145 | bool is_template = check_bits & BC_TEMPLATE; | |
146 | bool is_list = check_bits & BC_LIST; | |
147 | if (is_template || !is_list) { | |
148 | if (get_operation_type()!=OT_ASSIGN) error("The %s of %ss is not allowed.", get_operation_type_str(), what); | |
149 | } | |
150 | if (!is_template) { | |
151 | if (has_ifpresent) error("%s cannot have an 'ifpresent' attribute", what); | |
152 | } | |
153 | if (!is_template || !is_list) { | |
154 | if (length_restriction!=NULL) error("%s cannot have a length restriction", what); | |
155 | } | |
156 | } | |
157 | ||
158 | void Module_Param::add_elem(Module_Param* /*value*/) { | |
159 | TTCN_error("Internal error: Module_Param::add_elem()"); | |
160 | } | |
161 | ||
162 | void Module_Param::add_list_with_implicit_ids(Vector<Module_Param*>* /*mp_list*/) { | |
163 | TTCN_error("Internal error: Module_Param::add_list_with_implicit_ids()"); | |
164 | } | |
165 | ||
166 | boolean Module_Param::get_boolean() const { | |
167 | TTCN_error("Internal error: Module_Param::get_boolean()"); | |
168 | return FALSE; | |
169 | } | |
170 | ||
171 | size_t Module_Param::get_size() const { | |
172 | TTCN_error("Internal error: Module_Param::get_size()"); | |
173 | return 0; | |
174 | } | |
175 | ||
176 | Module_Param* Module_Param::get_elem(size_t /*index*/) const { | |
177 | TTCN_error("Internal error: Module_Param::get_elem()"); | |
178 | return NULL; | |
179 | } | |
180 | ||
181 | int Module_Param::get_string_size() const { | |
182 | TTCN_error("Internal error: Module_Param::get_string_size()"); | |
183 | return 0; | |
184 | } | |
185 | ||
186 | void* Module_Param::get_string_data() const { | |
187 | TTCN_error("Internal error: Module_Param::get_string_data()"); | |
188 | return NULL; | |
189 | } | |
190 | ||
191 | int_val_t* Module_Param::get_lower_int() const { | |
192 | TTCN_error("Internal error: Module_Param::get_lower_int()"); | |
193 | return NULL; | |
194 | } | |
195 | ||
196 | int_val_t* Module_Param::get_upper_int() const { | |
197 | TTCN_error("Internal error: Module_Param::get_upper_int()"); | |
198 | return NULL; | |
199 | } | |
200 | ||
201 | double Module_Param::get_lower_float() const { | |
202 | TTCN_error("Internal error: Module_Param::get_lower_float()"); | |
203 | return 0.0; | |
204 | } | |
205 | ||
206 | double Module_Param::get_upper_float() const { | |
207 | TTCN_error("Internal error: Module_Param::get_upper_float()"); | |
208 | return 0.0; | |
209 | } | |
210 | ||
211 | bool Module_Param::has_lower_float() const { | |
212 | TTCN_error("Internal error: Module_Param::has_lower_float()"); | |
213 | return false; | |
214 | } | |
215 | ||
216 | bool Module_Param::has_upper_float() const { | |
217 | TTCN_error("Internal error: Module_Param::has_upper_float()"); | |
218 | return false; | |
219 | } | |
220 | ||
221 | universal_char Module_Param::get_lower_uchar() const { | |
222 | TTCN_error("Internal error: Module_Param::get_lower_uchar()"); | |
223 | return universal_char(); | |
224 | } | |
225 | ||
226 | universal_char Module_Param::get_upper_uchar() const { | |
227 | TTCN_error("Internal error: Module_Param::get_upper_uchar()"); | |
228 | return universal_char(); | |
229 | } | |
230 | ||
231 | int_val_t* Module_Param::get_integer() const { | |
232 | TTCN_error("Internal error: Module_Param::get_integer()"); | |
233 | return NULL; | |
234 | } | |
235 | ||
236 | double Module_Param::get_float() const { | |
237 | TTCN_error("Internal error: Module_Param::get_float()"); | |
238 | return 0.0; | |
239 | } | |
240 | ||
241 | char* Module_Param::get_pattern() const { | |
242 | TTCN_error("Internal error: Module_Param::get_pattern()"); | |
243 | return NULL; | |
244 | } | |
245 | ||
246 | verdicttype Module_Param::get_verdict() const { | |
247 | TTCN_error("Internal error: Module_Param::get_verdict()"); | |
248 | return NONE; | |
249 | } | |
250 | ||
251 | char* Module_Param::get_enumerated() const { | |
252 | TTCN_error("Internal error: Module_Param::get_enumerated()"); | |
253 | return NULL; | |
254 | } | |
255 | ||
3abe9331 | 256 | Module_Param_Ptr Module_Param::get_referenced_param() const { |
257 | TTCN_error("Internal error: Module_Param::get_referenced_param()"); | |
258 | return NULL; | |
259 | } | |
260 | ||
261 | Module_Param::expression_operand_t Module_Param::get_expr_type() const { | |
262 | TTCN_error("Internal error: Module_Param::get_expr_type()"); | |
263 | return EXPR_ERROR; | |
264 | } | |
265 | ||
266 | const char* Module_Param::get_expr_type_str() const { | |
267 | TTCN_error("Internal error: Module_Param::get_expr_type_str()"); | |
268 | return NULL; | |
269 | } | |
270 | ||
271 | Module_Param* Module_Param::get_operand1() const { | |
272 | TTCN_error("Internal error: Module_Param::get_operand1()"); | |
273 | return NULL; | |
274 | } | |
275 | ||
276 | Module_Param* Module_Param::get_operand2() const { | |
277 | TTCN_error("Internal error: Module_Param::get_operand2()"); | |
278 | return NULL; | |
279 | } | |
280 | ||
281 | Module_Param_Ptr::Module_Param_Ptr(Module_Param* p) { | |
282 | ptr = new module_param_ptr_struct; | |
283 | ptr->mp_ptr = p; | |
284 | ptr->temporary = FALSE; | |
285 | ptr->ref_count = 1; | |
286 | } | |
287 | ||
288 | ||
289 | Module_Param_Ptr::Module_Param_Ptr(const Module_Param_Ptr& r) | |
290 | : ptr(r.ptr) { | |
291 | ++ptr->ref_count; | |
292 | } | |
293 | ||
294 | void Module_Param_Ptr::clean_up() { | |
295 | if (ptr->ref_count == 1) { | |
296 | if (ptr->temporary) { | |
297 | delete ptr->mp_ptr; | |
298 | } | |
299 | delete ptr; | |
300 | } | |
301 | else { | |
302 | --ptr->ref_count; | |
303 | } | |
304 | } | |
305 | ||
306 | Module_Param_Ptr& Module_Param_Ptr::operator=(const Module_Param_Ptr& r) { | |
307 | clean_up(); | |
308 | ptr = r.ptr; | |
309 | ++ptr->ref_count; | |
310 | return *this; | |
311 | } | |
312 | ||
313 | Module_Param_Reference::Module_Param_Reference(Module_Param_Name* p): mp_ref(p) { | |
314 | if (mp_ref == NULL) { | |
315 | TTCN_error("Internal error: Module_Param_Reference::Module_Param_Reference()"); | |
316 | } | |
317 | } | |
318 | ||
319 | Module_Param_Ptr Module_Param_Reference::get_referenced_param() const { | |
320 | mp_ref->reset(); | |
321 | Module_Param_Ptr ptr = Module_List::get_param(*mp_ref); | |
322 | ptr.set_temporary(); | |
323 | return ptr; | |
324 | } | |
325 | ||
326 | char* Module_Param_Reference::get_enumerated() const { | |
327 | if (mp_ref->is_single_name()) { | |
328 | return mp_ref->get_current_name(); | |
329 | } | |
330 | return NULL; | |
331 | } | |
332 | ||
333 | void Module_Param_Reference::log_value() const { | |
334 | TTCN_Logger::log_event_str(mp_ref->get_str()); | |
335 | } | |
336 | ||
337 | void Module_Param_Unbound::log_value() const { | |
338 | TTCN_Logger::log_event_str("<unbound>"); | |
339 | } | |
340 | ||
341 | Module_Param_Expression::Module_Param_Expression(expression_operand_t p_type, | |
342 | Module_Param* p_op1, Module_Param* p_op2) | |
343 | : expr_type(p_type), operand1(p_op1), operand2(p_op2) { | |
344 | if (operand1 == NULL || operand2 == NULL) { | |
345 | TTCN_error("Internal error: Module_Param_Expression::Module_Param_Expression()"); | |
346 | } | |
347 | operand1->set_parent(this); | |
348 | operand2->set_parent(this); | |
349 | } | |
350 | ||
351 | Module_Param_Expression::Module_Param_Expression(Module_Param* p_op) | |
352 | : expr_type(EXPR_NEGATE), operand1(p_op), operand2(NULL) { | |
353 | if (operand1 == NULL) { | |
354 | TTCN_error("Internal error: Module_Param_Expression::Module_Param_Expression()"); | |
355 | } | |
356 | operand1->set_parent(this); | |
357 | } | |
358 | ||
359 | Module_Param_Expression::~Module_Param_Expression() { | |
360 | delete operand1; | |
361 | if (operand2 != NULL) { | |
362 | delete operand2; | |
363 | } | |
364 | } | |
365 | ||
366 | const char* Module_Param_Expression::get_expr_type_str() const { | |
367 | switch (expr_type) { | |
368 | case EXPR_ADD: | |
369 | return "Adding (+)"; | |
370 | case EXPR_SUBTRACT: | |
371 | return "Subtracting (-)"; | |
372 | case EXPR_MULTIPLY: | |
373 | return "Multiplying (*)"; | |
374 | case EXPR_DIVIDE: | |
375 | return "Dividing (/)"; | |
376 | case EXPR_NEGATE: | |
377 | return "Negating (-)"; | |
378 | case EXPR_CONCATENATE: | |
379 | return "Concatenating (&)"; | |
380 | default: | |
381 | return NULL; | |
382 | } | |
383 | } | |
384 | ||
385 | void Module_Param_Expression::log_value() const { | |
386 | if (expr_type == EXPR_NEGATE) { | |
387 | TTCN_Logger::log_event_str("- "); | |
388 | } | |
389 | operand1->log_value(); | |
390 | switch (expr_type) { | |
391 | case EXPR_ADD: | |
392 | TTCN_Logger::log_event_str(" + "); | |
393 | break; | |
394 | case EXPR_SUBTRACT: | |
395 | TTCN_Logger::log_event_str(" - "); | |
396 | break; | |
397 | case EXPR_MULTIPLY: | |
398 | TTCN_Logger::log_event_str(" * "); | |
399 | break; | |
400 | case EXPR_DIVIDE: | |
401 | TTCN_Logger::log_event_str(" / "); | |
402 | break; | |
403 | case EXPR_CONCATENATE: | |
404 | TTCN_Logger::log_event_str(" & "); | |
405 | break; | |
406 | default: | |
407 | break; | |
408 | } | |
409 | if (expr_type != EXPR_NEGATE) { | |
410 | operand2->log_value(); | |
411 | } | |
412 | } | |
413 | ||
970ed795 EL |
414 | void Module_Param_NotUsed::log_value() const { |
415 | TTCN_Logger::log_event_str("-"); | |
416 | } | |
417 | ||
418 | void Module_Param_Omit::log_value() const { | |
419 | TTCN_Logger::log_event_str("omit"); | |
420 | } | |
421 | ||
422 | Module_Param_Integer::Module_Param_Integer(int_val_t* p): integer_value(p) { | |
423 | if (integer_value==NULL) TTCN_error("Internal error: Module_Param_Integer::Module_Param_Integer()"); | |
424 | } | |
425 | ||
426 | void Module_Param_Integer::log_value() const { | |
427 | if (integer_value->is_native()) { | |
428 | INTEGER(integer_value->get_val()).log(); | |
429 | } else { | |
430 | INTEGER integer; | |
431 | integer.set_val(*integer_value); | |
432 | integer.log(); | |
433 | } | |
434 | } | |
435 | ||
436 | void Module_Param_Float::log_value() const { | |
437 | FLOAT(float_value).log(); | |
438 | } | |
439 | ||
440 | void Module_Param_Boolean::log_value() const { | |
441 | BOOLEAN(boolean_value).log(); | |
442 | } | |
443 | ||
444 | void Module_Param_Verdict::log_value() const { | |
445 | VERDICTTYPE(verdict_value).log(); | |
446 | } | |
447 | ||
448 | void Module_Param_Objid::log_value() const { | |
449 | OBJID(n_chars, chars_ptr).log(); | |
450 | } | |
451 | ||
452 | void Module_Param_Bitstring::log_value() const { | |
453 | BITSTRING(n_chars, chars_ptr).log(); | |
454 | } | |
455 | ||
456 | void Module_Param_Hexstring::log_value() const { | |
457 | HEXSTRING(n_chars, chars_ptr).log(); | |
458 | } | |
459 | ||
460 | void Module_Param_Octetstring::log_value() const { | |
461 | OCTETSTRING(n_chars, chars_ptr).log(); | |
462 | } | |
463 | ||
464 | void Module_Param_Charstring::log_value() const { | |
465 | CHARSTRING(n_chars, chars_ptr).log(); | |
466 | } | |
467 | ||
468 | void Module_Param_Universal_Charstring::log_value() const { | |
469 | UNIVERSAL_CHARSTRING(n_chars, chars_ptr).log(); | |
470 | } | |
471 | ||
472 | void Module_Param_Enumerated::log_value() const { | |
473 | TTCN_Logger::log_event_str(enum_value); | |
474 | } | |
475 | ||
476 | void Module_Param_Ttcn_Null::log_value() const { | |
477 | TTCN_Logger::log_event_str("null"); | |
478 | } | |
479 | ||
480 | void Module_Param_Ttcn_mtc::log_value() const { | |
481 | TTCN_Logger::log_event_str("mtc"); | |
482 | } | |
483 | ||
484 | void Module_Param_Ttcn_system::log_value() const { | |
485 | TTCN_Logger::log_event_str("system"); | |
486 | } | |
487 | ||
488 | void Module_Param_Asn_Null::log_value() const { | |
489 | TTCN_Logger::log_event_str("NULL"); | |
490 | } | |
491 | ||
492 | void Module_Param_Any::log_value() const { | |
493 | TTCN_Logger::log_event_str("?"); | |
494 | } | |
495 | ||
496 | void Module_Param_AnyOrNone::log_value() const { | |
497 | TTCN_Logger::log_event_str("*"); | |
498 | } | |
499 | ||
500 | void Module_Param_IntRange::log_bound(int_val_t* bound, bool is_lower) { | |
501 | if (bound==NULL) { | |
502 | if (is_lower) TTCN_Logger::log_event_str("-"); | |
503 | TTCN_Logger::log_event_str("infinity"); | |
504 | } else if (bound->is_native()) { | |
505 | INTEGER(bound->get_val()).log(); | |
506 | } else { | |
507 | INTEGER integer; | |
508 | integer.set_val(*bound); | |
509 | integer.log(); | |
510 | } | |
511 | } | |
512 | ||
513 | void Module_Param_IntRange::log_value() const { | |
514 | TTCN_Logger::log_event_str("("); | |
515 | log_bound(lower_bound, true); | |
516 | TTCN_Logger::log_event_str(".."); | |
517 | log_bound(upper_bound, false); | |
518 | TTCN_Logger::log_event_str(")"); | |
519 | } | |
520 | ||
521 | void Module_Param_FloatRange::log_value() const { | |
522 | TTCN_Logger::log_event_str("("); | |
523 | if (has_lower) FLOAT(lower_bound).log(); | |
524 | else TTCN_Logger::log_event_str("-infinity"); | |
525 | TTCN_Logger::log_event_str(".."); | |
526 | if (has_upper) FLOAT(upper_bound).log(); | |
527 | else TTCN_Logger::log_event_str("infinity"); | |
528 | TTCN_Logger::log_event_str(")"); | |
529 | } | |
530 | ||
531 | void Module_Param_StringRange::log_value() const { | |
532 | TTCN_Logger::log_event_str("("); | |
533 | UNIVERSAL_CHARSTRING(lower_bound).log(); | |
534 | TTCN_Logger::log_event_str(".."); | |
535 | UNIVERSAL_CHARSTRING(upper_bound).log(); | |
536 | TTCN_Logger::log_event_str(")"); | |
537 | } | |
538 | ||
539 | void Module_Param_Pattern::log_value() const { | |
540 | TTCN_Logger::log_event_str("pattern \""); | |
541 | TTCN_Logger::log_event_str(pattern); | |
542 | TTCN_Logger::log_event_str("\""); | |
543 | } | |
544 | ||
545 | void Module_Param_Bitstring_Template::log_value() const { | |
546 | BITSTRING_template((unsigned int)n_chars, chars_ptr).log(); | |
547 | } | |
548 | ||
549 | void Module_Param_Hexstring_Template::log_value() const { | |
550 | HEXSTRING_template((unsigned int)n_chars, chars_ptr).log(); | |
551 | } | |
552 | ||
553 | void Module_Param_Octetstring_Template::log_value() const { | |
554 | OCTETSTRING_template((unsigned int)n_chars, chars_ptr).log(); | |
555 | } | |
556 | ||
557 | Module_Param_Compound::~Module_Param_Compound() { | |
558 | for (size_t i=0; i<values.size(); i++) { | |
559 | delete values[i]; | |
560 | } | |
561 | values.clear(); | |
562 | } | |
563 | ||
564 | size_t Module_Param_Compound::get_size() const { | |
565 | return values.size(); | |
566 | } | |
567 | ||
568 | Module_Param* Module_Param_Compound::get_elem(size_t index) const { | |
569 | if (index>=values.size()) TTCN_error("Internal error: Module_Param::get_elem(): index overflow"); | |
570 | return values[index]; | |
571 | } | |
572 | ||
573 | void Module_Param_Compound::log_value_vec(const char* begin_str, const char* end_str) const { | |
574 | TTCN_Logger::log_event_str(begin_str); | |
575 | TTCN_Logger::log_event_str(" "); | |
576 | for (size_t i=0; i<values.size(); ++i) { | |
577 | if (i>0) TTCN_Logger::log_event_str(", "); | |
578 | values[i]->log(); | |
579 | } | |
580 | if (!values.empty()) TTCN_Logger::log_event_str(" "); | |
581 | TTCN_Logger::log_event_str(end_str); | |
582 | } | |
583 | ||
584 | void Module_Param_Compound::add_elem(Module_Param* value) { | |
585 | value->set_parent(this); | |
586 | values.push_back(value); | |
587 | } | |
588 | ||
589 | void Module_Param_Compound::add_list_with_implicit_ids(Vector<Module_Param*>* mp_list) { | |
590 | for (size_t i=0; i<mp_list->size(); i++) { | |
591 | Module_Param* mp_current = mp_list->at(i); | |
592 | mp_current->set_id(new Module_Param_Index(get_size(),false)); | |
593 | add_elem(mp_current); | |
594 | } | |
595 | } | |
596 | ||
597 | char* Module_Param::get_param_context() const { | |
598 | char* result = NULL; | |
599 | if (parent != NULL) { | |
600 | result = parent->get_param_context(); | |
601 | } | |
602 | if (id) { | |
603 | char* id_str = id->get_str(); | |
604 | if (parent!=NULL && !id->is_index()) { | |
605 | result = mputc(result, '.'); | |
606 | } | |
607 | result = mputstr(result, id_str); | |
608 | Free(id_str); | |
609 | } | |
610 | return result; | |
611 | } | |
612 | ||
613 | void Module_Param::error(const char* err_msg, ...) const { | |
614 | if (Ttcn_String_Parsing::happening()) { | |
3abe9331 | 615 | char* exception_str = mcopystr("Error while setting "); |
616 | char* param_ctx; | |
617 | if (id && id->is_custom()) { | |
618 | param_ctx = mputstr(id->get_str(), " in module parameter"); | |
619 | } | |
620 | else { | |
621 | char* tmp = get_param_context(); | |
622 | param_ctx = mprintf("parameter field '%s'", tmp ? tmp : "<NULL pointer>"); | |
623 | Free(tmp); | |
624 | } | |
970ed795 EL |
625 | exception_str = mputstr(exception_str, param_ctx); |
626 | Free(param_ctx); | |
3abe9331 | 627 | exception_str = mputstr(exception_str, ": "); |
970ed795 EL |
628 | va_list p_var; |
629 | va_start(p_var, err_msg); | |
630 | char* error_msg_str = mprintf_va_list(err_msg, p_var); | |
631 | va_end(p_var); | |
632 | exception_str = mputstr(exception_str, error_msg_str); | |
633 | Free(error_msg_str); | |
634 | TTCN_error_begin("%s", exception_str); | |
635 | Free(exception_str); | |
636 | TTCN_error_end(); | |
637 | } | |
638 | TTCN_Logger::begin_event(TTCN_Logger::ERROR_UNQUALIFIED); | |
639 | TTCN_Logger::log_event_str("Error while "); | |
640 | switch (operation_type) { | |
641 | case OT_ASSIGN: TTCN_Logger::log_event_str("setting"); break; | |
642 | case OT_CONCAT: TTCN_Logger::log_event_str("concatenating"); break; | |
643 | default: TTCN_Logger::log_event_str("???"); | |
644 | } | |
3abe9331 | 645 | TTCN_Logger::log_event_str(" "); |
646 | if (id && id->is_custom()) { | |
647 | char* custom_ctx = id->get_str(); | |
648 | TTCN_Logger::log_event_str(custom_ctx); | |
649 | Free(custom_ctx); | |
650 | TTCN_Logger::log_event_str(" in module parameter"); | |
651 | } | |
652 | else { | |
653 | TTCN_Logger::log_event_str("parameter field '"); | |
654 | char* param_ctx = get_param_context(); | |
655 | TTCN_Logger::log_event_str(param_ctx); | |
656 | Free(param_ctx); | |
657 | TTCN_Logger::log_event_str("'"); | |
658 | } | |
970ed795 | 659 | switch (operation_type) { |
3abe9331 | 660 | case OT_ASSIGN: TTCN_Logger::log_event_str(" to '"); break; |
661 | case OT_CONCAT: TTCN_Logger::log_event_str(" and '"); break; | |
970ed795 EL |
662 | default: TTCN_Logger::log_event_str("' ??? '"); |
663 | } | |
664 | log(false); | |
665 | TTCN_Logger::log_event_str("': "); | |
666 | va_list p_var; | |
667 | va_start(p_var, err_msg); | |
668 | TTCN_Logger::log_event_va_list(err_msg, p_var); | |
669 | va_end(p_var); | |
670 | TTCN_Logger::send_event_as_error(); | |
671 | TTCN_Logger::end_event(); | |
672 | throw TC_Error(); | |
673 | } | |
674 | ||
3abe9331 | 675 | void Module_Param::type_error(const char* expected, const char* type_name /* = NULL */) const { |
676 | const Module_Param* reporter = this; | |
677 | // if it's an expression, find its head and use that to report the error | |
678 | // (since that's the only parameter with a valid name) | |
679 | while (reporter->parent != NULL && reporter->parent->get_type() == MP_Expression) { | |
680 | reporter = reporter->parent; | |
681 | } | |
682 | // either use this parameter's or the referenced parameter's type string | |
683 | // (but never the head's type string) | |
684 | reporter->error("Type mismatch: %s or reference to %s was expected%s%s instead of %s%s.", | |
685 | expected, expected, | |
686 | (type_name != NULL) ? " for type " : "", (type_name != NULL) ? type_name : "", | |
687 | (get_type() == MP_Reference) ? "reference to " : "", | |
688 | (get_type() == MP_Reference) ? get_referenced_param()->get_type_str() : get_type_str()); | |
689 | } | |
690 | ||
970ed795 | 691 | bool Ttcn_String_Parsing::string_parsing = false; |