Skip to content
Snippets Groups Projects
Value.cc 516 KiB
Newer Older
Elemer Lelik's avatar
Elemer Lelik committed
/******************************************************************************
 * Copyright (c) 2000-2017 Ericsson Telecom AB
Elemer Lelik's avatar
Elemer Lelik committed
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Baji, Laszlo
 *   Balasko, Jeno
 *   Baranyi, Botond
 *   Beres, Szabolcs
 *   Bibo, Zoltan
 *   Cserveni, Akos
 *   Delic, Adam
 *   Dimitrov, Peter
 *   Feher, Csaba
 *   Forstner, Matyas
 *   Gecse, Roland
 *   Kovacs, Ferenc
 *   Ormandi, Matyas
 *   Raduly, Csaba
 *   Szabados, Kristof
Elemer Lelik's avatar
Elemer Lelik committed
 *   Szabo, Janos Zoltan – initial implementation
 *   Szalai, Gabor
 *   Tatarka, Gabor
 *   Zalanyi, Balazs Andor
 *
 ******************************************************************************/
#include "../common/dbgnew.hh"
#include "Value.hh"
#include "Identifier.hh"
#include "Valuestuff.hh"
#include "PredefFunc.hh"
#include "CompField.hh"
#include "CompType.hh"
#include "EnumItem.hh"
#include "TypeCompat.hh"
#include "asn1/Block.hh"
#include "asn1/TokenBuf.hh"
#include "Real.hh"
#include "Int.hh"
#include "main.hh"
#include "Setting.hh"
#include "Type.hh"
#include "ttcn3/TtcnTemplate.hh"
#include "ttcn3/ArrayDimensions.hh"
#include "ustring.hh"
#include "../common/pattern.hh"

#include "ttcn3/PatternString.hh"
#include "ttcn3/Statement.hh"

#include "ttcn3/Attributes.hh"
Elemer Lelik's avatar
Elemer Lelik committed
#include "../common/JSON_Tokenizer.hh"
Elemer Lelik's avatar
Elemer Lelik committed
#include "ttcn3/Ttcn2Json.hh"

#include <regex.h>
#include <limits.h>

namespace Common {

  static void clean_up_string_elements(map<size_t, Value>*& string_elements)
  {
    if (string_elements) {
      for (size_t i = 0; i < string_elements->size(); i++)
	delete string_elements->get_nth_elem(i);
      string_elements->clear();
      delete string_elements;
      string_elements = 0;
    }
  }

  // =================================
  // ===== Value
  // =================================

