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"
38 size_t Module_Param_Id::get_index() const {
39 TTCN_error("Internal error: Module_Param_Id::get_index()");
43 char* Module_Param_Id::get_name() const {
44 TTCN_error("Internal error: Module_Param_Id::get_name()");
48 char* Module_Param_Id::get_current_name() const {
49 TTCN_error("Internal error: Module_Param_Id::get_current_name()");
53 bool Module_Param_Id::next_name(int offset
) {
54 TTCN_error("Internal error: Module_Param_Id::next_name()");
58 char* Module_Param_Name::get_str() const {
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
, '.');
66 result
= mputc(result
, '[');
68 result
= mputstr(result
, names
[i
]);
70 result
= mputc(result
, ']');
76 char* Module_Param_FieldName::get_str() const {
77 return mcopystr(name
);
80 char* Module_Param_Index::get_str() const {
81 return mprintf("[%lu]", (unsigned long)index
);
84 char* Module_Param_CustomName::get_str() const {
85 return mcopystr(name
);
88 void Module_Param_Length_Restriction::log() const {
89 TTCN_Logger::log_event(" length(%lu", (unsigned long)min
);
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
);
95 TTCN_Logger::log_event_str(")");
98 Module_Param_Id
* Module_Param::get_id() const {
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>";
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>";
118 void Module_Param::set_id(Module_Param_Id
* p_id
) {
119 if (id
) TTCN_error("Internal error: Module_Param::set_id()");
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
;
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
);
133 TTCN_Logger::log_event_str(get_operation_type_sign_str());
137 TTCN_Logger::log_event_str(" ifpresent");
139 if (length_restriction
!=NULL
) {
140 length_restriction
->log();
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
);
151 if (has_ifpresent
) error("%s cannot have an 'ifpresent' attribute", what
);
153 if (!is_template
|| !is_list
) {
154 if (length_restriction
!=NULL
) error("%s cannot have a length restriction", what
);
158 void Module_Param::add_elem(Module_Param
* /*value*/) {
159 TTCN_error("Internal error: Module_Param::add_elem()");
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()");
166 boolean
Module_Param::get_boolean() const {
167 TTCN_error("Internal error: Module_Param::get_boolean()");
171 size_t Module_Param::get_size() const {
172 TTCN_error("Internal error: Module_Param::get_size()");
176 Module_Param
* Module_Param::get_elem(size_t /*index*/) const {
177 TTCN_error("Internal error: Module_Param::get_elem()");
181 int Module_Param::get_string_size() const {
182 TTCN_error("Internal error: Module_Param::get_string_size()");
186 void* Module_Param::get_string_data() const {
187 TTCN_error("Internal error: Module_Param::get_string_data()");
191 int_val_t
* Module_Param::get_lower_int() const {
192 TTCN_error("Internal error: Module_Param::get_lower_int()");
196 int_val_t
* Module_Param::get_upper_int() const {
197 TTCN_error("Internal error: Module_Param::get_upper_int()");
201 double Module_Param::get_lower_float() const {
202 TTCN_error("Internal error: Module_Param::get_lower_float()");
206 double Module_Param::get_upper_float() const {
207 TTCN_error("Internal error: Module_Param::get_upper_float()");
211 bool Module_Param::has_lower_float() const {
212 TTCN_error("Internal error: Module_Param::has_lower_float()");
216 bool Module_Param::has_upper_float() const {
217 TTCN_error("Internal error: Module_Param::has_upper_float()");
221 universal_char
Module_Param::get_lower_uchar() const {
222 TTCN_error("Internal error: Module_Param::get_lower_uchar()");
223 return universal_char();
226 universal_char
Module_Param::get_upper_uchar() const {
227 TTCN_error("Internal error: Module_Param::get_upper_uchar()");
228 return universal_char();
231 int_val_t
* Module_Param::get_integer() const {
232 TTCN_error("Internal error: Module_Param::get_integer()");
236 double Module_Param::get_float() const {
237 TTCN_error("Internal error: Module_Param::get_float()");
241 char* Module_Param::get_pattern() const {
242 TTCN_error("Internal error: Module_Param::get_pattern()");
246 verdicttype
Module_Param::get_verdict() const {
247 TTCN_error("Internal error: Module_Param::get_verdict()");
251 char* Module_Param::get_enumerated() const {
252 TTCN_error("Internal error: Module_Param::get_enumerated()");
256 Module_Param_Ptr
Module_Param::get_referenced_param() const {
257 TTCN_error("Internal error: Module_Param::get_referenced_param()");
261 Module_Param::expression_operand_t
Module_Param::get_expr_type() const {
262 TTCN_error("Internal error: Module_Param::get_expr_type()");
266 const char* Module_Param::get_expr_type_str() const {
267 TTCN_error("Internal error: Module_Param::get_expr_type_str()");
271 Module_Param
* Module_Param::get_operand1() const {
272 TTCN_error("Internal error: Module_Param::get_operand1()");
276 Module_Param
* Module_Param::get_operand2() const {
277 TTCN_error("Internal error: Module_Param::get_operand2()");
281 Module_Param_Ptr::Module_Param_Ptr(Module_Param
* p
) {
282 ptr
= new module_param_ptr_struct
;
284 ptr
->temporary
= FALSE
;
289 Module_Param_Ptr::Module_Param_Ptr(const Module_Param_Ptr
& r
)
294 void Module_Param_Ptr::clean_up() {
295 if (ptr
->ref_count
== 1) {
296 if (ptr
->temporary
) {
306 Module_Param_Ptr
& Module_Param_Ptr::operator=(const Module_Param_Ptr
& r
) {
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()");
319 Module_Param_Ptr
Module_Param_Reference::get_referenced_param() const {
321 Module_Param_Ptr ptr
= Module_List::get_param(*mp_ref
);
326 char* Module_Param_Reference::get_enumerated() const {
327 if (mp_ref
->is_single_name()) {
328 return mp_ref
->get_current_name();
333 void Module_Param_Reference::log_value() const {
334 TTCN_Logger::log_event_str(mp_ref
->get_str());
337 void Module_Param_Unbound::log_value() const {
338 TTCN_Logger::log_event_str("<unbound>");
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()");
347 operand1
->set_parent(this);
348 operand2
->set_parent(this);
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()");
356 operand1
->set_parent(this);
359 Module_Param_Expression::~Module_Param_Expression() {
361 if (operand2
!= NULL
) {
366 const char* Module_Param_Expression::get_expr_type_str() const {
371 return "Subtracting (-)";
373 return "Multiplying (*)";
375 return "Dividing (/)";
377 return "Negating (-)";
378 case EXPR_CONCATENATE
:
379 return "Concatenating (&)";
385 void Module_Param_Expression::log_value() const {
386 if (expr_type
== EXPR_NEGATE
) {
387 TTCN_Logger::log_event_str("- ");
389 operand1
->log_value();
392 TTCN_Logger::log_event_str(" + ");
395 TTCN_Logger::log_event_str(" - ");
398 TTCN_Logger::log_event_str(" * ");
401 TTCN_Logger::log_event_str(" / ");
403 case EXPR_CONCATENATE
:
404 TTCN_Logger::log_event_str(" & ");
409 if (expr_type
!= EXPR_NEGATE
) {
410 operand2
->log_value();
414 void Module_Param_NotUsed::log_value() const {
415 TTCN_Logger::log_event_str("-");
418 void Module_Param_Omit::log_value() const {
419 TTCN_Logger::log_event_str("omit");
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()");
426 void Module_Param_Integer::log_value() const {
427 if (integer_value
->is_native()) {
428 INTEGER(integer_value
->get_val()).log();
431 integer
.set_val(*integer_value
);
436 void Module_Param_Float::log_value() const {
437 FLOAT(float_value
).log();
440 void Module_Param_Boolean::log_value() const {
441 BOOLEAN(boolean_value
).log();
444 void Module_Param_Verdict::log_value() const {
445 VERDICTTYPE(verdict_value
).log();
448 void Module_Param_Objid::log_value() const {
449 OBJID(n_chars
, chars_ptr
).log();
452 void Module_Param_Bitstring::log_value() const {
453 BITSTRING(n_chars
, chars_ptr
).log();
456 void Module_Param_Hexstring::log_value() const {
457 HEXSTRING(n_chars
, chars_ptr
).log();
460 void Module_Param_Octetstring::log_value() const {
461 OCTETSTRING(n_chars
, chars_ptr
).log();
464 void Module_Param_Charstring::log_value() const {
465 CHARSTRING(n_chars
, chars_ptr
).log();
468 void Module_Param_Universal_Charstring::log_value() const {
469 UNIVERSAL_CHARSTRING(n_chars
, chars_ptr
).log();
472 void Module_Param_Enumerated::log_value() const {
473 TTCN_Logger::log_event_str(enum_value
);
476 void Module_Param_Ttcn_Null::log_value() const {
477 TTCN_Logger::log_event_str("null");
480 void Module_Param_Ttcn_mtc::log_value() const {
481 TTCN_Logger::log_event_str("mtc");
484 void Module_Param_Ttcn_system::log_value() const {
485 TTCN_Logger::log_event_str("system");
488 void Module_Param_Asn_Null::log_value() const {
489 TTCN_Logger::log_event_str("NULL");
492 void Module_Param_Any::log_value() const {
493 TTCN_Logger::log_event_str("?");
496 void Module_Param_AnyOrNone::log_value() const {
497 TTCN_Logger::log_event_str("*");
500 void Module_Param_IntRange::log_bound(int_val_t
* bound
, bool is_lower
) {
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();
508 integer
.set_val(*bound
);
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(")");
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(")");
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(")");
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("\"");
545 void Module_Param_Bitstring_Template::log_value() const {
546 BITSTRING_template((unsigned int)n_chars
, chars_ptr
).log();
549 void Module_Param_Hexstring_Template::log_value() const {
550 HEXSTRING_template((unsigned int)n_chars
, chars_ptr
).log();
553 void Module_Param_Octetstring_Template::log_value() const {
554 OCTETSTRING_template((unsigned int)n_chars
, chars_ptr
).log();
557 Module_Param_Compound::~Module_Param_Compound() {
558 for (size_t i
=0; i
<values
.size(); i
++) {
564 size_t Module_Param_Compound::get_size() const {
565 return values
.size();
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
];
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(", ");
580 if (!values
.empty()) TTCN_Logger::log_event_str(" ");
581 TTCN_Logger::log_event_str(end_str
);
584 void Module_Param_Compound::add_elem(Module_Param
* value
) {
585 value
->set_parent(this);
586 values
.push_back(value
);
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
);
597 char* Module_Param::get_param_context() const {
599 if (parent
!= NULL
) {
600 result
= parent
->get_param_context();
603 char* id_str
= id
->get_str();
604 if (parent
!=NULL
&& !id
->is_index()) {
605 result
= mputc(result
, '.');
607 result
= mputstr(result
, id_str
);
613 void Module_Param::error(const char* err_msg
, ...) const {
614 if (Ttcn_String_Parsing::happening()) {
615 char* exception_str
= mcopystr("Error while setting ");
617 if (id
&& id
->is_custom()) {
618 param_ctx
= mputstr(id
->get_str(), " in module parameter");
621 char* tmp
= get_param_context();
622 param_ctx
= mprintf("parameter field '%s'", tmp
? tmp
: "<NULL pointer>");
625 exception_str
= mputstr(exception_str
, param_ctx
);
627 exception_str
= mputstr(exception_str
, ": ");
629 va_start(p_var
, err_msg
);
630 char* error_msg_str
= mprintf_va_list(err_msg
, p_var
);
632 exception_str
= mputstr(exception_str
, error_msg_str
);
634 TTCN_error_begin("%s", exception_str
);
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("???");
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
);
650 TTCN_Logger::log_event_str(" in module parameter");
653 TTCN_Logger::log_event_str("parameter field '");
654 char* param_ctx
= get_param_context();
655 TTCN_Logger::log_event_str(param_ctx
);
657 TTCN_Logger::log_event_str("'");
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("' ??? '");
665 TTCN_Logger::log_event_str("': ");
667 va_start(p_var
, err_msg
);
668 TTCN_Logger::log_event_va_list(err_msg
, p_var
);
670 TTCN_Logger::send_event_as_error();
671 TTCN_Logger::end_event();
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
;
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.",
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());
691 bool Ttcn_String_Parsing::string_parsing
= false;