Debugger - Stage 2 (artf511247)
[deliverable/titan.core.git] / core / Param_Types.cc
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 ******************************************************************************/
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"
35 #include "Module_list.hh"
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
84 char* Module_Param_CustomName::get_str() const {
85 return mcopystr(name);
86 }
87
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
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
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()) {
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 }
625 exception_str = mputstr(exception_str, param_ctx);
626 Free(param_ctx);
627 exception_str = mputstr(exception_str, ": ");
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 }
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 }
659 switch (operation_type) {
660 case OT_ASSIGN: TTCN_Logger::log_event_str(" to '"); break;
661 case OT_CONCAT: TTCN_Logger::log_event_str(" and '"); break;
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
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
691 bool Ttcn_String_Parsing::string_parsing = false;
This page took 0.045526 seconds and 5 git commands to generate.