| 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 | ******************************************************************************/ |
| 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"); |
| 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"); |
| 160 | default_ptr = NULL; |
| 161 | } |
| 162 | |
| 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 | |
| 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 | |
| 356 | boolean DEFAULT_template::match(component other_value, |
| 357 | boolean /* legacy */) const |
| 358 | { |
| 359 | if (other_value == NULL_COMPREF) return FALSE; |
| 360 | return match((Default_Base*)NULL); |
| 361 | } |
| 362 | |
| 363 | boolean DEFAULT_template::match(Default_Base *other_value, |
| 364 | boolean /* legacy */) const |
| 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 | |
| 388 | boolean DEFAULT_template::match(const DEFAULT& other_value, |
| 389 | boolean /* legacy */) const |
| 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 | |
| 449 | void DEFAULT_template::log_match(const DEFAULT& match_value, |
| 450 | boolean /* legacy */) const |
| 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"); |
| 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()) { |
| 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: |
| 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)); |
| 487 | } |
| 488 | *this = temp; |
| 489 | break; } |
| 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 | } |
| 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; |
| 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 | |
| 551 | boolean DEFAULT_template::is_present(boolean legacy /* = FALSE */) const |
| 552 | { |
| 553 | if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE; |
| 554 | return !match_omit(legacy); |
| 555 | } |
| 556 | |
| 557 | boolean DEFAULT_template::match_omit(boolean legacy /* = FALSE */) const |
| 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: |
| 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 |
| 574 | default: |
| 575 | return FALSE; |
| 576 | } |
| 577 | return FALSE; |
| 578 | } |
| 579 | |
| 580 | #ifndef TITAN_RUNTIME_2 |
| 581 | void DEFAULT_template::check_restriction(template_res t_res, const char* t_name, |
| 582 | boolean legacy /* = FALSE */) const |
| 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: |
| 594 | if (!match_omit(legacy)) return; |
| 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 | } |