  Value::Value(const Value& p)
    : GovernedSimple(p), valuetype(p.valuetype), my_governor(0)
  {
    switch(valuetype) {
    case V_ERROR:
    case V_NULL:
    case V_OMIT:
    case V_TTCN3_NULL:
    case V_DEFAULT_NULL:
    case V_FAT_NULL:
    case V_NOTUSED:
      break;
    case V_BOOL:
      u.val_bool=p.u.val_bool;
      break;
    case V_INT:
      u.val_Int=new int_val_t(*(p.u.val_Int));
      break;
    case V_NAMEDINT:
    case V_ENUM:
    case V_UNDEF_LOWERID:
      u.val_id=p.u.val_id->clone();
      break;
    case V_REAL:
      u.val_Real=p.u.val_Real;
      break;
    case V_BSTR:
    case V_HSTR:
    case V_OSTR:
    case V_CSTR:
    case V_ISO2022STR:
      set_val_str(new string(*p.u.str.val_str));
      break;
    case V_USTR:
      set_val_ustr(new ustring(*p.u.ustr.val_ustr));
      u.ustr.convert_str = p.u.ustr.convert_str;
      break;
    case V_CHARSYMS:
      u.char_syms = p.u.char_syms->clone();
      break;
    case V_OID:
    case V_ROID:
      u.oid_comps=new vector<OID_comp>;
      for(size_t i=0; i<p.u.oid_comps->size(); i++)
        add_oid_comp((*p.u.oid_comps)[i]->clone());
      break;
    case V_CHOICE:
      u.choice.alt_name=p.u.choice.alt_name->clone();
      u.choice.alt_value=p.u.choice.alt_value->clone();
      break;
    case V_SEQOF:
    case V_SETOF:
    case V_ARRAY:
      u.val_vs=p.u.val_vs->clone();
      break;
    case V_SEQ:
    case V_SET:
      u.val_nvs=p.u.val_nvs->clone();
      break;
    case V_REFD:
      u.ref.ref=p.u.ref.ref->clone();
      u.ref.refd_last=0;
      break;
    case V_NAMEDBITS:
      for(size_t i=0; i<p.u.ids->size(); i++) {
        Identifier *id = p.u.ids->get_nth_elem(i);
        u.ids->add(id->get_name(), id->clone());
      }
      break;
    case V_UNDEF_BLOCK:
      u.block=p.u.block->clone();
      break;
    case V_VERDICT:
      u.verdict=p.u.verdict;
      break;
    case V_EXPR:
      u.expr.v_optype = p.u.expr.v_optype;
      u.expr.state = EXPR_NOT_CHECKED;
      switch(u.expr.v_optype) {
      case OPTYPE_RND: // -
      case OPTYPE_COMP_NULL:
      case OPTYPE_COMP_MTC:
      case OPTYPE_COMP_SYSTEM:
      case OPTYPE_COMP_SELF:
      case OPTYPE_COMP_RUNNING_ANY:
      case OPTYPE_COMP_RUNNING_ALL:
      case OPTYPE_COMP_ALIVE_ANY:
      case OPTYPE_COMP_ALIVE_ALL:
      case OPTYPE_TMR_RUNNING_ANY:
      case OPTYPE_GETVERDICT:
      case OPTYPE_TESTCASENAME:
Elemer Lelik's avatar
Elemer Lelik committed
      case OPTYPE_PROF_RUNNING:
        break;
      case OPTYPE_COMP_RUNNING: // v1 [r2] b4
      case OPTYPE_COMP_ALIVE:
        u.expr.r2 = p.u.expr.r2 != NULL ? p.u.expr.r2->clone() : NULL;
        u.expr.b4 = p.u.expr.b4;
        // no break
      case OPTYPE_UNARYPLUS: // v1
      case OPTYPE_UNARYMINUS:
      case OPTYPE_NOT:
      case OPTYPE_NOT4B:
      case OPTYPE_BIT2HEX:
      case OPTYPE_BIT2INT:
      case OPTYPE_BIT2OCT:
      case OPTYPE_BIT2STR:
      case OPTYPE_BSON2JSON:
      case OPTYPE_CBOR2JSON:
      case OPTYPE_CHAR2INT:
      case OPTYPE_CHAR2OCT:
      case OPTYPE_FLOAT2INT:
      case OPTYPE_FLOAT2STR:
      case OPTYPE_HEX2BIT:
      case OPTYPE_HEX2INT:
      case OPTYPE_HEX2OCT:
      case OPTYPE_HEX2STR:
      case OPTYPE_INT2CHAR:
      case OPTYPE_INT2FLOAT:
      case OPTYPE_INT2STR:
      case OPTYPE_INT2UNICHAR:
      case OPTYPE_JSON2BSON:
      case OPTYPE_JSON2CBOR:
      case OPTYPE_OCT2BIT:
      case OPTYPE_OCT2CHAR:
      case OPTYPE_OCT2HEX:
      case OPTYPE_OCT2INT:
      case OPTYPE_OCT2STR:
      case OPTYPE_STR2BIT:
      case OPTYPE_STR2FLOAT:
      case OPTYPE_STR2HEX:
      case OPTYPE_STR2INT:
      case OPTYPE_STR2OCT:
      case OPTYPE_UNICHAR2INT:
      case OPTYPE_UNICHAR2CHAR:
      case OPTYPE_ENUM2INT:
      case OPTYPE_RNDWITHVAL:
      case OPTYPE_GET_STRINGENCODING:
      case OPTYPE_DECODE_BASE64:
      case OPTYPE_REMOVE_BOM:
        u.expr.v1=p.u.expr.v1->clone();
        break;
      case OPTYPE_HOSTID: // [v1]
        u.expr.v1=p.u.expr.v1?p.u.expr.v1->clone():0;
        break;
      case OPTYPE_ADD: // v1 v2
      case OPTYPE_SUBTRACT:
      case OPTYPE_MULTIPLY:
      case OPTYPE_DIVIDE:
      case OPTYPE_MOD:
      case OPTYPE_REM:
      case OPTYPE_CONCAT:
      case OPTYPE_EQ:
      case OPTYPE_LT:
      case OPTYPE_GT:
      case OPTYPE_NE:
      case OPTYPE_GE:
      case OPTYPE_LE:
      case OPTYPE_AND:
      case OPTYPE_OR:
      case OPTYPE_XOR:
      case OPTYPE_AND4B:
      case OPTYPE_OR4B:
      case OPTYPE_XOR4B:
      case OPTYPE_SHL:
      case OPTYPE_SHR:
      case OPTYPE_ROTL:
      case OPTYPE_ROTR:
      case OPTYPE_INT2BIT:
      case OPTYPE_INT2HEX:
      case OPTYPE_INT2OCT:
        u.expr.v1=p.u.expr.v1->clone();
        u.expr.v2=p.u.expr.v2->clone();
        break;
      case OPTYPE_UNICHAR2OCT: // v1 [v2]
      case OPTYPE_OCT2UNICHAR:
      case OPTYPE_ENCODE_BASE64:
        u.expr.v1=p.u.expr.v1->clone();
        u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
        break;
      case OPTYPE_UNDEF_RUNNING: // r1 [r2] b4
      case OPTYPE_TMR_RUNNING: // r1 [r2] b4
        u.expr.r1=p.u.expr.r1->clone();
        u.expr.r2 = p.u.expr.r2 != NULL ? p.u.expr.r2->clone() : NULL;
        u.expr.b4 = p.u.expr.b4;
        break;
      case OPTYPE_DECODE: // r1 r2 [v3] [v4]
        u.expr.r1 = p.u.expr.r1->clone();
        u.expr.r2 = p.u.expr.r2->clone();
        u.expr.v2 = p.u.expr.v3 != NULL ? p.u.expr.v3->clone() : NULL;
        u.expr.v3 = p.u.expr.v4 != NULL ? p.u.expr.v4->clone() : NULL;
        break;
      case OPTYPE_SUBSTR:
        u.expr.ti1=p.u.expr.ti1->clone();
        u.expr.v2 = p.u.expr.v2 != NULL ? p.u.expr.v2->clone() : NULL;
        u.expr.v3 = p.u.expr.v3 != NULL ? p.u.expr.v3->clone() : NULL;
        break;
      case OPTYPE_REGEXP:
        u.expr.ti1=p.u.expr.ti1->clone();
        u.expr.t2=p.u.expr.t2->clone();
        u.expr.v3=p.u.expr.v3->clone();
        break;
      case OPTYPE_DECOMP: // v1 v2 v3
        u.expr.v1=p.u.expr.v1->clone();
        u.expr.v2=p.u.expr.v2->clone();
        u.expr.v3=p.u.expr.v3->clone();
        break;
      case OPTYPE_REPLACE:
        u.expr.ti1 = p.u.expr.ti1->clone();
        u.expr.v2 = p.u.expr.v2->clone();
        u.expr.v3 = p.u.expr.v3->clone();
        u.expr.ti4 = p.u.expr.ti4->clone();
        break;
      case OPTYPE_LENGTHOF: // ti1
      case OPTYPE_SIZEOF:  // ti1
      case OPTYPE_VALUEOF: // ti1
      case OPTYPE_ISPRESENT:
      case OPTYPE_TTCN2STRING:
      case OPTYPE_ISVALUE:
      case OPTYPE_ISBOUND:
        u.expr.ti1=p.u.expr.ti1->clone();
        break;
      case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2] [v3] [v4]
        u.expr.ti1=p.u.expr.ti1->clone();
        u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
        u.expr.v3 = p.u.expr.v3 != NULL ? p.u.expr.v3->clone() : NULL;
        u.expr.v4 = p.u.expr.v4 != NULL ? p.u.expr.v4->clone() : NULL;
      case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3] [v4] [v5]
        u.expr.r1 = p.u.expr.r1->clone();
        u.expr.r2 = p.u.expr.r2->clone();
        u.expr.v3 = p.u.expr.v3 != NULL ? p.u.expr.v3->clone() : NULL;
        u.expr.v4 = p.u.expr.v4 != NULL ? p.u.expr.v4->clone() : NULL;
        u.expr.v5 = p.u.expr.v5 != NULL ? p.u.expr.v5->clone() : NULL;
      case OPTYPE_TMR_READ:
      case OPTYPE_ACTIVATE:
        u.expr.r1=p.u.expr.r1->clone();
        break;
      case OPTYPE_EXECUTE: // r1 [v2]
        u.expr.r1=p.u.expr.r1->clone();
        u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
        break;
      case OPTYPE_CHECKSTATE_ANY: // [r1] v2
      case OPTYPE_CHECKSTATE_ALL:
        u.expr.r1=p.u.expr.r1?p.u.expr.r1->clone():0;
        u.expr.v2=p.u.expr.v2->clone();
        break;
      case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
        u.expr.r1=p.u.expr.r1->clone();
        u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
        u.expr.v3=p.u.expr.v3?p.u.expr.v3->clone():0;
        u.expr.b4 = p.u.expr.b4;
        break;
      case OPTYPE_MATCH: // v1 t2
        u.expr.v1=p.u.expr.v1->clone();
        u.expr.t2=p.u.expr.t2->clone();
        break;
      case OPTYPE_ISCHOSEN: // r1 i2
        u.expr.r1=p.u.expr.r1->clone();
        u.expr.i2=p.u.expr.i2->clone();
        break;
      case OPTYPE_ISCHOSEN_V: // v1 i2
        u.expr.v1=p.u.expr.v1->clone();
        u.expr.i2=p.u.expr.i2->clone();
        break;
      case OPTYPE_ISCHOSEN_T: // t1 i2
        u.expr.t1=p.u.expr.t1->clone();
        u.expr.i2=p.u.expr.i2->clone();
        break;
      case OPTYPE_ACTIVATE_REFD:
        u.expr.v1 = p.u.expr.v1->clone();
        if(p.u.expr.state!=EXPR_CHECKED)
          u.expr.t_list2 = p.u.expr.t_list2->clone();
        else {
          u.expr.ap_list2 = p.u.expr.ap_list2->clone();
          u.expr.state = EXPR_CHECKED;
          }
        break;
      case OPTYPE_EXECUTE_REFD:
        u.expr.v1 = p.u.expr.v1->clone();
        if(p.u.expr.state!=EXPR_CHECKED)
          u.expr.t_list2 = p.u.expr.t_list2->clone();
        else {
          u.expr.ap_list2 = p.u.expr.ap_list2->clone();
          u.expr.state = EXPR_CHECKED;
          }
        u.expr.v3 = p.u.expr.v3 ? p.u.expr.v3->clone() : 0;
        break;
      case OPTYPE_LOG2STR:
      case OPTYPE_ANY2UNISTR:
        u.expr.logargs = p.u.expr.logargs->clone();
        break;
      case OPTYPE_ISTEMPLATEKIND:
        u.expr.ti1 = p.u.expr.ti1->clone();
        u.expr.v2 = p.u.expr.v2->clone();
        break;
      default:
        FATAL_ERROR("Value::Value()");
      } // switch
      break;
    case V_MACRO:
      u.macro = p.u.macro;
      break;
    case V_FUNCTION:
    case V_ALTSTEP:
    case V_TESTCASE:
      u.refd_fat = p.u.refd_fat;
      break;
    case V_INVOKE:
      u.invoke.v = p.u.invoke.v->clone();
      u.invoke.t_list = p.u.invoke.t_list?p.u.invoke.t_list->clone():0;
      u.invoke.ap_list = p.u.invoke.ap_list?p.u.invoke.ap_list->clone():0;
      break;
    case V_REFER:
      u.refered = p.u.refered->clone();
      break;
    case V_ANY_VALUE:
    case V_ANY_OR_OMIT:
      u.len_res = p.u.len_res != NULL ? p.u.len_res->clone() : NULL;
      break;
    default:
      FATAL_ERROR("Value::Value()");
    } // switch
  }

  void Value::clean_up()
  {
    switch (valuetype) {
    case V_ERROR:
    case V_NULL:
    case V_BOOL:
    case V_REAL:
    case V_OMIT:
    case V_VERDICT:
    case V_TTCN3_NULL:
    case V_DEFAULT_NULL:
    case V_FAT_NULL:
    case V_MACRO:
    case V_NOTUSED:
    case V_FUNCTION:
    case V_ALTSTEP:
    case V_TESTCASE:
      break;
    case V_INT:
      delete u.val_Int;
      break;
    case V_NAMEDINT:
    case V_ENUM:
    case V_UNDEF_LOWERID:
      delete u.val_id;
      break;
    case V_BSTR:
    case V_HSTR:
    case V_OSTR:
    case V_CSTR:
    case V_ISO2022STR:
      delete u.str.val_str;
      clean_up_string_elements(u.str.str_elements);
      break;
    case V_USTR:
      delete u.ustr.val_ustr;
      clean_up_string_elements(u.ustr.ustr_elements);
      break;
    case V_CHARSYMS:
      delete u.char_syms;
      break;
    case V_OID:
    case V_ROID:
      if (u.oid_comps) {
	for(size_t i=0; i<u.oid_comps->size(); i++)
          delete (*u.oid_comps)[i];
	u.oid_comps->clear();
	delete u.oid_comps;
      }
      break;
    case V_EXPR:
      clean_up_expr();
      break;
    case V_CHOICE:
      delete u.choice.alt_name;
      delete u.choice.alt_value;
      break;
    case V_SEQOF:
    case V_SETOF:
    case V_ARRAY:
      delete u.val_vs;
      break;
    case V_SEQ:
    case V_SET:
      delete u.val_nvs;
      break;
    case V_REFD:
      delete u.ref.ref;
      break;
    case V_REFER:
      delete u.refered;
      break;
    case V_INVOKE:
      delete u.invoke.v;
      delete u.invoke.t_list;
      delete u.invoke.ap_list;
      break;
    case V_NAMEDBITS:
      if(u.ids) {
        for(size_t i=0; i<u.ids->size(); i++) delete u.ids->get_nth_elem(i);
        u.ids->clear();
        delete u.ids;
      }
      break;
    case V_UNDEF_BLOCK:
      delete u.block;
      break;
    case V_ANY_VALUE:
    case V_ANY_OR_OMIT:
      delete u.len_res;
      break;
    default:
      FATAL_ERROR("Value::clean_up()");
    } // switch
  }

  void Value::clean_up_expr()
  {
    switch (u.expr.state) {
    case EXPR_CHECKING:
    case EXPR_CHECKING_ERR:
      FATAL_ERROR("Value::clean_up_expr()");
    default:
      break;
    }
    switch (u.expr.v_optype) {
    case OPTYPE_RND: // -
    case OPTYPE_COMP_NULL:
    case OPTYPE_COMP_MTC:
    case OPTYPE_COMP_SYSTEM:
    case OPTYPE_COMP_SELF:
    case OPTYPE_COMP_RUNNING_ANY:
    case OPTYPE_COMP_RUNNING_ALL:
    case OPTYPE_COMP_ALIVE_ANY:
    case OPTYPE_COMP_ALIVE_ALL:
    case OPTYPE_TMR_RUNNING_ANY:
    case OPTYPE_GETVERDICT:
    case OPTYPE_TESTCASENAME:
Elemer Lelik's avatar
Elemer Lelik committed
    case OPTYPE_PROF_RUNNING:
      break;
    case OPTYPE_COMP_RUNNING: // v1 [r2] b4
    case OPTYPE_COMP_ALIVE:
      delete u.expr.r2;
      // no break
    case OPTYPE_UNARYPLUS: // v1
    case OPTYPE_UNARYMINUS:
    case OPTYPE_NOT:
    case OPTYPE_NOT4B:
    case OPTYPE_BIT2HEX:
    case OPTYPE_BIT2INT:
    case OPTYPE_BIT2OCT:
    case OPTYPE_BIT2STR:
    case OPTYPE_BSON2JSON:
    case OPTYPE_CBOR2JSON:
    case OPTYPE_CHAR2INT:
    case OPTYPE_CHAR2OCT:
    case OPTYPE_FLOAT2INT:
    case OPTYPE_FLOAT2STR:
    case OPTYPE_HEX2BIT:
    case OPTYPE_HEX2INT:
    case OPTYPE_HEX2OCT:
    case OPTYPE_HEX2STR:
    case OPTYPE_INT2CHAR:
    case OPTYPE_INT2FLOAT:
    case OPTYPE_INT2STR:
    case OPTYPE_INT2UNICHAR:
    case OPTYPE_JSON2BSON:
    case OPTYPE_JSON2CBOR:
    case OPTYPE_OCT2BIT:
    case OPTYPE_OCT2CHAR:
    case OPTYPE_OCT2HEX:
    case OPTYPE_OCT2INT:
    case OPTYPE_OCT2STR:
    case OPTYPE_STR2BIT:
    case OPTYPE_STR2FLOAT:
    case OPTYPE_STR2HEX:
    case OPTYPE_STR2INT:
    case OPTYPE_STR2OCT:
    case OPTYPE_UNICHAR2INT:
    case OPTYPE_UNICHAR2CHAR:
    case OPTYPE_ENUM2INT:
    case OPTYPE_RNDWITHVAL:
    case OPTYPE_REMOVE_BOM:
    case OPTYPE_GET_STRINGENCODING:
    case OPTYPE_DECODE_BASE64:
    case OPTYPE_HOSTID:
      delete u.expr.v1;
      break;
    case OPTYPE_ADD: // v1 v2
    case OPTYPE_SUBTRACT:
    case OPTYPE_MULTIPLY:
    case OPTYPE_DIVIDE:
    case OPTYPE_MOD:
    case OPTYPE_REM:
    case OPTYPE_CONCAT:
    case OPTYPE_EQ:
    case OPTYPE_LT:
    case OPTYPE_GT:
    case OPTYPE_NE:
    case OPTYPE_GE:
    case OPTYPE_LE:
    case OPTYPE_AND:
    case OPTYPE_OR:
    case OPTYPE_XOR:
    case OPTYPE_AND4B:
    case OPTYPE_OR4B:
    case OPTYPE_XOR4B:
    case OPTYPE_SHL:
    case OPTYPE_SHR:
    case OPTYPE_ROTL:
    case OPTYPE_ROTR:
    case OPTYPE_INT2BIT:
    case OPTYPE_INT2HEX:
    case OPTYPE_INT2OCT:
    case OPTYPE_UNICHAR2OCT:
    case OPTYPE_OCT2UNICHAR:
    case OPTYPE_ENCODE_BASE64:
      delete u.expr.v1;
      delete u.expr.v2;
      break;
    case OPTYPE_UNDEF_RUNNING: // r1 [r2] b4
    case OPTYPE_TMR_RUNNING: // r1 [r2] b4
      delete u.expr.r1;
      delete u.expr.r2;
      break;
    case OPTYPE_DECODE: // r1 r2 [v3] [v4]
      delete u.expr.r1;
      delete u.expr.r2;
      delete u.expr.v3;
      delete u.expr.v4;
      break;
    case OPTYPE_SUBSTR:
      delete u.expr.ti1;
      delete u.expr.v2;
      delete u.expr.v3;
      break;
    case OPTYPE_REGEXP:
      delete u.expr.ti1;
      delete u.expr.t2;
      delete u.expr.v3;
      break;
    case OPTYPE_DECOMP: // v1 v2 v3
      delete u.expr.v1;
      delete u.expr.v2;
      delete u.expr.v3;
      break;
    case OPTYPE_REPLACE:
      delete u.expr.ti1;
      delete u.expr.v2;
      delete u.expr.v3;
      delete u.expr.ti4;
      break;
    case OPTYPE_LENGTHOF: // ti1
    case OPTYPE_SIZEOF:  // ti1
    case OPTYPE_VALUEOF: // ti1
    case OPTYPE_ISVALUE:
    case OPTYPE_ISBOUND:
    case OPTYPE_ISPRESENT:
    case OPTYPE_TTCN2STRING:
      delete u.expr.ti1;
      break;
    case OPTYPE_ISTEMPLATEKIND: // ti1 v2
      delete u.expr.ti1;
      delete u.expr.v2;
      break;
    case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2] [v3] [v4]
      delete u.expr.ti1;
      delete u.expr.v2;
      delete u.expr.v3;
      delete u.expr.v4;
      break;
    case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3] [v4] [v5]
      delete u.expr.r1;
      delete u.expr.r2;
      delete u.expr.v3;
      delete u.expr.v4;
      delete u.expr.v5;
    case OPTYPE_TMR_READ:
    case OPTYPE_ACTIVATE:
      delete u.expr.r1;
      break;
    case OPTYPE_EXECUTE: // r1 [v2]
      delete u.expr.r1;
      delete u.expr.v2;
      break;
    case OPTYPE_CHECKSTATE_ANY: // [r1] v2
    case OPTYPE_CHECKSTATE_ALL:
      delete u.expr.r1;
      delete u.expr.v2;
      break;
    case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
      delete u.expr.r1;
      delete u.expr.v2;
      delete u.expr.v3;
      break;
    case OPTYPE_MATCH: // v1 t2
      delete u.expr.v1;
      delete u.expr.t2;
      break;
    case OPTYPE_ISCHOSEN: // r1 i2
      delete u.expr.r1;
      delete u.expr.i2;
      break;
    case OPTYPE_ISCHOSEN_V: // v1 i2
      delete u.expr.v1;
      delete u.expr.i2;
      break;
    case OPTYPE_ISCHOSEN_T: // t1 i2
      delete u.expr.t1;
      delete u.expr.i2;
      break;
    case OPTYPE_ACTIVATE_REFD: //v1 t_list2
      delete u.expr.v1;
      if(u.expr.state!=EXPR_CHECKED)
        delete u.expr.t_list2;
      else
        delete u.expr.ap_list2;
      break;
    case OPTYPE_EXECUTE_REFD: //v1 t_list2 [v3]
      delete u.expr.v1;
      if(u.expr.state!=EXPR_CHECKED)
        delete u.expr.t_list2;
      else
        delete u.expr.ap_list2;
      delete u.expr.v3;
      break;
    case OPTYPE_LOG2STR:
    case OPTYPE_ANY2UNISTR:
      delete u.expr.logargs;
      break;
    default:
      FATAL_ERROR("Value::clean_up_expr()");
    } // switch
  }

  void Value::copy_and_destroy(Value *src)
  {
    clean_up();
    valuetype = src->valuetype;
    u = src->u;
    // update the pointer used for caching if it points to the value itself
    if (valuetype == V_REFD && u.ref.refd_last == src) u.ref.refd_last = this;
    src->valuetype = V_ERROR;
    delete src;
  }

  Value::Value(valuetype_t p_vt)
    : GovernedSimple(S_V), valuetype(p_vt), my_governor(0), in_brackets(false)
  {
    switch(valuetype) {
    case V_NULL:
    case V_TTCN3_NULL:
    case V_OMIT:
    case V_NOTUSED:
    case V_ERROR:
      break;
    case V_OID:
    case V_ROID:
      u.oid_comps=new vector<OID_comp>();
      break;
    case V_NAMEDBITS:
      u.ids=new map<string, Identifier>();
      break;
    default:
      FATAL_ERROR("Value::Value()");
    } // switch
  }

  Value::Value(valuetype_t p_vt, bool p_val_bool)
    : GovernedSimple(S_V), valuetype(p_vt), my_governor(0), in_brackets(false)
  {
    switch(valuetype) {
    case V_BOOL:
      u.val_bool=p_val_bool;
      break;
    default:
      FATAL_ERROR("Value::Value()");
    } // switch
  }

  Value::Value(valuetype_t p_vt, const Int& p_val_Int)
    : GovernedSimple(S_V), valuetype(p_vt), my_governor(0), in_brackets(false)
  {
    switch(valuetype) {
    case V_INT:
      u.val_Int=new int_val_t(p_val_Int);
      break;
    default:
      FATAL_ERROR("Value::Value()");
    } // switch
  }

  Value::Value(valuetype_t p_vt, int_val_t *p_val_Int)
    : GovernedSimple(S_V), valuetype(p_vt), my_governor(0), in_brackets(false)
  {
    switch(valuetype){
    case V_INT:
      u.val_Int=p_val_Int;
      break;
    default:
      FATAL_ERROR("Value::Value()");
    }
  }

  Value::Value(valuetype_t p_vt, string *p_val_str)
    : GovernedSimple(S_V), valuetype(p_vt), my_governor(0), in_brackets(false)
  {
    if(!p_val_str) FATAL_ERROR("NULL parameter");
    switch(valuetype) {
    case V_BSTR:
    case V_HSTR:
    case V_OSTR:
    case V_CSTR:
    case V_ISO2022STR:
      set_val_str(p_val_str);
      break;
    default:
      FATAL_ERROR("Value::Value()");
    } // switch
  }

  Value::Value(valuetype_t p_vt, ustring *p_val_ustr)
    : GovernedSimple(S_V), valuetype(p_vt), my_governor(0), in_brackets(false)
  {
    if (p_vt != V_USTR || !p_val_ustr) FATAL_ERROR("Value::Value()");
    set_val_ustr(p_val_ustr);
    u.ustr.convert_str = false;
  }

  Value::Value(valuetype_t p_vt, CharSyms *p_char_syms)
    : GovernedSimple(S_V), valuetype(p_vt), my_governor(0), in_brackets(false)
  {
    if (!p_char_syms) FATAL_ERROR("NULL parameter");
    switch (valuetype) {
    case V_CHARSYMS:
      u.char_syms = p_char_syms;
      break;
    default:
      FATAL_ERROR("Value::Value()");
    } // switch
  }

  Value::Value(valuetype_t p_vt, Identifier *p_val_id)
    : GovernedSimple(S_V), valuetype(p_vt), my_governor(0), in_brackets(false)
  {
    if(!p_val_id)
      FATAL_ERROR("NULL parameter");
    switch(valuetype) {
    case V_NAMEDINT:
    case V_ENUM:
    case V_UNDEF_LOWERID:
      u.val_id=p_val_id;
      break;
    default:
      FATAL_ERROR("Value::Value()");
    } // switch
  }

  Value::Value(valuetype_t p_vt, Identifier *p_id, Value *p_val)
    : GovernedSimple(S_V), valuetype(p_vt), my_governor(0), in_brackets(false)
  {
    if(!p_id || !p_val)
      FATAL_ERROR("NULL parameter");
    switch(valuetype) {
    case V_CHOICE:
      u.choice.alt_name=p_id;
      u.choice.alt_value=p_val;
      break;
    default:
      FATAL_ERROR("Value::Value()");
    } // switch
  }

  Value::Value(valuetype_t p_vt, const Real& p_val_Real)
    : GovernedSimple(S_V), valuetype(p_vt), my_governor(0), in_brackets(false)
  {
    switch(valuetype) {
    case V_REAL:
      u.val_Real=p_val_Real;
      break;
    default:
      FATAL_ERROR("Value::Value()");
    } // switch
  }

  Value::Value(valuetype_t p_vt, Values *p_vs)
    : GovernedSimple(S_V), valuetype(p_vt), my_governor(0), in_brackets(false)
  {
    if(!p_vs) FATAL_ERROR("NULL parameter");
    switch(valuetype) {
    case V_SEQOF:
    case V_SETOF:
    case V_ARRAY:
      u.val_vs=p_vs;
      break;
    default:
      FATAL_ERROR("Value::Value()");
    } // switch
  }

  Value::Value(valuetype_t p_vt, Value *p_v,
    Ttcn::ParsedActualParameters *p_t_list)
    : GovernedSimple(S_V), valuetype(p_vt), my_governor(0), in_brackets(false)
  {
    if(!p_v || !p_t_list) FATAL_ERROR("NULL parameter");
    switch(valuetype) {
    case V_INVOKE:
      u.invoke.v = p_v;
      u.invoke.t_list = p_t_list;
      u.invoke.ap_list = 0;
      break;
    default:
      FATAL_ERROR("Value::Value()");
    }
  }

  // -
  Value::Value(operationtype_t p_optype)
    : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0), in_brackets(false)
  {
    u.expr.v_optype = p_optype;
    u.expr.state = EXPR_NOT_CHECKED;
    switch(p_optype) {
    case OPTYPE_RND:
    case OPTYPE_COMP_NULL:
    case OPTYPE_COMP_MTC:
    case OPTYPE_COMP_SYSTEM:
    case OPTYPE_COMP_SELF:
    case OPTYPE_COMP_RUNNING_ANY:
    case OPTYPE_COMP_RUNNING_ALL:
    case OPTYPE_COMP_ALIVE_ANY:
    case OPTYPE_COMP_ALIVE_ALL:
    case OPTYPE_TMR_RUNNING_ANY:
    case OPTYPE_GETVERDICT:
    case OPTYPE_TESTCASENAME:
Elemer Lelik's avatar
Elemer Lelik committed
    case OPTYPE_PROF_RUNNING:
      break;
    default:
      FATAL_ERROR("Value::Value()");
    } // switch
  }

  // v1
  Value::Value(operationtype_t p_optype, Value *p_v1)
    : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0), in_brackets(false)
  {
    u.expr.v_optype = p_optype;
    u.expr.state = EXPR_NOT_CHECKED;
    switch(p_optype) {
    case OPTYPE_UNARYPLUS:
    case OPTYPE_UNARYMINUS:
    case OPTYPE_NOT:
    case OPTYPE_NOT4B:
    case OPTYPE_BIT2HEX:
    case OPTYPE_BIT2INT:
    case OPTYPE_BIT2OCT:
    case OPTYPE_BIT2STR:
    case OPTYPE_BSON2JSON:
    case OPTYPE_CBOR2JSON:
    case OPTYPE_CHAR2INT:
    case OPTYPE_CHAR2OCT:
    case OPTYPE_FLOAT2INT:
    case OPTYPE_FLOAT2STR:
    case OPTYPE_HEX2BIT:
    case OPTYPE_HEX2INT:
    case OPTYPE_HEX2OCT:
    case OPTYPE_HEX2STR:
    case OPTYPE_INT2CHAR:
    case OPTYPE_INT2FLOAT:
    case OPTYPE_INT2STR:
    case OPTYPE_INT2UNICHAR:
    case OPTYPE_JSON2BSON:
    case OPTYPE_JSON2CBOR:
    case OPTYPE_OCT2BIT:
    case OPTYPE_OCT2CHAR:
    case OPTYPE_OCT2HEX:
    case OPTYPE_OCT2INT:
    case OPTYPE_OCT2STR:
    case OPTYPE_STR2BIT:
    case OPTYPE_STR2FLOAT:
    case OPTYPE_STR2HEX:
    case OPTYPE_STR2INT:
    case OPTYPE_STR2OCT:
    case OPTYPE_UNICHAR2INT:
    case OPTYPE_UNICHAR2CHAR:
    case OPTYPE_ENUM2INT:
    case OPTYPE_RNDWITHVAL:
    case OPTYPE_REMOVE_BOM:
    case OPTYPE_GET_STRINGENCODING:
    case OPTYPE_DECODE_BASE64:
      if(!p_v1) FATAL_ERROR("Value::Value()");
      u.expr.v1=p_v1;
      break;
    case OPTYPE_HOSTID:
      u.expr.v1=p_v1;
      break;
    default:
      FATAL_ERROR("Value::Value()");
    } // switch
  }
  
  // v1 [r2] b4
  Value::Value(operationtype_t p_optype, Value* p_v1, Ttcn::Ref_base *p_r2,
               bool p_b4)
    : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0), in_brackets(false)
  {
    u.expr.v_optype = p_optype;
    u.expr.state = EXPR_NOT_CHECKED;
    switch(p_optype) {
    case OPTYPE_COMP_RUNNING:
    case OPTYPE_COMP_ALIVE:
      if (p_v1 == NULL) {