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
14 ******************************************************************************/
17 #include "../common/memory.h"
23 #include "openssl/bn.h"
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"
35 #include "Module_list.hh"
36 #include "Debugger.hh"
37 #include "DebugCommands.hh"
40 size_t Module_Param_Id::get_index() const {
41 TTCN_error("Internal error: Module_Param_Id::get_index()");
45 char* Module_Param_Id::get_name() const {
46 TTCN_error("Internal error: Module_Param_Id::get_name()");
50 char* Module_Param_Id::get_current_name() const {
51 TTCN_error("Internal error: Module_Param_Id::get_current_name()");
55 bool Module_Param_Id::next_name(int offset
) {
56 TTCN_error("Internal error: Module_Param_Id::next_name()");
60 char* Module_Param_Name::get_str() const {
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
, '.');
68 result
= mputc(result
, '[');
70 result
= mputstr(result
, names
[i
]);
72 result
= mputc(result
, ']');
78 char* Module_Param_FieldName::get_str() const {
79 return mcopystr(name
);
82 char* Module_Param_Index::get_str() const {
83 return mprintf("[%lu]", (unsigned long)index
);
86 char* Module_Param_CustomName::get_str() const {
87 return mcopystr(name
);
90 void Module_Param_Length_Restriction::log() const {
91 TTCN_Logger::log_event(" length(%lu", (unsigned long)min
);
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
);
97 TTCN_Logger::log_event_str(")");
100 Module_Param_Id
* Module_Param::get_id() const {
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>";
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>";
120 void Module_Param::set_id(Module_Param_Id
* p_id
) {
121 if (id
) TTCN_error("Internal error: Module_Param::set_id()");
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
;
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
);
135 TTCN_Logger::log_event_str(get_operation_type_sign_str());
139 TTCN_Logger::log_event_str(" ifpresent");
141 if (length_restriction
!=NULL
) {
142 length_restriction
->log();
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
);
153 if (has_ifpresent
) error("%s cannot have an 'ifpresent' attribute", what
);
155 if (!is_template
|| !is_list
) {
156 if (length_restriction
!=NULL
) error("%s cannot have a length restriction", what
);
160 void Module_Param::add_elem(Module_Param
* /*value*/) {
161 TTCN_error("Internal error: Module_Param::add_elem()");
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()");
168 boolean
Module_Param::get_boolean() const {
169 TTCN_error("Internal error: Module_Param::get_boolean()");
173 size_t Module_Param::get_size() const {
174 TTCN_error("Internal error: Module_Param::get_size()");
178 Module_Param
* Module_Param::get_elem(size_t /*index*/) const {
179 TTCN_error("Internal error: Module_Param::get_elem()");
183 int Module_Param::get_string_size() const {
184 TTCN_error("Internal error: Module_Param::get_string_size()");
188 void* Module_Param::get_string_data() const {
189 TTCN_error("Internal error: Module_Param::get_string_data()");
193 int_val_t
* Module_Param::get_lower_int() const {
194 TTCN_error("Internal error: Module_Param::get_lower_int()");
198 int_val_t
* Module_Param::get_upper_int() const {
199 TTCN_error("Internal error: Module_Param::get_upper_int()");
203 double Module_Param::get_lower_float() const {
204 TTCN_error("Internal error: Module_Param::get_lower_float()");
208 double Module_Param::get_upper_float() const {
209 TTCN_error("Internal error: Module_Param::get_upper_float()");
213 bool Module_Param::has_lower_float() const {
214 TTCN_error("Internal error: Module_Param::has_lower_float()");
218 bool Module_Param::has_upper_float() const {
219 TTCN_error("Internal error: Module_Param::has_upper_float()");
223 universal_char
Module_Param::get_lower_uchar() const {
224 TTCN_error("Internal error: Module_Param::get_lower_uchar()");
225 return universal_char();
228 universal_char
Module_Param::get_upper_uchar() const {
229 TTCN_error("Internal error: Module_Param::get_upper_uchar()");
230 return universal_char();
233 int_val_t
* Module_Param::get_integer() const {
234 TTCN_error("Internal error: Module_Param::get_integer()");
238 double Module_Param::get_float() const {
239 TTCN_error("Internal error: Module_Param::get_float()");
243 char* Module_Param::get_pattern() const {
244 TTCN_error("Internal error: Module_Param::get_pattern()");
248 verdicttype
Module_Param::get_verdict() const {
249 TTCN_error("Internal error: Module_Param::get_verdict()");
253 char* Module_Param::get_enumerated() const {
254 TTCN_error("Internal error: Module_Param::get_enumerated()");
258 Module_Param_Ptr
Module_Param::get_referenced_param() const {
259 TTCN_error("Internal error: Module_Param::get_referenced_param()");
263 Module_Param::expression_operand_t
Module_Param::get_expr_type() const {
264 TTCN_error("Internal error: Module_Param::get_expr_type()");
268 const char* Module_Param::get_expr_type_str() const {
269 TTCN_error("Internal error: Module_Param::get_expr_type_str()");
273 Module_Param
* Module_Param::get_operand1() const {
274 TTCN_error("Internal error: Module_Param::get_operand1()");
278 Module_Param
* Module_Param::get_operand2() const {
279 TTCN_error("Internal error: Module_Param::get_operand2()");
283 Module_Param_Ptr::Module_Param_Ptr(Module_Param
* p
) {
284 ptr
= new module_param_ptr_struct
;
286 ptr
->temporary
= FALSE
;
291 Module_Param_Ptr::Module_Param_Ptr(const Module_Param_Ptr
& r
)
296 void Module_Param_Ptr::clean_up() {
297 if (ptr
->ref_count
== 1) {
298 if (ptr
->temporary
) {
308 Module_Param_Ptr
& Module_Param_Ptr::operator=(const Module_Param_Ptr
& r
) {
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()");
321 Module_Param_Ptr
Module_Param_Reference::get_referenced_param() const {
322 if (Debugger_Value_Parsing::happening()) {
323 error("References to other variables are not allowed.");
326 Module_Param_Ptr ptr
= Module_List::get_param(*mp_ref
);
331 char* Module_Param_Reference::get_enumerated() const {
332 if (mp_ref
->is_single_name()) {
333 return mp_ref
->get_current_name();
338 void Module_Param_Reference::log_value() const {
339 TTCN_Logger::log_event_str(mp_ref
->get_str());
342 void Module_Param_Unbound::log_value() const {
343 TTCN_Logger::log_event_str("<unbound>");
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()");
352 operand1
->set_parent(this);
353 operand2
->set_parent(this);
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()");
361 operand1
->set_parent(this);
364 Module_Param_Expression::~Module_Param_Expression() {
366 if (operand2
!= NULL
) {
371 const char* Module_Param_Expression::get_expr_type_str() const {
376 return "Subtracting (-)";
378 return "Multiplying (*)";
380 return "Dividing (/)";
382 return "Negating (-)";
383 case EXPR_CONCATENATE
:
384 return "Concatenating (&)";
390 void Module_Param_Expression::log_value() const {
391 if (expr_type
== EXPR_NEGATE
) {
392 TTCN_Logger::log_event_str("- ");
394 operand1
->log_value();
397 TTCN_Logger::log_event_str(" + ");
400 TTCN_Logger::log_event_str(" - ");
403 TTCN_Logger::log_event_str(" * ");
406 TTCN_Logger::log_event_str(" / ");
408 case EXPR_CONCATENATE
:
409 TTCN_Logger::log_event_str(" & ");
414 if (expr_type
!= EXPR_NEGATE
) {
415 operand2
->log_value();
419 void Module_Param_NotUsed::log_value() const {
420 TTCN_Logger::log_event_str("-");
423 void Module_Param_Omit::log_value() const {
424 TTCN_Logger::log_event_str("omit");
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()");
431 void Module_Param_Integer::log_value() const {
432 if (integer_value
->is_native()) {
433 INTEGER(integer_value
->get_val()).log();
436 integer
.set_val(*integer_value
);
441 void Module_Param_Float::log_value() const {
442 FLOAT(float_value
).log();
445 void Module_Param_Boolean::log_value() const {
446 BOOLEAN(boolean_value
).log();
449 void Module_Param_Verdict::log_value() const {
450 VERDICTTYPE(verdict_value
).log();
453 void Module_Param_Objid::log_value() const {
454 OBJID(n_chars
, chars_ptr
).log();
457 void Module_Param_Bitstring::log_value() const {
458 BITSTRING(n_chars
, chars_ptr
).log();
461 void Module_Param_Hexstring::log_value() const {
462 HEXSTRING(n_chars
, chars_ptr
).log();
465 void Module_Param_Octetstring::log_value() const {
466 OCTETSTRING(n_chars
, chars_ptr
).log();
469 void Module_Param_Charstring::log_value() const {
470 CHARSTRING(n_chars
, chars_ptr
).log();
473 void Module_Param_Universal_Charstring::log_value() const {
474 UNIVERSAL_CHARSTRING(n_chars
, chars_ptr
).log();
477 void Module_Param_Enumerated::log_value() const {
478 TTCN_Logger::log_event_str(enum_value
);
481 void Module_Param_Ttcn_Null::log_value() const {
482 TTCN_Logger::log_event_str("null");
485 void Module_Param_Ttcn_mtc::log_value() const {
486 TTCN_Logger::log_event_str("mtc");
489 void Module_Param_Ttcn_system::log_value() const {
490 TTCN_Logger::log_event_str("system");
493 void Module_Param_Asn_Null::log_value() const {
494 TTCN_Logger::log_event_str("NULL");
497 void Module_Param_Any::log_value() const {
498 TTCN_Logger::log_event_str("?");
501 void Module_Param_AnyOrNone::log_value() const {
502 TTCN_Logger::log_event_str("*");
505 void Module_Param_IntRange::log_bound(int_val_t
* bound
, bool is_lower
) {
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();
513 integer
.set_val(*bound
);
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(")");
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(")");
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(")");
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("\"");
550 void Module_Param_Bitstring_Template::log_value() const {
551 BITSTRING_template((unsigned int)n_chars
, chars_ptr
).log();
554 void Module_Param_Hexstring_Template::log_value() const {
555 HEXSTRING_template((unsigned int)n_chars
, chars_ptr
).log();
558 void Module_Param_Octetstring_Template::log_value() const {
559 OCTETSTRING_template((unsigned int)n_chars
, chars_ptr
).log();
562 Module_Param_Compound::~Module_Param_Compound() {
563 for (size_t i
=0; i
<values
.size(); i
++) {
569 size_t Module_Param_Compound::get_size() const {
570 return values
.size();
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
];
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(", ");
585 if (!values
.empty()) TTCN_Logger::log_event_str(" ");
586 TTCN_Logger::log_event_str(end_str
);
589 void Module_Param_Compound::add_elem(Module_Param
* value
) {
590 value
->set_parent(this);
591 values
.push_back(value
);
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
);
602 char* Module_Param::get_param_context() const {
604 if (parent
!= NULL
) {
605 result
= parent
->get_param_context();
608 char* id_str
= id
->get_str();
609 if (parent
!=NULL
&& !id
->is_index()) {
610 result
= mputc(result
, '.');
612 result
= mputstr(result
, id_str
);
618 void Module_Param::error(const char* err_msg
, ...) const {
619 if (Ttcn_String_Parsing::happening()) {
620 char* exception_str
= mcopystr("Error while setting ");
622 if (id
&& id
->is_custom()) {
623 param_ctx
= mputstr(id
->get_str(), " in module parameter");
626 char* tmp
= get_param_context();
627 param_ctx
= mprintf("parameter field '%s'", tmp
? tmp
: "<NULL pointer>");
630 exception_str
= mputstr(exception_str
, param_ctx
);
632 exception_str
= mputstr(exception_str
, ": ");
634 va_start(p_var
, err_msg
);
635 char* error_msg_str
= mprintf_va_list(err_msg
, p_var
);
637 exception_str
= mputstr(exception_str
, error_msg_str
);
639 TTCN_error_begin("%s", exception_str
);
643 else if (Debugger_Value_Parsing::happening()) {
644 char* exception_str
= mcopystr("Error while overwriting ");
646 if (id
&& id
->is_custom()) {
647 param_ctx
= mputstr(id
->get_str(), " in the variable");
650 char* tmp
= get_param_context();
651 param_ctx
= tmp
!= NULL
? mprintf("variable field '%s'", tmp
) :
652 mcopystr("the variable");
655 exception_str
= mputstr(exception_str
, param_ctx
);
657 exception_str
= mputstr(exception_str
, ": ");
659 va_start(p_var
, err_msg
);
660 char* error_msg_str
= mprintf_va_list(err_msg
, p_var
);
662 exception_str
= mputstr(exception_str
, error_msg_str
);
664 ttcn3_debugger
.print(DRET_NOTIFICATION
, "%s", exception_str
);
666 throw TC_Error(); // don't log anything in this case
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("???");
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
);
680 TTCN_Logger::log_event_str(" in module parameter");
683 TTCN_Logger::log_event_str("parameter field '");
684 char* param_ctx
= get_param_context();
685 TTCN_Logger::log_event_str(param_ctx
);
687 TTCN_Logger::log_event_str("'");
689 switch (operation_type
) {
690 case OT_ASSIGN
: TTCN_Logger::log_event_str(" to '"); break;
691 case OT_CONCAT
: TTCN_Logger::log_event_str(" and '"); break;
692 default: TTCN_Logger::log_event_str("' ??? '");
695 TTCN_Logger::log_event_str("': ");
697 va_start(p_var
, err_msg
);
698 TTCN_Logger::log_event_va_list(err_msg
, p_var
);
700 TTCN_Logger::send_event_as_error();
701 TTCN_Logger::end_event();
705 void Module_Param::type_error(const char* expected
, const char* type_name
/* = NULL */) const {
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());
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
;
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.",
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());
727 bool Ttcn_String_Parsing::string_parsing
= false;
728 bool Debugger_Value_Parsing::is_happening
= false;