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
17 * Szabo, Janos Zoltan – initial implementation
20 ******************************************************************************/
23 #include "Parameters.h"
24 #include "Param_Types.hh"
27 #include "TitanLoggerApi.hh"
29 #include "../common/dbgnew.hh"
31 Default_Base::Default_Base(const char *par_altstep_name
)
33 default_id
= TTCN_Default::activate(this);
34 altstep_name
= par_altstep_name
;
35 TTCN_Logger::log_defaultop_activate(par_altstep_name
, default_id
);
38 Default_Base::~Default_Base()
40 TTCN_Logger::log_defaultop_deactivate(altstep_name
, default_id
);
43 void Default_Base::log() const
45 TTCN_Logger::log_event("default reference: altstep: %s, id: %u",
46 altstep_name
, default_id
);
49 // a little hack to create a pointer constant other than NULL
50 // by taking the address of a memory object used for nothing
51 static Default_Base
*dummy_ptr
= NULL
;
52 static Default_Base
* const UNBOUND_DEFAULT
= (Default_Base
*)&dummy_ptr
;
56 default_ptr
= UNBOUND_DEFAULT
;
59 DEFAULT::DEFAULT(component other_value
)
61 if (other_value
!= NULL_COMPREF
)
62 TTCN_error("Initialization from an invalid default reference.");
66 DEFAULT::DEFAULT(Default_Base
*other_value
)
68 default_ptr
= other_value
;
71 DEFAULT::DEFAULT(const DEFAULT
& other_value
)
72 : Base_Type(other_value
)
74 if (other_value
.default_ptr
== UNBOUND_DEFAULT
)
75 TTCN_error("Copying an unbound default reference.");
76 default_ptr
= other_value
.default_ptr
;
79 DEFAULT
& DEFAULT::operator=(component other_value
)
81 if (other_value
!= NULL_COMPREF
)
82 TTCN_error("Assignment of an invalid default reference.");
87 DEFAULT
& DEFAULT::operator=(Default_Base
*other_value
)
89 default_ptr
= other_value
;
93 DEFAULT
& DEFAULT::operator=(const DEFAULT
& other_value
)
95 if (other_value
.default_ptr
== UNBOUND_DEFAULT
)
96 TTCN_error("Assignment of an unbound default reference.");
97 default_ptr
= other_value
.default_ptr
;
101 boolean
DEFAULT::operator==(component other_value
) const
103 if (default_ptr
== UNBOUND_DEFAULT
) TTCN_error("The left operand of "
104 "comparison is an unbound default reference.");
105 if (other_value
!= NULL_COMPREF
)
106 TTCN_error("Comparison of an invalid default value.");
107 return default_ptr
== NULL
;
110 boolean
DEFAULT::operator==(Default_Base
*other_value
) const
112 if (default_ptr
== UNBOUND_DEFAULT
) TTCN_error("The left operand of "
113 "comparison is an unbound default reference.");
114 return default_ptr
== other_value
;
117 boolean
DEFAULT::operator==(const DEFAULT
& other_value
) const
119 if (default_ptr
== UNBOUND_DEFAULT
) TTCN_error("The left operand of "
120 "comparison is an unbound default reference.");
121 if (other_value
.default_ptr
== UNBOUND_DEFAULT
) TTCN_error("The right "
122 "operand of comparison is an unbound default reference.");
123 return default_ptr
== other_value
.default_ptr
;
126 DEFAULT::operator Default_Base
*() const
128 if (default_ptr
== UNBOUND_DEFAULT
)
129 TTCN_error("Using the value of an unbound default reference.");
133 boolean
DEFAULT::is_bound() const
135 return default_ptr
!= UNBOUND_DEFAULT
; // what about NULL ?
138 boolean
DEFAULT::is_value() const
140 return default_ptr
!= UNBOUND_DEFAULT
; // what about NULL ?
143 void DEFAULT::clean_up()
145 default_ptr
= UNBOUND_DEFAULT
;
148 void DEFAULT::log() const
150 TTCN_Default::log(default_ptr
);
153 void DEFAULT::set_param(Module_Param
& param
) {
154 param
.basic_check(Module_Param::BC_VALUE
, "default reference (null) value");
155 Module_Param_Ptr mp
= ¶m
;
156 if (param
.get_type() == Module_Param::MP_Reference
) {
157 mp
= param
.get_referenced_param();
159 if (mp
->get_type()!=Module_Param::MP_Ttcn_Null
) param
.type_error("default reference (null) value");
163 Module_Param
* DEFAULT::get_param(Module_Param_Name
& /* param_name */) const
166 return new Module_Param_Unbound();
168 return new Module_Param_Ttcn_Null();
171 void DEFAULT::encode_text(Text_Buf
&) const
173 TTCN_error("Default references cannot be sent to other test components.");
176 void DEFAULT::decode_text(Text_Buf
&)
178 TTCN_error("Default references cannot be received from other test "
182 boolean
operator==(component default_value
, const DEFAULT
& other_value
)
184 if (default_value
!= NULL_COMPREF
) TTCN_error("The left operand of "
185 "comparison is an invalid default reference.");
186 if (other_value
.default_ptr
== UNBOUND_DEFAULT
) TTCN_error("The right "
187 "operand of comparison is an unbound default reference.");
188 return other_value
.default_ptr
== NULL
;
191 boolean
operator==(Default_Base
*default_value
, const DEFAULT
& other_value
)
193 if (other_value
.default_ptr
== UNBOUND_DEFAULT
) TTCN_error("The right "
194 "operand of comparison is an unbound default reference.");
195 return default_value
== other_value
.default_ptr
;
198 void DEFAULT_template::clean_up()
200 if (template_selection
== VALUE_LIST
||
201 template_selection
== COMPLEMENTED_LIST
)
202 delete [] value_list
.list_value
;
203 template_selection
= UNINITIALIZED_TEMPLATE
;
206 void DEFAULT_template::copy_template(const DEFAULT_template
& other_value
)
208 switch (other_value
.template_selection
) {
210 single_value
= other_value
.single_value
;
217 case COMPLEMENTED_LIST
:
218 value_list
.n_values
= other_value
.value_list
.n_values
;
219 value_list
.list_value
= new DEFAULT_template
[value_list
.n_values
];
220 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
221 value_list
.list_value
[i
].copy_template(
222 other_value
.value_list
.list_value
[i
]);
225 TTCN_error("Copying an uninitialized/unsupported default reference "
228 set_selection(other_value
);
231 DEFAULT_template::DEFAULT_template()
236 DEFAULT_template::DEFAULT_template(template_sel other_value
)
237 : Base_Template(other_value
)
239 check_single_selection(other_value
);
242 DEFAULT_template::DEFAULT_template(component other_value
)
243 : Base_Template(SPECIFIC_VALUE
)
245 if (other_value
!= NULL_COMPREF
)
246 TTCN_error("Creating a template from an invalid default reference.");
250 DEFAULT_template::DEFAULT_template(Default_Base
*other_value
)
251 : Base_Template(SPECIFIC_VALUE
)
253 single_value
= other_value
;
256 DEFAULT_template::DEFAULT_template(const DEFAULT
& other_value
)
257 : Base_Template(SPECIFIC_VALUE
)
259 if (other_value
.default_ptr
== UNBOUND_DEFAULT
)
260 TTCN_error("Creating a template from an unbound default reference.");
261 single_value
= other_value
.default_ptr
;
264 DEFAULT_template::DEFAULT_template(const OPTIONAL
<DEFAULT
>& other_value
)
266 switch (other_value
.get_selection()) {
267 case OPTIONAL_PRESENT
:
268 set_selection(SPECIFIC_VALUE
);
269 single_value
= (Default_Base
*)(const DEFAULT
&)other_value
;
272 set_selection(OMIT_VALUE
);
275 TTCN_error("Creating a default reference template from an unbound "
280 DEFAULT_template::DEFAULT_template(const DEFAULT_template
& other_value
)
283 copy_template(other_value
);
286 DEFAULT_template::~DEFAULT_template()
291 DEFAULT_template
& DEFAULT_template::operator=(template_sel other_value
)
293 check_single_selection(other_value
);
295 set_selection(other_value
);
299 DEFAULT_template
& DEFAULT_template::operator=(component other_value
)
301 if (other_value
!= NULL_COMPREF
)
302 TTCN_error("Assignment of an invalid default reference to a template.");
304 set_selection(SPECIFIC_VALUE
);
309 DEFAULT_template
& DEFAULT_template::operator=(Default_Base
*other_value
)
312 set_selection(SPECIFIC_VALUE
);
313 single_value
= other_value
;
317 DEFAULT_template
& DEFAULT_template::operator=(const DEFAULT
& other_value
)
319 if (other_value
.default_ptr
== UNBOUND_DEFAULT
)
320 TTCN_error("Assignment of an unbound default reference to a template.");
322 set_selection(SPECIFIC_VALUE
);
323 single_value
= other_value
.default_ptr
;
327 DEFAULT_template
& DEFAULT_template::operator=
328 (const OPTIONAL
<DEFAULT
>& other_value
)
331 switch (other_value
.get_selection()) {
332 case OPTIONAL_PRESENT
:
333 set_selection(SPECIFIC_VALUE
);
334 single_value
= (Default_Base
*)(const DEFAULT
&)other_value
;
337 set_selection(OMIT_VALUE
);
340 TTCN_error("Assignment of an unbound optional field to a default "
341 "reference template.");
346 DEFAULT_template
& DEFAULT_template::operator=
347 (const DEFAULT_template
& other_value
)
349 if (&other_value
!= this) {
351 copy_template(other_value
);
356 boolean
DEFAULT_template::match(component other_value
,
357 boolean
/* legacy */) const
359 if (other_value
== NULL_COMPREF
) return FALSE
;
360 return match((Default_Base
*)NULL
);
363 boolean
DEFAULT_template::match(Default_Base
*other_value
,
364 boolean
/* legacy */) const
366 if (other_value
== UNBOUND_DEFAULT
) return FALSE
;
367 switch (template_selection
) {
369 return single_value
== other_value
;
376 case COMPLEMENTED_LIST
:
377 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
378 if (value_list
.list_value
[i
].match(other_value
))
379 return template_selection
== VALUE_LIST
;
380 return template_selection
== COMPLEMENTED_LIST
;
382 TTCN_error("Matching with an uninitialized/unsupported default "
383 "reference template.");
388 boolean
DEFAULT_template::match(const DEFAULT
& other_value
,
389 boolean
/* legacy */) const
391 if (!other_value
.is_bound()) return FALSE
;
392 return match(other_value
.default_ptr
);
395 Default_Base
*DEFAULT_template::valueof() const
397 if (template_selection
!= SPECIFIC_VALUE
|| is_ifpresent
)
398 TTCN_error("Performing a valueof or send operation on a non-specific "
399 "default reference template.");
403 void DEFAULT_template::set_type(template_sel template_type
,
404 unsigned int list_length
)
406 if (template_type
!= VALUE_LIST
&& template_type
!= COMPLEMENTED_LIST
)
407 TTCN_error("Setting an invalid list type for a default reference "
410 set_selection(template_type
);
411 value_list
.n_values
= list_length
;
412 value_list
.list_value
= new DEFAULT_template
[list_length
];
415 DEFAULT_template
& DEFAULT_template::list_item(unsigned int list_index
)
417 if (template_selection
!= VALUE_LIST
&&
418 template_selection
!= COMPLEMENTED_LIST
) TTCN_error("Accessing a list "
419 "element of a non-list default reference template.");
420 if (list_index
>= value_list
.n_values
) TTCN_error("Index overflow in a "
421 "default reference value list template.");
422 return value_list
.list_value
[list_index
];
425 void DEFAULT_template::log() const
427 switch (template_selection
) {
429 TTCN_Default::log(single_value
);
431 case COMPLEMENTED_LIST
:
432 TTCN_Logger::log_event_str("complement ");
435 TTCN_Logger::log_char('(');
436 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++) {
437 if (i
> 0) TTCN_Logger::log_event_str(", ");
438 value_list
.list_value
[i
].log();
440 TTCN_Logger::log_char(')');
449 void DEFAULT_template::log_match(const DEFAULT
& match_value
,
450 boolean
/* legacy */) const
452 if (TTCN_Logger::VERBOSITY_COMPACT
== TTCN_Logger::get_matching_verbosity()
453 && TTCN_Logger::get_logmatch_buffer_len() != 0) {
454 TTCN_Logger::print_logmatch_buffer();
455 TTCN_Logger::log_event_str(" := ");
458 TTCN_Logger::log_event_str(" with ");
460 if(match(match_value
))TTCN_Logger::log_event_str(" matched");
461 else TTCN_Logger::log_event_str(" unmatched");
464 void DEFAULT_template::set_param(Module_Param
& param
) {
465 param
.basic_check(Module_Param::BC_TEMPLATE
, "default reference (null) template");
466 Module_Param_Ptr mp
= ¶m
;
467 if (param
.get_type() == Module_Param::MP_Reference
) {
468 mp
= param
.get_referenced_param();
470 switch (mp
->get_type()) {
471 case Module_Param::MP_Omit
:
474 case Module_Param::MP_Any
:
477 case Module_Param::MP_AnyOrNone
:
480 case Module_Param::MP_List_Template
:
481 case Module_Param::MP_ComplementList_Template
: {
482 DEFAULT_template temp
;
483 temp
.set_type(mp
->get_type() == Module_Param::MP_List_Template
?
484 VALUE_LIST
: COMPLEMENTED_LIST
, mp
->get_size());
485 for (size_t i
=0; i
<mp
->get_size(); i
++) {
486 temp
.list_item(i
).set_param(*mp
->get_elem(i
));
490 case Module_Param::MP_Ttcn_Null
:
491 *this = DEFAULT(NULL_COMPREF
);
494 param
.type_error("default reference (null) template");
496 is_ifpresent
= param
.get_ifpresent() || mp
->get_ifpresent();
499 Module_Param
* DEFAULT_template::get_param(Module_Param_Name
& param_name
) const
501 Module_Param
* mp
= NULL
;
502 switch (template_selection
) {
503 case UNINITIALIZED_TEMPLATE
:
504 mp
= new Module_Param_Unbound();
507 mp
= new Module_Param_Omit();
510 mp
= new Module_Param_Any();
513 mp
= new Module_Param_AnyOrNone();
516 mp
= new Module_Param_Ttcn_Null();
519 case COMPLEMENTED_LIST
: {
520 if (template_selection
== VALUE_LIST
) {
521 mp
= new Module_Param_List_Template();
524 mp
= new Module_Param_ComplementList_Template();
526 for (size_t i
= 0; i
< value_list
.n_values
; ++i
) {
527 mp
->add_elem(value_list
.list_value
[i
].get_param(param_name
));
539 void DEFAULT_template::encode_text(Text_Buf
&) const
541 TTCN_error("Default reference templates cannot be sent to other test "
545 void DEFAULT_template::decode_text(Text_Buf
&)
547 TTCN_error("Default reference templates cannot be received from other test "
551 boolean
DEFAULT_template::is_present(boolean legacy
/* = FALSE */) const
553 if (template_selection
==UNINITIALIZED_TEMPLATE
) return FALSE
;
554 return !match_omit(legacy
);
557 boolean
DEFAULT_template::match_omit(boolean legacy
/* = FALSE */) const
559 if (is_ifpresent
) return TRUE
;
560 switch (template_selection
) {
565 case COMPLEMENTED_LIST
:
567 // legacy behavior: 'omit' can appear in the value/complement list
568 for (unsigned int i
=0; i
<value_list
.n_values
; i
++)
569 if (value_list
.list_value
[i
].match_omit())
570 return template_selection
==VALUE_LIST
;
571 return template_selection
==COMPLEMENTED_LIST
;
580 #ifndef TITAN_RUNTIME_2
581 void DEFAULT_template::check_restriction(template_res t_res
, const char* t_name
,
582 boolean legacy
/* = FALSE */) const
584 if (template_selection
==UNINITIALIZED_TEMPLATE
) return;
585 switch ((t_name
&&(t_res
==TR_VALUE
))?TR_OMIT
:t_res
) {
587 if (!is_ifpresent
&& template_selection
==SPECIFIC_VALUE
) return;
590 if (!is_ifpresent
&& (template_selection
==OMIT_VALUE
||
591 template_selection
==SPECIFIC_VALUE
)) return;
594 if (!match_omit(legacy
)) return;
599 TTCN_error("Restriction `%s' on template of type %s violated.",
600 get_res_name(t_res
), t_name
? t_name
: "default reference");
605 unsigned int TTCN_Default::default_count
= 0, TTCN_Default::backup_count
= 0;
606 Default_Base
*TTCN_Default::list_head
= NULL
, *TTCN_Default::list_tail
= NULL
,
607 *TTCN_Default::backup_head
= NULL
, *TTCN_Default::backup_tail
= NULL
;
608 boolean
TTCN_Default::control_defaults_saved
= FALSE
;
610 unsigned int TTCN_Default::activate(Default_Base
*new_default
)
612 new_default
->default_prev
= list_tail
;
613 new_default
->default_next
= NULL
;
614 if (list_tail
!= NULL
) list_tail
->default_next
= new_default
;
615 else list_head
= new_default
;
616 list_tail
= new_default
;
617 return ++default_count
;
620 void TTCN_Default::deactivate(Default_Base
*removable_default
)
622 for (Default_Base
*default_iter
= list_head
; default_iter
!= NULL
;
623 default_iter
= default_iter
->default_next
) {
624 if (default_iter
== removable_default
) {
625 if (removable_default
->default_prev
!= NULL
)
626 removable_default
->default_prev
->default_next
=
627 removable_default
->default_next
;
628 else list_head
= removable_default
->default_next
;
629 if (removable_default
->default_next
!= NULL
)
630 removable_default
->default_next
->default_prev
=
631 removable_default
->default_prev
;
632 else list_tail
= removable_default
->default_prev
;
633 delete removable_default
;
637 TTCN_warning("Performing a deactivate operation on an inactive "
638 "default reference.");
641 void TTCN_Default::deactivate(const DEFAULT
&removable_default
)
643 if (removable_default
.default_ptr
== UNBOUND_DEFAULT
)
644 TTCN_error("Performing a deactivate operation on an unbound default "
646 if (removable_default
.default_ptr
== NULL
)
647 TTCN_Logger::log_defaultop_deactivate(NULL
, 0);
648 else deactivate(removable_default
.default_ptr
);
651 void TTCN_Default::deactivate_all()
653 while (list_head
!= NULL
) deactivate(list_head
);
656 alt_status
TTCN_Default::try_altsteps()
658 alt_status ret_val
= ALT_NO
;
659 for (Default_Base
*default_iter
= list_tail
; default_iter
!= NULL
; ) {
660 Default_Base
*prev_iter
= default_iter
->default_prev
;
661 unsigned int default_id
= default_iter
->default_id
;
662 const char *altstep_name
= default_iter
->altstep_name
;
663 switch (default_iter
->call_altstep()) {
665 TTCN_Logger::log_defaultop_exit(altstep_name
, default_id
,
666 TitanLoggerApi::DefaultEnd::finish
);
669 TTCN_Logger::log_defaultop_exit(altstep_name
, default_id
,
670 TitanLoggerApi::DefaultEnd::repeat__
);
673 TTCN_Logger::log_defaultop_exit(altstep_name
, default_id
,
674 TitanLoggerApi::DefaultEnd::break__
);
682 default_iter
= prev_iter
;
687 void TTCN_Default::log(Default_Base
*default_ptr
)
689 if (default_ptr
== UNBOUND_DEFAULT
) TTCN_Logger::log_event_unbound();
690 else if (default_ptr
== NULL
) TTCN_Logger::log_event_str("null");
692 for (Default_Base
*default_iter
= list_head
; default_iter
!= NULL
;
693 default_iter
= default_iter
->default_next
) {
694 if (default_iter
== default_ptr
) {
699 TTCN_Logger::log_event_str("default reference: already deactivated");
703 void TTCN_Default::save_control_defaults()
705 if (control_defaults_saved
)
706 TTCN_error("Internal error: Control part defaults are already saved.");
707 // put the list of control part defaults into the backup
708 backup_head
= list_head
;
710 backup_tail
= list_tail
;
712 backup_count
= default_count
;
714 control_defaults_saved
= TRUE
;
717 void TTCN_Default::restore_control_defaults()
719 if (!control_defaults_saved
)
720 TTCN_error("Internal error: Control part defaults are not saved.");
721 if (list_head
!= NULL
)
722 TTCN_error("Internal error: There are defaults timers. "
723 "Control part defaults cannot be restored.");
724 // restore the list of control part defaults from the backup
725 list_head
= backup_head
;
727 list_tail
= backup_tail
;
729 default_count
= backup_count
;
731 control_defaults_saved
= FALSE
;
734 void TTCN_Default::reset_counter()
736 if (control_defaults_saved
) TTCN_error("Internal error: Default counter "
737 "cannot be reset when the control part defaults are saved.");
738 if (list_head
!= NULL
) TTCN_error("Internal error: Default counter "
739 "cannot be reset when there are active defaults.");