Sync with 5.3.0
[deliverable/titan.core.git] / core / Default.cc
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 ///////////////////////////////////////////////////////////////////////////////
8 #include "Default.hh"
9
10 #include "Parameters.h"
11 #include "Param_Types.hh"
12 #include "Logger.hh"
13 #include "Error.hh"
14 #include "TitanLoggerApi.hh"
15
16 #include "../common/dbgnew.hh"
17
18 Default_Base::Default_Base(const char *par_altstep_name)
19 {
20 default_id = TTCN_Default::activate(this);
21 altstep_name = par_altstep_name;
22 TTCN_Logger::log_defaultop_activate(par_altstep_name, default_id);
23 }
24
25 Default_Base::~Default_Base()
26 {
27 TTCN_Logger::log_defaultop_deactivate(altstep_name, default_id);
28 }
29
30 void Default_Base::log() const
31 {
32 TTCN_Logger::log_event("default reference: altstep: %s, id: %u",
33 altstep_name, default_id);
34 }
35
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;
40
41 DEFAULT::DEFAULT()
42 {
43 default_ptr = UNBOUND_DEFAULT;
44 }
45
46 DEFAULT::DEFAULT(component other_value)
47 {
48 if (other_value != NULL_COMPREF)
49 TTCN_error("Initialization from an invalid default reference.");
50 default_ptr = NULL;
51 }
52
53 DEFAULT::DEFAULT(Default_Base *other_value)
54 {
55 default_ptr = other_value;
56 }
57
58 DEFAULT::DEFAULT(const DEFAULT& other_value)
59 : Base_Type(other_value)
60 {
61 if (other_value.default_ptr == UNBOUND_DEFAULT)
62 TTCN_error("Copying an unbound default reference.");
63 default_ptr = other_value.default_ptr;
64 }
65
66 DEFAULT& DEFAULT::operator=(component other_value)
67 {
68 if (other_value != NULL_COMPREF)
69 TTCN_error("Assignment of an invalid default reference.");
70 default_ptr = NULL;
71 return *this;
72 }
73
74 DEFAULT& DEFAULT::operator=(Default_Base *other_value)
75 {
76 default_ptr = other_value;
77 return *this;
78 }
79
80 DEFAULT& DEFAULT::operator=(const DEFAULT& other_value)
81 {
82 if (other_value.default_ptr == UNBOUND_DEFAULT)
83 TTCN_error("Assignment of an unbound default reference.");
84 default_ptr = other_value.default_ptr;
85 return *this;
86 }
87
88 boolean DEFAULT::operator==(component other_value) const
89 {
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;
95 }
96
97 boolean DEFAULT::operator==(Default_Base *other_value) const
98 {
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;
102 }
103
104 boolean DEFAULT::operator==(const DEFAULT& other_value) const
105 {
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;
111 }
112
113 DEFAULT::operator Default_Base*() const
114 {
115 if (default_ptr == UNBOUND_DEFAULT)
116 TTCN_error("Using the value of an unbound default reference.");
117 return default_ptr;
118 }
119
120 boolean DEFAULT::is_bound() const
121 {
122 return default_ptr != UNBOUND_DEFAULT; // what about NULL ?
123 }
124
125 boolean DEFAULT::is_value() const
126 {
127 return default_ptr != UNBOUND_DEFAULT; // what about NULL ?
128 }
129
130 void DEFAULT::clean_up()
131 {
132 default_ptr = UNBOUND_DEFAULT;
133 }
134
135 void DEFAULT::log() const
136 {
137 TTCN_Default::log(default_ptr);
138 }
139
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");
143 default_ptr = NULL;
144 }
145
146 void DEFAULT::encode_text(Text_Buf&) const
147 {
148 TTCN_error("Default references cannot be sent to other test components.");
149 }
150
151 void DEFAULT::decode_text(Text_Buf&)
152 {
153 TTCN_error("Default references cannot be received from other test "
154 "components.");
155 }
156
157 boolean operator==(component default_value, const DEFAULT& other_value)
158 {
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;
164 }
165
166 boolean operator==(Default_Base *default_value, const DEFAULT& other_value)
167 {
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;
171 }
172
173 void DEFAULT_template::clean_up()
174 {
175 if (template_selection == VALUE_LIST ||
176 template_selection == COMPLEMENTED_LIST)
177 delete [] value_list.list_value;
178 template_selection = UNINITIALIZED_TEMPLATE;
179 }
180
181 void DEFAULT_template::copy_template(const DEFAULT_template& other_value)
182 {
183 switch (other_value.template_selection) {
184 case SPECIFIC_VALUE:
185 single_value = other_value.single_value;
186 break;
187 case OMIT_VALUE:
188 case ANY_VALUE:
189 case ANY_OR_OMIT:
190 break;
191 case VALUE_LIST:
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]);
198 break;
199 default:
200 TTCN_error("Copying an uninitialized/unsupported default reference "
201 "template.");
202 }
203 set_selection(other_value);
204 }
205
206 DEFAULT_template::DEFAULT_template()
207 {
208
209 }
210
211 DEFAULT_template::DEFAULT_template(template_sel other_value)
212 : Base_Template(other_value)
213 {
214 check_single_selection(other_value);
215 }
216
217 DEFAULT_template::DEFAULT_template(component other_value)
218 : Base_Template(SPECIFIC_VALUE)
219 {
220 if (other_value != NULL_COMPREF)
221 TTCN_error("Creating a template from an invalid default reference.");
222 single_value = NULL;
223 }
224
225 DEFAULT_template::DEFAULT_template(Default_Base *other_value)
226 : Base_Template(SPECIFIC_VALUE)
227 {
228 single_value = other_value;
229 }
230
231 DEFAULT_template::DEFAULT_template(const DEFAULT& other_value)
232 : Base_Template(SPECIFIC_VALUE)
233 {
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;
237 }
238
239 DEFAULT_template::DEFAULT_template(const OPTIONAL<DEFAULT>& other_value)
240 {
241 switch (other_value.get_selection()) {
242 case OPTIONAL_PRESENT:
243 set_selection(SPECIFIC_VALUE);
244 single_value = (Default_Base*)(const DEFAULT&)other_value;
245 break;
246 case OPTIONAL_OMIT:
247 set_selection(OMIT_VALUE);
248 break;
249 default:
250 TTCN_error("Creating a default reference template from an unbound "
251 "optional field.");
252 }
253 }
254
255 DEFAULT_template::DEFAULT_template(const DEFAULT_template& other_value)
256 : Base_Template()
257 {
258 copy_template(other_value);
259 }
260
261 DEFAULT_template::~DEFAULT_template()
262 {
263 clean_up();
264 }
265
266 DEFAULT_template& DEFAULT_template::operator=(template_sel other_value)
267 {
268 check_single_selection(other_value);
269 clean_up();
270 set_selection(other_value);
271 return *this;
272 }
273
274 DEFAULT_template& DEFAULT_template::operator=(component other_value)
275 {
276 if (other_value != NULL_COMPREF)
277 TTCN_error("Assignment of an invalid default reference to a template.");
278 clean_up();
279 set_selection(SPECIFIC_VALUE);
280 single_value = NULL;
281 return *this;
282 }
283
284 DEFAULT_template& DEFAULT_template::operator=(Default_Base *other_value)
285 {
286 clean_up();
287 set_selection(SPECIFIC_VALUE);
288 single_value = other_value;
289 return *this;
290 }
291
292 DEFAULT_template& DEFAULT_template::operator=(const DEFAULT& other_value)
293 {
294 if (other_value.default_ptr == UNBOUND_DEFAULT)
295 TTCN_error("Assignment of an unbound default reference to a template.");
296 clean_up();
297 set_selection(SPECIFIC_VALUE);
298 single_value = other_value.default_ptr;
299 return *this;
300 }
301
302 DEFAULT_template& DEFAULT_template::operator=
303 (const OPTIONAL<DEFAULT>& other_value)
304 {
305 clean_up();
306 switch (other_value.get_selection()) {
307 case OPTIONAL_PRESENT:
308 set_selection(SPECIFIC_VALUE);
309 single_value = (Default_Base*)(const DEFAULT&)other_value;
310 break;
311 case OPTIONAL_OMIT:
312 set_selection(OMIT_VALUE);
313 break;
314 default:
315 TTCN_error("Assignment of an unbound optional field to a default "
316 "reference template.");
317 }
318 return *this;
319 }
320
321 DEFAULT_template& DEFAULT_template::operator=
322 (const DEFAULT_template& other_value)
323 {
324 if (&other_value != this) {
325 clean_up();
326 copy_template(other_value);
327 }
328 return *this;
329 }
330
331 boolean DEFAULT_template::match(component other_value) const
332 {
333 if (other_value == NULL_COMPREF) return FALSE;
334 return match((Default_Base*)NULL);
335 }
336
337 boolean DEFAULT_template::match(Default_Base *other_value) const
338 {
339 if (other_value == UNBOUND_DEFAULT) return FALSE;
340 switch (template_selection) {
341 case SPECIFIC_VALUE:
342 return single_value == other_value;
343 case OMIT_VALUE:
344 return FALSE;
345 case ANY_VALUE:
346 case ANY_OR_OMIT:
347 return TRUE;
348 case VALUE_LIST:
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;
354 default:
355 TTCN_error("Matching with an uninitialized/unsupported default "
356 "reference template.");
357 }
358 return FALSE;
359 }
360
361 boolean DEFAULT_template::match(const DEFAULT& other_value) const
362 {
363 if (!other_value.is_bound()) return FALSE;
364 return match(other_value.default_ptr);
365 }
366
367 Default_Base *DEFAULT_template::valueof() const
368 {
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.");
372 return single_value;
373 }
374
375 void DEFAULT_template::set_type(template_sel template_type,
376 unsigned int list_length)
377 {
378 if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
379 TTCN_error("Setting an invalid list type for a default reference "
380 "template.");
381 clean_up();
382 set_selection(template_type);
383 value_list.n_values = list_length;
384 value_list.list_value = new DEFAULT_template[list_length];
385 }
386
387 DEFAULT_template& DEFAULT_template::list_item(unsigned int list_index)
388 {
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];
395 }
396
397 void DEFAULT_template::log() const
398 {
399 switch (template_selection) {
400 case SPECIFIC_VALUE:
401 TTCN_Default::log(single_value);
402 break;
403 case COMPLEMENTED_LIST:
404 TTCN_Logger::log_event_str("complement ");
405 // no break
406 case VALUE_LIST:
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();
411 }
412 TTCN_Logger::log_char(')');
413 break;
414 default:
415 log_generic();
416 break;
417 }
418 log_ifpresent();
419 }
420
421 void DEFAULT_template::log_match(const DEFAULT& match_value) const
422 {
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(" := ");
427 }
428 match_value.log();
429 TTCN_Logger::log_event_str(" with ");
430 log();
431 if(match(match_value))TTCN_Logger::log_event_str(" matched");
432 else TTCN_Logger::log_event_str(" unmatched");
433 }
434
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:
439 *this = OMIT_VALUE;
440 break;
441 case Module_Param::MP_Any:
442 *this = ANY_VALUE;
443 break;
444 case Module_Param::MP_AnyOrNone:
445 *this = ANY_OR_OMIT;
446 break;
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));
452 }
453 break;
454 case Module_Param::MP_Ttcn_Null:
455 *this = DEFAULT(NULL_COMPREF);
456 break;
457 default:
458 param.type_error("default reference (null) template");
459 }
460 is_ifpresent = param.get_ifpresent();
461 }
462
463 void DEFAULT_template::encode_text(Text_Buf&) const
464 {
465 TTCN_error("Default reference templates cannot be sent to other test "
466 "components.");
467 }
468
469 void DEFAULT_template::decode_text(Text_Buf&)
470 {
471 TTCN_error("Default reference templates cannot be received from other test "
472 "components.");
473 }
474
475 boolean DEFAULT_template::is_present() const
476 {
477 if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
478 return !match_omit();
479 }
480
481 boolean DEFAULT_template::match_omit() const
482 {
483 if (is_ifpresent) return TRUE;
484 switch (template_selection) {
485 case OMIT_VALUE:
486 case ANY_OR_OMIT:
487 return TRUE;
488 case VALUE_LIST:
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;
494 default:
495 return FALSE;
496 }
497 return FALSE;
498 }
499
500 #ifndef TITAN_RUNTIME_2
501 void DEFAULT_template::check_restriction(template_res t_res, const char* t_name) const
502 {
503 if (template_selection==UNINITIALIZED_TEMPLATE) return;
504 switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
505 case TR_VALUE:
506 if (!is_ifpresent && template_selection==SPECIFIC_VALUE) return;
507 break;
508 case TR_OMIT:
509 if (!is_ifpresent && (template_selection==OMIT_VALUE ||
510 template_selection==SPECIFIC_VALUE)) return;
511 break;
512 case TR_PRESENT:
513 if (!match_omit()) return;
514 break;
515 default:
516 return;
517 }
518 TTCN_error("Restriction `%s' on template of type %s violated.",
519 get_res_name(t_res), t_name ? t_name : "default reference");
520
521 }
522 #endif
523
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;
528
529 unsigned int TTCN_Default::activate(Default_Base *new_default)
530 {
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;
537 }
538
539 void TTCN_Default::deactivate(Default_Base *removable_default)
540 {
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;
553 return;
554 }
555 }
556 TTCN_warning("Performing a deactivate operation on an inactive "
557 "default reference.");
558 }
559
560 void TTCN_Default::deactivate(const DEFAULT &removable_default)
561 {
562 if (removable_default.default_ptr == UNBOUND_DEFAULT)
563 TTCN_error("Performing a deactivate operation on an unbound default "
564 "reference.");
565 if (removable_default.default_ptr == NULL)
566 TTCN_Logger::log_defaultop_deactivate(NULL, 0);
567 else deactivate(removable_default.default_ptr);
568 }
569
570 void TTCN_Default::deactivate_all()
571 {
572 while (list_head != NULL) deactivate(list_head);
573 }
574
575 alt_status TTCN_Default::try_altsteps()
576 {
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()) {
583 case ALT_YES:
584 TTCN_Logger::log_defaultop_exit(altstep_name, default_id,
585 TitanLoggerApi::DefaultEnd::finish);
586 return ALT_YES;
587 case ALT_REPEAT:
588 TTCN_Logger::log_defaultop_exit(altstep_name, default_id,
589 TitanLoggerApi::DefaultEnd::repeat__);
590 return ALT_REPEAT;
591 case ALT_BREAK:
592 TTCN_Logger::log_defaultop_exit(altstep_name, default_id,
593 TitanLoggerApi::DefaultEnd::break__);
594 return ALT_BREAK;
595 case ALT_MAYBE:
596 ret_val = ALT_MAYBE;
597 break;
598 default:
599 break;
600 }
601 default_iter = prev_iter;
602 }
603 return ret_val;
604 }
605
606 void TTCN_Default::log(Default_Base *default_ptr)
607 {
608 if (default_ptr == UNBOUND_DEFAULT) TTCN_Logger::log_event_unbound();
609 else if (default_ptr == NULL) TTCN_Logger::log_event_str("null");
610 else {
611 for (Default_Base *default_iter = list_head; default_iter != NULL;
612 default_iter = default_iter->default_next) {
613 if (default_iter == default_ptr) {
614 default_ptr->log();
615 return;
616 }
617 }
618 TTCN_Logger::log_event_str("default reference: already deactivated");
619 }
620 }
621
622 void TTCN_Default::save_control_defaults()
623 {
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;
628 list_head = NULL;
629 backup_tail = list_tail;
630 list_tail = NULL;
631 backup_count = default_count;
632 default_count = 0;
633 control_defaults_saved = TRUE;
634 }
635
636 void TTCN_Default::restore_control_defaults()
637 {
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;
645 backup_head = NULL;
646 list_tail = backup_tail;
647 backup_tail = NULL;
648 default_count = backup_count;
649 backup_count = 0;
650 control_defaults_saved = FALSE;
651 }
652
653 void TTCN_Default::reset_counter()
654 {
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.");
659 default_count = 0;
660 }
This page took 0.045339 seconds and 5 git commands to generate.