Commit | Line | Data |
---|---|---|
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 | * Feher, Csaba | |
14 | * Forstner, Matyas | |
15 | * Raduly, Csaba | |
16 | * Szabados, Kristof | |
17 | * Szabo, Janos Zoltan – initial implementation | |
18 | * Tatarka, Gabor | |
19 | * | |
20 | ******************************************************************************/ | |
970ed795 EL |
21 | #include "Default.hh" |
22 | ||
23 | #include "Parameters.h" | |
24 | #include "Param_Types.hh" | |
25 | #include "Logger.hh" | |
26 | #include "Error.hh" | |
27 | #include "TitanLoggerApi.hh" | |
28 | ||
29 | #include "../common/dbgnew.hh" | |
30 | ||
31 | Default_Base::Default_Base(const char *par_altstep_name) | |
32 | { | |
33 | default_id = TTCN_Default::activate(this); | |
34 | altstep_name = par_altstep_name; | |
35 | TTCN_Logger::log_defaultop_activate(par_altstep_name, default_id); | |
36 | } | |
37 | ||
38 | Default_Base::~Default_Base() | |
39 | { | |
40 | TTCN_Logger::log_defaultop_deactivate(altstep_name, default_id); | |
41 | } | |
42 | ||
43 | void Default_Base::log() const | |
44 | { | |
45 | TTCN_Logger::log_event("default reference: altstep: %s, id: %u", | |
46 | altstep_name, default_id); | |
47 | } | |
48 | ||
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; | |
53 | ||
54 | DEFAULT::DEFAULT() | |
55 | { | |
56 | default_ptr = UNBOUND_DEFAULT; | |
57 | } | |
58 | ||
59 | DEFAULT::DEFAULT(component other_value) | |
60 | { | |
61 | if (other_value != NULL_COMPREF) | |
62 | TTCN_error("Initialization from an invalid default reference."); | |
63 | default_ptr = NULL; | |
64 | } | |
65 | ||
66 | DEFAULT::DEFAULT(Default_Base *other_value) | |
67 | { | |
68 | default_ptr = other_value; | |
69 | } | |
70 | ||
71 | DEFAULT::DEFAULT(const DEFAULT& other_value) | |
72 | : Base_Type(other_value) | |
73 | { | |
74 | if (other_value.default_ptr == UNBOUND_DEFAULT) | |
75 | TTCN_error("Copying an unbound default reference."); | |
76 | default_ptr = other_value.default_ptr; | |
77 | } | |
78 | ||
79 | DEFAULT& DEFAULT::operator=(component other_value) | |
80 | { | |
81 | if (other_value != NULL_COMPREF) | |
82 | TTCN_error("Assignment of an invalid default reference."); | |
83 | default_ptr = NULL; | |
84 | return *this; | |
85 | } | |
86 | ||
87 | DEFAULT& DEFAULT::operator=(Default_Base *other_value) | |
88 | { | |
89 | default_ptr = other_value; | |
90 | return *this; | |
91 | } | |
92 | ||
93 | DEFAULT& DEFAULT::operator=(const DEFAULT& other_value) | |
94 | { | |
95 | if (other_value.default_ptr == UNBOUND_DEFAULT) | |
96 | TTCN_error("Assignment of an unbound default reference."); | |
97 | default_ptr = other_value.default_ptr; | |
98 | return *this; | |
99 | } | |
100 | ||
101 | boolean DEFAULT::operator==(component other_value) const | |
102 | { | |
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; | |
108 | } | |
109 | ||
110 | boolean DEFAULT::operator==(Default_Base *other_value) const | |
111 | { | |
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; | |
115 | } | |
116 | ||
117 | boolean DEFAULT::operator==(const DEFAULT& other_value) const | |
118 | { | |
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; | |
124 | } | |
125 | ||
126 | DEFAULT::operator Default_Base*() const | |
127 | { | |
128 | if (default_ptr == UNBOUND_DEFAULT) | |
129 | TTCN_error("Using the value of an unbound default reference."); | |
130 | return default_ptr; | |
131 | } | |
132 | ||
133 | boolean DEFAULT::is_bound() const | |
134 | { | |
135 | return default_ptr != UNBOUND_DEFAULT; // what about NULL ? | |
136 | } | |
137 | ||
138 | boolean DEFAULT::is_value() const | |
139 | { | |
140 | return default_ptr != UNBOUND_DEFAULT; // what about NULL ? | |
141 | } | |
142 | ||
143 | void DEFAULT::clean_up() | |
144 | { | |
145 | default_ptr = UNBOUND_DEFAULT; | |
146 | } | |
147 | ||
148 | void DEFAULT::log() const | |
149 | { | |
150 | TTCN_Default::log(default_ptr); | |
151 | } | |
152 | ||
153 | void DEFAULT::set_param(Module_Param& param) { | |
154 | param.basic_check(Module_Param::BC_VALUE, "default reference (null) value"); | |
3abe9331 | 155 | Module_Param_Ptr mp = ¶m; |
156 | if (param.get_type() == Module_Param::MP_Reference) { | |
157 | mp = param.get_referenced_param(); | |
158 | } | |
159 | if (mp->get_type()!=Module_Param::MP_Ttcn_Null) param.type_error("default reference (null) value"); | |
970ed795 EL |
160 | default_ptr = NULL; |
161 | } | |
162 | ||
3abe9331 | 163 | Module_Param* DEFAULT::get_param(Module_Param_Name& /* param_name */) const |
164 | { | |
165 | if (!is_bound()) { | |
166 | return new Module_Param_Unbound(); | |
167 | } | |
168 | return new Module_Param_Ttcn_Null(); | |
169 | } | |
170 | ||
970ed795 EL |
171 | void DEFAULT::encode_text(Text_Buf&) const |
172 | { | |
173 | TTCN_error("Default references cannot be sent to other test components."); | |
174 | } | |
175 | ||
176 | void DEFAULT::decode_text(Text_Buf&) | |
177 | { | |
178 | TTCN_error("Default references cannot be received from other test " | |
179 | "components."); | |
180 | } | |
181 | ||
182 | boolean operator==(component default_value, const DEFAULT& other_value) | |
183 | { | |
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; | |
189 | } | |
190 | ||
191 | boolean operator==(Default_Base *default_value, const DEFAULT& other_value) | |
192 | { | |
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; | |
196 | } | |
197 | ||
198 | void DEFAULT_template::clean_up() | |
199 | { | |
200 | if (template_selection == VALUE_LIST || | |
201 | template_selection == COMPLEMENTED_LIST) | |
202 | delete [] value_list.list_value; | |
203 | template_selection = UNINITIALIZED_TEMPLATE; | |
204 | } | |
205 | ||
206 | void DEFAULT_template::copy_template(const DEFAULT_template& other_value) | |
207 | { | |
208 | switch (other_value.template_selection) { | |
209 | case SPECIFIC_VALUE: | |
210 | single_value = other_value.single_value; | |
211 | break; | |
212 | case OMIT_VALUE: | |
213 | case ANY_VALUE: | |
214 | case ANY_OR_OMIT: | |
215 | break; | |
216 | case VALUE_LIST: | |
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]); | |
223 | break; | |
224 | default: | |
225 | TTCN_error("Copying an uninitialized/unsupported default reference " | |
226 | "template."); | |
227 | } | |
228 | set_selection(other_value); | |
229 | } | |
230 | ||
231 | DEFAULT_template::DEFAULT_template() | |
232 | { | |
233 | ||
234 | } | |
235 | ||
236 | DEFAULT_template::DEFAULT_template(template_sel other_value) | |
237 | : Base_Template(other_value) | |
238 | { | |
239 | check_single_selection(other_value); | |
240 | } | |
241 | ||
242 | DEFAULT_template::DEFAULT_template(component other_value) | |
243 | : Base_Template(SPECIFIC_VALUE) | |
244 | { | |
245 | if (other_value != NULL_COMPREF) | |
246 | TTCN_error("Creating a template from an invalid default reference."); | |
247 | single_value = NULL; | |
248 | } | |
249 | ||
250 | DEFAULT_template::DEFAULT_template(Default_Base *other_value) | |
251 | : Base_Template(SPECIFIC_VALUE) | |
252 | { | |
253 | single_value = other_value; | |
254 | } | |
255 | ||
256 | DEFAULT_template::DEFAULT_template(const DEFAULT& other_value) | |
257 | : Base_Template(SPECIFIC_VALUE) | |
258 | { | |
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; | |
262 | } | |
263 | ||
264 | DEFAULT_template::DEFAULT_template(const OPTIONAL<DEFAULT>& other_value) | |
265 | { | |
266 | switch (other_value.get_selection()) { | |
267 | case OPTIONAL_PRESENT: | |
268 | set_selection(SPECIFIC_VALUE); | |
269 | single_value = (Default_Base*)(const DEFAULT&)other_value; | |
270 | break; | |
271 | case OPTIONAL_OMIT: | |
272 | set_selection(OMIT_VALUE); | |
273 | break; | |
274 | default: | |
275 | TTCN_error("Creating a default reference template from an unbound " | |
276 | "optional field."); | |
277 | } | |
278 | } | |
279 | ||
280 | DEFAULT_template::DEFAULT_template(const DEFAULT_template& other_value) | |
281 | : Base_Template() | |
282 | { | |
283 | copy_template(other_value); | |
284 | } | |
285 | ||
286 | DEFAULT_template::~DEFAULT_template() | |
287 | { | |
288 | clean_up(); | |
289 | } | |
290 | ||
291 | DEFAULT_template& DEFAULT_template::operator=(template_sel other_value) | |
292 | { | |
293 | check_single_selection(other_value); | |
294 | clean_up(); | |
295 | set_selection(other_value); | |
296 | return *this; | |
297 | } | |
298 | ||
299 | DEFAULT_template& DEFAULT_template::operator=(component other_value) | |
300 | { | |
301 | if (other_value != NULL_COMPREF) | |
302 | TTCN_error("Assignment of an invalid default reference to a template."); | |
303 | clean_up(); | |
304 | set_selection(SPECIFIC_VALUE); | |
305 | single_value = NULL; | |
306 | return *this; | |
307 | } | |
308 | ||
309 | DEFAULT_template& DEFAULT_template::operator=(Default_Base *other_value) | |
310 | { | |
311 | clean_up(); | |
312 | set_selection(SPECIFIC_VALUE); | |
313 | single_value = other_value; | |
314 | return *this; | |
315 | } | |
316 | ||
317 | DEFAULT_template& DEFAULT_template::operator=(const DEFAULT& other_value) | |
318 | { | |
319 | if (other_value.default_ptr == UNBOUND_DEFAULT) | |
320 | TTCN_error("Assignment of an unbound default reference to a template."); | |
321 | clean_up(); | |
322 | set_selection(SPECIFIC_VALUE); | |
323 | single_value = other_value.default_ptr; | |
324 | return *this; | |
325 | } | |
326 | ||
327 | DEFAULT_template& DEFAULT_template::operator= | |
328 | (const OPTIONAL<DEFAULT>& other_value) | |
329 | { | |
330 | clean_up(); | |
331 | switch (other_value.get_selection()) { | |
332 | case OPTIONAL_PRESENT: | |
333 | set_selection(SPECIFIC_VALUE); | |
334 | single_value = (Default_Base*)(const DEFAULT&)other_value; | |
335 | break; | |
336 | case OPTIONAL_OMIT: | |
337 | set_selection(OMIT_VALUE); | |
338 | break; | |
339 | default: | |
340 | TTCN_error("Assignment of an unbound optional field to a default " | |
341 | "reference template."); | |
342 | } | |
343 | return *this; | |
344 | } | |
345 | ||
346 | DEFAULT_template& DEFAULT_template::operator= | |
347 | (const DEFAULT_template& other_value) | |
348 | { | |
349 | if (&other_value != this) { | |
350 | clean_up(); | |
351 | copy_template(other_value); | |
352 | } | |
353 | return *this; | |
354 | } | |
355 | ||
3abe9331 | 356 | boolean DEFAULT_template::match(component other_value, |
357 | boolean /* legacy */) const | |
970ed795 EL |
358 | { |
359 | if (other_value == NULL_COMPREF) return FALSE; | |
360 | return match((Default_Base*)NULL); | |
361 | } | |
362 | ||
3abe9331 | 363 | boolean DEFAULT_template::match(Default_Base *other_value, |
364 | boolean /* legacy */) const | |
970ed795 EL |
365 | { |
366 | if (other_value == UNBOUND_DEFAULT) return FALSE; | |
367 | switch (template_selection) { | |
368 | case SPECIFIC_VALUE: | |
369 | return single_value == other_value; | |
370 | case OMIT_VALUE: | |
371 | return FALSE; | |
372 | case ANY_VALUE: | |
373 | case ANY_OR_OMIT: | |
374 | return TRUE; | |
375 | case VALUE_LIST: | |
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; | |
381 | default: | |
382 | TTCN_error("Matching with an uninitialized/unsupported default " | |
383 | "reference template."); | |
384 | } | |
385 | return FALSE; | |
386 | } | |
387 | ||
3abe9331 | 388 | boolean DEFAULT_template::match(const DEFAULT& other_value, |
389 | boolean /* legacy */) const | |
970ed795 EL |
390 | { |
391 | if (!other_value.is_bound()) return FALSE; | |
392 | return match(other_value.default_ptr); | |
393 | } | |
394 | ||
395 | Default_Base *DEFAULT_template::valueof() const | |
396 | { | |
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."); | |
400 | return single_value; | |
401 | } | |
402 | ||
403 | void DEFAULT_template::set_type(template_sel template_type, | |
404 | unsigned int list_length) | |
405 | { | |
406 | if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST) | |
407 | TTCN_error("Setting an invalid list type for a default reference " | |
408 | "template."); | |
409 | clean_up(); | |
410 | set_selection(template_type); | |
411 | value_list.n_values = list_length; | |
412 | value_list.list_value = new DEFAULT_template[list_length]; | |
413 | } | |
414 | ||
415 | DEFAULT_template& DEFAULT_template::list_item(unsigned int list_index) | |
416 | { | |
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]; | |
423 | } | |
424 | ||
425 | void DEFAULT_template::log() const | |
426 | { | |
427 | switch (template_selection) { | |
428 | case SPECIFIC_VALUE: | |
429 | TTCN_Default::log(single_value); | |
430 | break; | |
431 | case COMPLEMENTED_LIST: | |
432 | TTCN_Logger::log_event_str("complement "); | |
433 | // no break | |
434 | case VALUE_LIST: | |
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(); | |
439 | } | |
440 | TTCN_Logger::log_char(')'); | |
441 | break; | |
442 | default: | |
443 | log_generic(); | |
444 | break; | |
445 | } | |
446 | log_ifpresent(); | |
447 | } | |
448 | ||
3abe9331 | 449 | void DEFAULT_template::log_match(const DEFAULT& match_value, |
450 | boolean /* legacy */) const | |
970ed795 EL |
451 | { |
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(" := "); | |
456 | } | |
457 | match_value.log(); | |
458 | TTCN_Logger::log_event_str(" with "); | |
459 | log(); | |
460 | if(match(match_value))TTCN_Logger::log_event_str(" matched"); | |
461 | else TTCN_Logger::log_event_str(" unmatched"); | |
462 | } | |
463 | ||
464 | void DEFAULT_template::set_param(Module_Param& param) { | |
465 | param.basic_check(Module_Param::BC_TEMPLATE, "default reference (null) template"); | |
3abe9331 | 466 | Module_Param_Ptr mp = ¶m; |
467 | if (param.get_type() == Module_Param::MP_Reference) { | |
468 | mp = param.get_referenced_param(); | |
469 | } | |
470 | switch (mp->get_type()) { | |
970ed795 EL |
471 | case Module_Param::MP_Omit: |
472 | *this = OMIT_VALUE; | |
473 | break; | |
474 | case Module_Param::MP_Any: | |
475 | *this = ANY_VALUE; | |
476 | break; | |
477 | case Module_Param::MP_AnyOrNone: | |
478 | *this = ANY_OR_OMIT; | |
479 | break; | |
480 | case Module_Param::MP_List_Template: | |
3abe9331 | 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)); | |
970ed795 | 487 | } |
3abe9331 | 488 | *this = temp; |
489 | break; } | |
970ed795 EL |
490 | case Module_Param::MP_Ttcn_Null: |
491 | *this = DEFAULT(NULL_COMPREF); | |
492 | break; | |
493 | default: | |
494 | param.type_error("default reference (null) template"); | |
495 | } | |
3abe9331 | 496 | is_ifpresent = param.get_ifpresent() || mp->get_ifpresent(); |
497 | } | |
498 | ||
499 | Module_Param* DEFAULT_template::get_param(Module_Param_Name& param_name) const | |
500 | { | |
501 | Module_Param* mp = NULL; | |
502 | switch (template_selection) { | |
503 | case UNINITIALIZED_TEMPLATE: | |
504 | mp = new Module_Param_Unbound(); | |
505 | break; | |
506 | case OMIT_VALUE: | |
507 | mp = new Module_Param_Omit(); | |
508 | break; | |
509 | case ANY_VALUE: | |
510 | mp = new Module_Param_Any(); | |
511 | break; | |
512 | case ANY_OR_OMIT: | |
513 | mp = new Module_Param_AnyOrNone(); | |
514 | break; | |
515 | case SPECIFIC_VALUE: | |
516 | mp = new Module_Param_Ttcn_Null(); | |
517 | break; | |
518 | case VALUE_LIST: | |
519 | case COMPLEMENTED_LIST: { | |
520 | if (template_selection == VALUE_LIST) { | |
521 | mp = new Module_Param_List_Template(); | |
522 | } | |
523 | else { | |
524 | mp = new Module_Param_ComplementList_Template(); | |
525 | } | |
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)); | |
528 | } | |
529 | break; } | |
530 | default: | |
531 | break; | |
532 | } | |
533 | if (is_ifpresent) { | |
534 | mp->set_ifpresent(); | |
535 | } | |
536 | return mp; | |
970ed795 EL |
537 | } |
538 | ||
539 | void DEFAULT_template::encode_text(Text_Buf&) const | |
540 | { | |
541 | TTCN_error("Default reference templates cannot be sent to other test " | |
542 | "components."); | |
543 | } | |
544 | ||
545 | void DEFAULT_template::decode_text(Text_Buf&) | |
546 | { | |
547 | TTCN_error("Default reference templates cannot be received from other test " | |
548 | "components."); | |
549 | } | |
550 | ||
3abe9331 | 551 | boolean DEFAULT_template::is_present(boolean legacy /* = FALSE */) const |
970ed795 EL |
552 | { |
553 | if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE; | |
3abe9331 | 554 | return !match_omit(legacy); |
970ed795 EL |
555 | } |
556 | ||
3abe9331 | 557 | boolean DEFAULT_template::match_omit(boolean legacy /* = FALSE */) const |
970ed795 EL |
558 | { |
559 | if (is_ifpresent) return TRUE; | |
560 | switch (template_selection) { | |
561 | case OMIT_VALUE: | |
562 | case ANY_OR_OMIT: | |
563 | return TRUE; | |
564 | case VALUE_LIST: | |
565 | case COMPLEMENTED_LIST: | |
3abe9331 | 566 | if (legacy) { |
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; | |
572 | } | |
573 | // else fall through | |
970ed795 EL |
574 | default: |
575 | return FALSE; | |
576 | } | |
577 | return FALSE; | |
578 | } | |
579 | ||
580 | #ifndef TITAN_RUNTIME_2 | |
3abe9331 | 581 | void DEFAULT_template::check_restriction(template_res t_res, const char* t_name, |
582 | boolean legacy /* = FALSE */) const | |
970ed795 EL |
583 | { |
584 | if (template_selection==UNINITIALIZED_TEMPLATE) return; | |
585 | switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) { | |
586 | case TR_VALUE: | |
587 | if (!is_ifpresent && template_selection==SPECIFIC_VALUE) return; | |
588 | break; | |
589 | case TR_OMIT: | |
590 | if (!is_ifpresent && (template_selection==OMIT_VALUE || | |
591 | template_selection==SPECIFIC_VALUE)) return; | |
592 | break; | |
593 | case TR_PRESENT: | |
3abe9331 | 594 | if (!match_omit(legacy)) return; |
970ed795 EL |
595 | break; |
596 | default: | |
597 | return; | |
598 | } | |
599 | TTCN_error("Restriction `%s' on template of type %s violated.", | |
600 | get_res_name(t_res), t_name ? t_name : "default reference"); | |
601 | ||
602 | } | |
603 | #endif | |
604 | ||
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; | |
609 | ||
610 | unsigned int TTCN_Default::activate(Default_Base *new_default) | |
611 | { | |
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; | |
618 | } | |
619 | ||
620 | void TTCN_Default::deactivate(Default_Base *removable_default) | |
621 | { | |
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; | |
634 | return; | |
635 | } | |
636 | } | |
637 | TTCN_warning("Performing a deactivate operation on an inactive " | |
638 | "default reference."); | |
639 | } | |
640 | ||
641 | void TTCN_Default::deactivate(const DEFAULT &removable_default) | |
642 | { | |
643 | if (removable_default.default_ptr == UNBOUND_DEFAULT) | |
644 | TTCN_error("Performing a deactivate operation on an unbound default " | |
645 | "reference."); | |
646 | if (removable_default.default_ptr == NULL) | |
647 | TTCN_Logger::log_defaultop_deactivate(NULL, 0); | |
648 | else deactivate(removable_default.default_ptr); | |
649 | } | |
650 | ||
651 | void TTCN_Default::deactivate_all() | |
652 | { | |
653 | while (list_head != NULL) deactivate(list_head); | |
654 | } | |
655 | ||
656 | alt_status TTCN_Default::try_altsteps() | |
657 | { | |
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()) { | |
664 | case ALT_YES: | |
665 | TTCN_Logger::log_defaultop_exit(altstep_name, default_id, | |
666 | TitanLoggerApi::DefaultEnd::finish); | |
667 | return ALT_YES; | |
668 | case ALT_REPEAT: | |
669 | TTCN_Logger::log_defaultop_exit(altstep_name, default_id, | |
670 | TitanLoggerApi::DefaultEnd::repeat__); | |
671 | return ALT_REPEAT; | |
672 | case ALT_BREAK: | |
673 | TTCN_Logger::log_defaultop_exit(altstep_name, default_id, | |
674 | TitanLoggerApi::DefaultEnd::break__); | |
675 | return ALT_BREAK; | |
676 | case ALT_MAYBE: | |
677 | ret_val = ALT_MAYBE; | |
678 | break; | |
679 | default: | |
680 | break; | |
681 | } | |
682 | default_iter = prev_iter; | |
683 | } | |
684 | return ret_val; | |
685 | } | |
686 | ||
687 | void TTCN_Default::log(Default_Base *default_ptr) | |
688 | { | |
689 | if (default_ptr == UNBOUND_DEFAULT) TTCN_Logger::log_event_unbound(); | |
690 | else if (default_ptr == NULL) TTCN_Logger::log_event_str("null"); | |
691 | else { | |
692 | for (Default_Base *default_iter = list_head; default_iter != NULL; | |
693 | default_iter = default_iter->default_next) { | |
694 | if (default_iter == default_ptr) { | |
695 | default_ptr->log(); | |
696 | return; | |
697 | } | |
698 | } | |
699 | TTCN_Logger::log_event_str("default reference: already deactivated"); | |
700 | } | |
701 | } | |
702 | ||
703 | void TTCN_Default::save_control_defaults() | |
704 | { | |
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; | |
709 | list_head = NULL; | |
710 | backup_tail = list_tail; | |
711 | list_tail = NULL; | |
712 | backup_count = default_count; | |
713 | default_count = 0; | |
714 | control_defaults_saved = TRUE; | |
715 | } | |
716 | ||
717 | void TTCN_Default::restore_control_defaults() | |
718 | { | |
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; | |
726 | backup_head = NULL; | |
727 | list_tail = backup_tail; | |
728 | backup_tail = NULL; | |
729 | default_count = backup_count; | |
730 | backup_count = 0; | |
731 | control_defaults_saved = FALSE; | |
732 | } | |
733 | ||
734 | void TTCN_Default::reset_counter() | |
735 | { | |
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."); | |
740 | default_count = 0; | |
741 | } |