Merge pull request #63 from BenceJanosSzabo/master
[deliverable/titan.core.git] / core / Param_Types.cc
CommitLineData
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
38size_t Module_Param_Id::get_index() const {
39 TTCN_error("Internal error: Module_Param_Id::get_index()");
40 return 0;
41}
42
43char* Module_Param_Id::get_name() const {
44 TTCN_error("Internal error: Module_Param_Id::get_name()");
45 return NULL;
46}
47
48char* Module_Param_Id::get_current_name() const {
49 TTCN_error("Internal error: Module_Param_Id::get_current_name()");
50 return NULL;
51}
52
53bool Module_Param_Id::next_name(int offset) {
54 TTCN_error("Internal error: Module_Param_Id::next_name()");
55 return false;
56}
57
58char* 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
76char* Module_Param_FieldName::get_str() const {
77 return mcopystr(name);
78}
79
80char* Module_Param_Index::get_str() const {
81 return mprintf("[%lu]", (unsigned long)index);
82}
83
3abe9331 84char* Module_Param_CustomName::get_str() const {
85 return mcopystr(name);
86}
87
970ed795
EL
88void 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
98Module_Param_Id* Module_Param::get_id() const {
99 return id;
100}
101
102const 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
110const 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
118void 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
123void 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
128void 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
144void 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
158void Module_Param::add_elem(Module_Param* /*value*/) {
159 TTCN_error("Internal error: Module_Param::add_elem()");
160}
161
162void 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
166boolean Module_Param::get_boolean() const {
167 TTCN_error("Internal error: Module_Param::get_boolean()");
168 return FALSE;
169}
170
171size_t Module_Param::get_size() const {
172 TTCN_error("Internal error: Module_Param::get_size()");
173 return 0;
174}
175
176Module_Param* Module_Param::get_elem(size_t /*index*/) const {
177 TTCN_error("Internal error: Module_Param::get_elem()");
178 return NULL;
179}
180
181int Module_Param::get_string_size() const {
182 TTCN_error("Internal error: Module_Param::get_string_size()");
183 return 0;
184}
185
186void* Module_Param::get_string_data() const {
187 TTCN_error("Internal error: Module_Param::get_string_data()");
188 return NULL;
189}
190
191int_val_t* Module_Param::get_lower_int() const {
192 TTCN_error("Internal error: Module_Param::get_lower_int()");
193 return NULL;
194}
195
196int_val_t* Module_Param::get_upper_int() const {
197 TTCN_error("Internal error: Module_Param::get_upper_int()");
198 return NULL;
199}
200
201double Module_Param::get_lower_float() const {
202 TTCN_error("Internal error: Module_Param::get_lower_float()");
203 return 0.0;
204}
205
206double Module_Param::get_upper_float() const {
207 TTCN_error("Internal error: Module_Param::get_upper_float()");
208 return 0.0;
209}
210
211bool Module_Param::has_lower_float() const {
212 TTCN_error("Internal error: Module_Param::has_lower_float()");
213 return false;
214}
215
216bool Module_Param::has_upper_float() const {
217 TTCN_error("Internal error: Module_Param::has_upper_float()");
218 return false;
219}
220
221universal_char Module_Param::get_lower_uchar() const {
222 TTCN_error("Internal error: Module_Param::get_lower_uchar()");
223 return universal_char();
224}
225
226universal_char Module_Param::get_upper_uchar() const {
227 TTCN_error("Internal error: Module_Param::get_upper_uchar()");
228 return universal_char();
229}
230
231int_val_t* Module_Param::get_integer() const {
232 TTCN_error("Internal error: Module_Param::get_integer()");
233 return NULL;
234}
235
236double Module_Param::get_float() const {
237 TTCN_error("Internal error: Module_Param::get_float()");
238 return 0.0;
239}
240
241char* Module_Param::get_pattern() const {
242 TTCN_error("Internal error: Module_Param::get_pattern()");
243 return NULL;
244}
245
246verdicttype Module_Param::get_verdict() const {
247 TTCN_error("Internal error: Module_Param::get_verdict()");
248 return NONE;
249}
250
251char* Module_Param::get_enumerated() const {
252 TTCN_error("Internal error: Module_Param::get_enumerated()");
253 return NULL;
254}
255
3abe9331 256Module_Param_Ptr Module_Param::get_referenced_param() const {
257 TTCN_error("Internal error: Module_Param::get_referenced_param()");
258 return NULL;
259}
260
261Module_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
266const char* Module_Param::get_expr_type_str() const {
267 TTCN_error("Internal error: Module_Param::get_expr_type_str()");
268 return NULL;
269}
270
271Module_Param* Module_Param::get_operand1() const {
272 TTCN_error("Internal error: Module_Param::get_operand1()");
273 return NULL;
274}
275
276Module_Param* Module_Param::get_operand2() const {
277 TTCN_error("Internal error: Module_Param::get_operand2()");
278 return NULL;
279}
280
281Module_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
289Module_Param_Ptr::Module_Param_Ptr(const Module_Param_Ptr& r)
290: ptr(r.ptr) {
291 ++ptr->ref_count;
292}
293
294void 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
306Module_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
313Module_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
319Module_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
326char* 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
333void Module_Param_Reference::log_value() const {
334 TTCN_Logger::log_event_str(mp_ref->get_str());
335}
336
337void Module_Param_Unbound::log_value() const {
338 TTCN_Logger::log_event_str("<unbound>");
339}
340
341Module_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
351Module_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
359Module_Param_Expression::~Module_Param_Expression() {
360 delete operand1;
361 if (operand2 != NULL) {
362 delete operand2;
363 }
364}
365
366const 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
385void 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
414void Module_Param_NotUsed::log_value() const {
415 TTCN_Logger::log_event_str("-");
416}
417
418void Module_Param_Omit::log_value() const {
419 TTCN_Logger::log_event_str("omit");
420}
421
422Module_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
426void 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
436void Module_Param_Float::log_value() const {
437 FLOAT(float_value).log();
438}
439
440void Module_Param_Boolean::log_value() const {
441 BOOLEAN(boolean_value).log();
442}
443
444void Module_Param_Verdict::log_value() const {
445 VERDICTTYPE(verdict_value).log();
446}
447
448void Module_Param_Objid::log_value() const {
449 OBJID(n_chars, chars_ptr).log();
450}
451
452void Module_Param_Bitstring::log_value() const {
453 BITSTRING(n_chars, chars_ptr).log();
454}
455
456void Module_Param_Hexstring::log_value() const {
457 HEXSTRING(n_chars, chars_ptr).log();
458}
459
460void Module_Param_Octetstring::log_value() const {
461 OCTETSTRING(n_chars, chars_ptr).log();
462}
463
464void Module_Param_Charstring::log_value() const {
465 CHARSTRING(n_chars, chars_ptr).log();
466}
467
468void Module_Param_Universal_Charstring::log_value() const {
469 UNIVERSAL_CHARSTRING(n_chars, chars_ptr).log();
470}
471
472void Module_Param_Enumerated::log_value() const {
473 TTCN_Logger::log_event_str(enum_value);
474}
475
476void Module_Param_Ttcn_Null::log_value() const {
477 TTCN_Logger::log_event_str("null");
478}
479
480void Module_Param_Ttcn_mtc::log_value() const {
481 TTCN_Logger::log_event_str("mtc");
482}
483
484void Module_Param_Ttcn_system::log_value() const {
485 TTCN_Logger::log_event_str("system");
486}
487
488void Module_Param_Asn_Null::log_value() const {
489 TTCN_Logger::log_event_str("NULL");
490}
491
492void Module_Param_Any::log_value() const {
493 TTCN_Logger::log_event_str("?");
494}
495
496void Module_Param_AnyOrNone::log_value() const {
497 TTCN_Logger::log_event_str("*");
498}
499
500void 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
513void 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
521void 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
531void 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
539void 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
545void Module_Param_Bitstring_Template::log_value() const {
546 BITSTRING_template((unsigned int)n_chars, chars_ptr).log();
547}
548
549void Module_Param_Hexstring_Template::log_value() const {
550 HEXSTRING_template((unsigned int)n_chars, chars_ptr).log();
551}
552
553void Module_Param_Octetstring_Template::log_value() const {
554 OCTETSTRING_template((unsigned int)n_chars, chars_ptr).log();
555}
556
557Module_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
564size_t Module_Param_Compound::get_size() const {
565 return values.size();
566}
567
568Module_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
573void 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
584void Module_Param_Compound::add_elem(Module_Param* value) {
585 value->set_parent(this);
586 values.push_back(value);
587}
588
589void 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
597char* 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
613void 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 675void 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 691bool Ttcn_String_Parsing::string_parsing = false;
This page took 0.048184 seconds and 5 git commands to generate.