1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 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 ///////////////////////////////////////////////////////////////////////////////
10 #include "Parameters.h"
11 #include "Param_Types.hh"
14 #include "TitanLoggerApi.hh"
16 #include "../common/dbgnew.hh"
18 Default_Base::Default_Base(const char *par_altstep_name
)
20 default_id
= TTCN_Default::activate(this);
21 altstep_name
= par_altstep_name
;
22 TTCN_Logger::log_defaultop_activate(par_altstep_name
, default_id
);
25 Default_Base::~Default_Base()
27 TTCN_Logger::log_defaultop_deactivate(altstep_name
, default_id
);
30 void Default_Base::log() const
32 TTCN_Logger::log_event("default reference: altstep: %s, id: %u",
33 altstep_name
, default_id
);
36 // a little hack to create a pointer constant other than NULL
37 // by taking the address of a memory object used for nothing
38 static Default_Base
*dummy_ptr
= NULL
;
39 static Default_Base
* const UNBOUND_DEFAULT
= (Default_Base
*)&dummy_ptr
;
43 default_ptr
= UNBOUND_DEFAULT
;
46 DEFAULT::DEFAULT(component other_value
)
48 if (other_value
!= NULL_COMPREF
)
49 TTCN_error("Initialization from an invalid default reference.");
53 DEFAULT::DEFAULT(Default_Base
*other_value
)
55 default_ptr
= other_value
;
58 DEFAULT::DEFAULT(const DEFAULT
& other_value
)
59 : Base_Type(other_value
)
61 if (other_value
.default_ptr
== UNBOUND_DEFAULT
)
62 TTCN_error("Copying an unbound default reference.");
63 default_ptr
= other_value
.default_ptr
;
66 DEFAULT
& DEFAULT::operator=(component other_value
)
68 if (other_value
!= NULL_COMPREF
)
69 TTCN_error("Assignment of an invalid default reference.");
74 DEFAULT
& DEFAULT::operator=(Default_Base
*other_value
)
76 default_ptr
= other_value
;
80 DEFAULT
& DEFAULT::operator=(const DEFAULT
& other_value
)
82 if (other_value
.default_ptr
== UNBOUND_DEFAULT
)
83 TTCN_error("Assignment of an unbound default reference.");
84 default_ptr
= other_value
.default_ptr
;
88 boolean
DEFAULT::operator==(component other_value
) const
90 if (default_ptr
== UNBOUND_DEFAULT
) TTCN_error("The left operand of "
91 "comparison is an unbound default reference.");
92 if (other_value
!= NULL_COMPREF
)
93 TTCN_error("Comparison of an invalid default value.");
94 return default_ptr
== NULL
;
97 boolean
DEFAULT::operator==(Default_Base
*other_value
) const
99 if (default_ptr
== UNBOUND_DEFAULT
) TTCN_error("The left operand of "
100 "comparison is an unbound default reference.");
101 return default_ptr
== other_value
;
104 boolean
DEFAULT::operator==(const DEFAULT
& other_value
) const
106 if (default_ptr
== UNBOUND_DEFAULT
) TTCN_error("The left operand of "
107 "comparison is an unbound default reference.");
108 if (other_value
.default_ptr
== UNBOUND_DEFAULT
) TTCN_error("The right "
109 "operand of comparison is an unbound default reference.");
110 return default_ptr
== other_value
.default_ptr
;
113 DEFAULT::operator Default_Base
*() const
115 if (default_ptr
== UNBOUND_DEFAULT
)
116 TTCN_error("Using the value of an unbound default reference.");
120 boolean
DEFAULT::is_bound() const
122 return default_ptr
!= UNBOUND_DEFAULT
; // what about NULL ?
125 boolean
DEFAULT::is_value() const
127 return default_ptr
!= UNBOUND_DEFAULT
; // what about NULL ?
130 void DEFAULT::clean_up()
132 default_ptr
= UNBOUND_DEFAULT
;
135 void DEFAULT::log() const
137 TTCN_Default::log(default_ptr
);
140 void DEFAULT::set_param(Module_Param
& param
) {
141 param
.basic_check(Module_Param::BC_VALUE
, "default reference (null) value");
142 if (param
.get_type()!=Module_Param::MP_Ttcn_Null
) param
.type_error("default reference (null) value");
146 void DEFAULT::encode_text(Text_Buf
&) const
148 TTCN_error("Default references cannot be sent to other test components.");
151 void DEFAULT::decode_text(Text_Buf
&)
153 TTCN_error("Default references cannot be received from other test "
157 boolean
operator==(component default_value
, const DEFAULT
& other_value
)
159 if (default_value
!= NULL_COMPREF
) TTCN_error("The left operand of "
160 "comparison is an invalid default reference.");
161 if (other_value
.default_ptr
== UNBOUND_DEFAULT
) TTCN_error("The right "
162 "operand of comparison is an unbound default reference.");
163 return other_value
.default_ptr
== NULL
;
166 boolean
operator==(Default_Base
*default_value
, const DEFAULT
& other_value
)
168 if (other_value
.default_ptr
== UNBOUND_DEFAULT
) TTCN_error("The right "
169 "operand of comparison is an unbound default reference.");
170 return default_value
== other_value
.default_ptr
;
173 void DEFAULT_template::clean_up()
175 if (template_selection
== VALUE_LIST
||
176 template_selection
== COMPLEMENTED_LIST
)
177 delete [] value_list
.list_value
;
178 template_selection
= UNINITIALIZED_TEMPLATE
;
181 void DEFAULT_template::copy_template(const DEFAULT_template
& other_value
)
183 switch (other_value
.template_selection
) {
185 single_value
= other_value
.single_value
;
192 case COMPLEMENTED_LIST
:
193 value_list
.n_values
= other_value
.value_list
.n_values
;
194 value_list
.list_value
= new DEFAULT_template
[value_list
.n_values
];
195 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
196 value_list
.list_value
[i
].copy_template(
197 other_value
.value_list
.list_value
[i
]);
200 TTCN_error("Copying an uninitialized/unsupported default reference "
203 set_selection(other_value
);
206 DEFAULT_template::DEFAULT_template()
211 DEFAULT_template::DEFAULT_template(template_sel other_value
)
212 : Base_Template(other_value
)
214 check_single_selection(other_value
);
217 DEFAULT_template::DEFAULT_template(component other_value
)
218 : Base_Template(SPECIFIC_VALUE
)
220 if (other_value
!= NULL_COMPREF
)
221 TTCN_error("Creating a template from an invalid default reference.");
225 DEFAULT_template::DEFAULT_template(Default_Base
*other_value
)
226 : Base_Template(SPECIFIC_VALUE
)
228 single_value
= other_value
;
231 DEFAULT_template::DEFAULT_template(const DEFAULT
& other_value
)
232 : Base_Template(SPECIFIC_VALUE
)
234 if (other_value
.default_ptr
== UNBOUND_DEFAULT
)
235 TTCN_error("Creating a template from an unbound default reference.");
236 single_value
= other_value
.default_ptr
;
239 DEFAULT_template::DEFAULT_template(const OPTIONAL
<DEFAULT
>& other_value
)
241 switch (other_value
.get_selection()) {
242 case OPTIONAL_PRESENT
:
243 set_selection(SPECIFIC_VALUE
);
244 single_value
= (Default_Base
*)(const DEFAULT
&)other_value
;
247 set_selection(OMIT_VALUE
);
250 TTCN_error("Creating a default reference template from an unbound "
255 DEFAULT_template::DEFAULT_template(const DEFAULT_template
& other_value
)
258 copy_template(other_value
);
261 DEFAULT_template::~DEFAULT_template()
266 DEFAULT_template
& DEFAULT_template::operator=(template_sel other_value
)
268 check_single_selection(other_value
);
270 set_selection(other_value
);
274 DEFAULT_template
& DEFAULT_template::operator=(component other_value
)
276 if (other_value
!= NULL_COMPREF
)
277 TTCN_error("Assignment of an invalid default reference to a template.");
279 set_selection(SPECIFIC_VALUE
);
284 DEFAULT_template
& DEFAULT_template::operator=(Default_Base
*other_value
)
287 set_selection(SPECIFIC_VALUE
);
288 single_value
= other_value
;
292 DEFAULT_template
& DEFAULT_template::operator=(const DEFAULT
& other_value
)
294 if (other_value
.default_ptr
== UNBOUND_DEFAULT
)
295 TTCN_error("Assignment of an unbound default reference to a template.");
297 set_selection(SPECIFIC_VALUE
);
298 single_value
= other_value
.default_ptr
;
302 DEFAULT_template
& DEFAULT_template::operator=
303 (const OPTIONAL
<DEFAULT
>& other_value
)
306 switch (other_value
.get_selection()) {
307 case OPTIONAL_PRESENT
:
308 set_selection(SPECIFIC_VALUE
);
309 single_value
= (Default_Base
*)(const DEFAULT
&)other_value
;
312 set_selection(OMIT_VALUE
);
315 TTCN_error("Assignment of an unbound optional field to a default "
316 "reference template.");
321 DEFAULT_template
& DEFAULT_template::operator=
322 (const DEFAULT_template
& other_value
)
324 if (&other_value
!= this) {
326 copy_template(other_value
);
331 boolean
DEFAULT_template::match(component other_value
) const
333 if (other_value
== NULL_COMPREF
) return FALSE
;
334 return match((Default_Base
*)NULL
);
337 boolean
DEFAULT_template::match(Default_Base
*other_value
) const
339 if (other_value
== UNBOUND_DEFAULT
) return FALSE
;
340 switch (template_selection
) {
342 return single_value
== other_value
;
349 case COMPLEMENTED_LIST
:
350 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
351 if (value_list
.list_value
[i
].match(other_value
))
352 return template_selection
== VALUE_LIST
;
353 return template_selection
== COMPLEMENTED_LIST
;
355 TTCN_error("Matching with an uninitialized/unsupported default "
356 "reference template.");
361 boolean
DEFAULT_template::match(const DEFAULT
& other_value
) const
363 if (!other_value
.is_bound()) return FALSE
;
364 return match(other_value
.default_ptr
);
367 Default_Base
*DEFAULT_template::valueof() const
369 if (template_selection
!= SPECIFIC_VALUE
|| is_ifpresent
)
370 TTCN_error("Performing a valueof or send operation on a non-specific "
371 "default reference template.");
375 void DEFAULT_template::set_type(template_sel template_type
,
376 unsigned int list_length
)
378 if (template_type
!= VALUE_LIST
&& template_type
!= COMPLEMENTED_LIST
)
379 TTCN_error("Setting an invalid list type for a default reference "
382 set_selection(template_type
);
383 value_list
.n_values
= list_length
;
384 value_list
.list_value
= new DEFAULT_template
[list_length
];
387 DEFAULT_template
& DEFAULT_template::list_item(unsigned int list_index
)
389 if (template_selection
!= VALUE_LIST
&&
390 template_selection
!= COMPLEMENTED_LIST
) TTCN_error("Accessing a list "
391 "element of a non-list default reference template.");
392 if (list_index
>= value_list
.n_values
) TTCN_error("Index overflow in a "
393 "default reference value list template.");
394 return value_list
.list_value
[list_index
];
397 void DEFAULT_template::log() const
399 switch (template_selection
) {
401 TTCN_Default::log(single_value
);
403 case COMPLEMENTED_LIST
:
404 TTCN_Logger::log_event_str("complement ");
407 TTCN_Logger::log_char('(');
408 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++) {
409 if (i
> 0) TTCN_Logger::log_event_str(", ");
410 value_list
.list_value
[i
].log();
412 TTCN_Logger::log_char(')');
421 void DEFAULT_template::log_match(const DEFAULT
& match_value
) const
423 if (TTCN_Logger::VERBOSITY_COMPACT
== TTCN_Logger::get_matching_verbosity()
424 && TTCN_Logger::get_logmatch_buffer_len() != 0) {
425 TTCN_Logger::print_logmatch_buffer();
426 TTCN_Logger::log_event_str(" := ");
429 TTCN_Logger::log_event_str(" with ");
431 if(match(match_value
))TTCN_Logger::log_event_str(" matched");
432 else TTCN_Logger::log_event_str(" unmatched");
435 void DEFAULT_template::set_param(Module_Param
& param
) {
436 param
.basic_check(Module_Param::BC_TEMPLATE
, "default reference (null) template");
437 switch (param
.get_type()) {
438 case Module_Param::MP_Omit
:
441 case Module_Param::MP_Any
:
444 case Module_Param::MP_AnyOrNone
:
447 case Module_Param::MP_List_Template
:
448 case Module_Param::MP_ComplementList_Template
:
449 set_type(param
.get_type()==Module_Param::MP_List_Template
? VALUE_LIST
: COMPLEMENTED_LIST
, param
.get_size());
450 for (size_t i
=0; i
<param
.get_size(); i
++) {
451 list_item(i
).set_param(*param
.get_elem(i
));
454 case Module_Param::MP_Ttcn_Null
:
455 *this = DEFAULT(NULL_COMPREF
);
458 param
.type_error("default reference (null) template");
460 is_ifpresent
= param
.get_ifpresent();
463 void DEFAULT_template::encode_text(Text_Buf
&) const
465 TTCN_error("Default reference templates cannot be sent to other test "
469 void DEFAULT_template::decode_text(Text_Buf
&)
471 TTCN_error("Default reference templates cannot be received from other test "
475 boolean
DEFAULT_template::is_present() const
477 if (template_selection
==UNINITIALIZED_TEMPLATE
) return FALSE
;
478 return !match_omit();
481 boolean
DEFAULT_template::match_omit() const
483 if (is_ifpresent
) return TRUE
;
484 switch (template_selection
) {
489 case COMPLEMENTED_LIST
:
490 for (unsigned int i
=0; i
<value_list
.n_values
; i
++)
491 if (value_list
.list_value
[i
].match_omit())
492 return template_selection
==VALUE_LIST
;
493 return template_selection
==COMPLEMENTED_LIST
;
500 #ifndef TITAN_RUNTIME_2
501 void DEFAULT_template::check_restriction(template_res t_res
, const char* t_name
) const
503 if (template_selection
==UNINITIALIZED_TEMPLATE
) return;
504 switch ((t_name
&&(t_res
==TR_VALUE
))?TR_OMIT
:t_res
) {
506 if (!is_ifpresent
&& template_selection
==SPECIFIC_VALUE
) return;
509 if (!is_ifpresent
&& (template_selection
==OMIT_VALUE
||
510 template_selection
==SPECIFIC_VALUE
)) return;
513 if (!match_omit()) return;
518 TTCN_error("Restriction `%s' on template of type %s violated.",
519 get_res_name(t_res
), t_name
? t_name
: "default reference");
524 unsigned int TTCN_Default::default_count
= 0, TTCN_Default::backup_count
= 0;
525 Default_Base
*TTCN_Default::list_head
= NULL
, *TTCN_Default::list_tail
= NULL
,
526 *TTCN_Default::backup_head
= NULL
, *TTCN_Default::backup_tail
= NULL
;
527 boolean
TTCN_Default::control_defaults_saved
= FALSE
;
529 unsigned int TTCN_Default::activate(Default_Base
*new_default
)
531 new_default
->default_prev
= list_tail
;
532 new_default
->default_next
= NULL
;
533 if (list_tail
!= NULL
) list_tail
->default_next
= new_default
;
534 else list_head
= new_default
;
535 list_tail
= new_default
;
536 return ++default_count
;
539 void TTCN_Default::deactivate(Default_Base
*removable_default
)
541 for (Default_Base
*default_iter
= list_head
; default_iter
!= NULL
;
542 default_iter
= default_iter
->default_next
) {
543 if (default_iter
== removable_default
) {
544 if (removable_default
->default_prev
!= NULL
)
545 removable_default
->default_prev
->default_next
=
546 removable_default
->default_next
;
547 else list_head
= removable_default
->default_next
;
548 if (removable_default
->default_next
!= NULL
)
549 removable_default
->default_next
->default_prev
=
550 removable_default
->default_prev
;
551 else list_tail
= removable_default
->default_prev
;
552 delete removable_default
;
556 TTCN_warning("Performing a deactivate operation on an inactive "
557 "default reference.");
560 void TTCN_Default::deactivate(const DEFAULT
&removable_default
)
562 if (removable_default
.default_ptr
== UNBOUND_DEFAULT
)
563 TTCN_error("Performing a deactivate operation on an unbound default "
565 if (removable_default
.default_ptr
== NULL
)
566 TTCN_Logger::log_defaultop_deactivate(NULL
, 0);
567 else deactivate(removable_default
.default_ptr
);
570 void TTCN_Default::deactivate_all()
572 while (list_head
!= NULL
) deactivate(list_head
);
575 alt_status
TTCN_Default::try_altsteps()
577 alt_status ret_val
= ALT_NO
;
578 for (Default_Base
*default_iter
= list_tail
; default_iter
!= NULL
; ) {
579 Default_Base
*prev_iter
= default_iter
->default_prev
;
580 unsigned int default_id
= default_iter
->default_id
;
581 const char *altstep_name
= default_iter
->altstep_name
;
582 switch (default_iter
->call_altstep()) {
584 TTCN_Logger::log_defaultop_exit(altstep_name
, default_id
,
585 TitanLoggerApi::DefaultEnd::finish
);
588 TTCN_Logger::log_defaultop_exit(altstep_name
, default_id
,
589 TitanLoggerApi::DefaultEnd::repeat__
);
592 TTCN_Logger::log_defaultop_exit(altstep_name
, default_id
,
593 TitanLoggerApi::DefaultEnd::break__
);
601 default_iter
= prev_iter
;
606 void TTCN_Default::log(Default_Base
*default_ptr
)
608 if (default_ptr
== UNBOUND_DEFAULT
) TTCN_Logger::log_event_unbound();
609 else if (default_ptr
== NULL
) TTCN_Logger::log_event_str("null");
611 for (Default_Base
*default_iter
= list_head
; default_iter
!= NULL
;
612 default_iter
= default_iter
->default_next
) {
613 if (default_iter
== default_ptr
) {
618 TTCN_Logger::log_event_str("default reference: already deactivated");
622 void TTCN_Default::save_control_defaults()
624 if (control_defaults_saved
)
625 TTCN_error("Internal error: Control part defaults are already saved.");
626 // put the list of control part defaults into the backup
627 backup_head
= list_head
;
629 backup_tail
= list_tail
;
631 backup_count
= default_count
;
633 control_defaults_saved
= TRUE
;
636 void TTCN_Default::restore_control_defaults()
638 if (!control_defaults_saved
)
639 TTCN_error("Internal error: Control part defaults are not saved.");
640 if (list_head
!= NULL
)
641 TTCN_error("Internal error: There are defaults timers. "
642 "Control part defaults cannot be restored.");
643 // restore the list of control part defaults from the backup
644 list_head
= backup_head
;
646 list_tail
= backup_tail
;
648 default_count
= backup_count
;
650 control_defaults_saved
= FALSE
;
653 void TTCN_Default::reset_counter()
655 if (control_defaults_saved
) TTCN_error("Internal error: Default counter "
656 "cannot be reset when the control part defaults are saved.");
657 if (list_head
!= NULL
) TTCN_error("Internal error: Default counter "
658 "cannot be reset when there are active defaults.");