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