fixed Segfault in decmatch confomance test cases (artf764443)
[deliverable/titan.core.git] / compiler2 / Value.cc
index 3a8ade1950d5d85bcba6e811c4c24009ecb1f27a..56a05debd9441488a562d67e3a32a0b7a0936572 100644 (file)
@@ -1,10 +1,33 @@
-///////////////////////////////////////////////////////////////////////////////
-// Copyright (c) 2000-2015 Ericsson Telecom AB
-// 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
-///////////////////////////////////////////////////////////////////////////////
+/******************************************************************************
+ * Copyright (c) 2000-2016 Ericsson Telecom AB
+ * 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
+ *   Szabo, Bence Janos
+ *   Szabo, Janos Zoltan – initial implementation
+ *   Szalai, Gabor
+ *   Tatarka, Gabor
+ *   Zalanyi, Balazs Andor
+ *
+ ******************************************************************************/
 #include "../common/dbgnew.hh"
 #include "Value.hh"
 #include "Identifier.hh"
@@ -188,6 +211,9 @@ namespace Common {
       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:
@@ -256,6 +282,15 @@ namespace Common {
       case OPTYPE_TTCN2STRING:
         u.expr.ti1=p.u.expr.ti1->clone();
         break;
+      case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
+        u.expr.ti1=p.u.expr.ti1->clone();
+        u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
+        break; 
+      case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
+        u.expr.r1 = p.u.expr.r1->clone();
+        u.expr.r2 = p.u.expr.r2->clone();
+        u.expr.v3=p.u.expr.v3?p.u.expr.v3->clone():0;
+        break;
       case OPTYPE_UNDEF_RUNNING:
       case OPTYPE_TMR_READ:
       case OPTYPE_TMR_RUNNING:
@@ -266,6 +301,11 @@ namespace Common {
         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;
@@ -308,6 +348,7 @@ namespace Common {
         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;
       default:
@@ -490,6 +531,7 @@ namespace Common {
     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
@@ -559,6 +601,15 @@ namespace Common {
     case OPTYPE_TTCN2STRING:
       delete u.expr.ti1;
       break;
+    case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
+      delete u.expr.ti1;
+      delete u.expr.v2;
+      break;
+    case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
+      delete u.expr.r1;
+      delete u.expr.r2;
+      delete u.expr.v3;
+      break;
     case OPTYPE_UNDEF_RUNNING:
     case OPTYPE_TMR_READ:
     case OPTYPE_TMR_RUNNING:
@@ -569,6 +620,11 @@ namespace Common {
       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;
@@ -606,6 +662,7 @@ namespace Common {
       delete u.expr.v3;
       break;
     case OPTYPE_LOG2STR:
+    case OPTYPE_ANY2UNISTR:
       delete u.expr.logargs;
       break;
     default:
@@ -869,6 +926,9 @@ namespace Common {
       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
@@ -887,10 +947,13 @@ namespace Common {
     case OPTYPE_ISVALUE:
     case OPTYPE_ISBOUND:
     case OPTYPE_ENCODE:
+    case OPTYPE_ENCVALUE_UNICHAR:
     case OPTYPE_ISPRESENT:
     case OPTYPE_TTCN2STRING:
       if(!p_ti1) FATAL_ERROR("Value::Value()");
       u.expr.ti1=p_ti1;
+      // Needed in the case of OPTYPE_ENCVALUE_UNICHAR
+      u.expr.v2=NULL;
       break;
     default:
       FATAL_ERROR("Value::Value()");
@@ -953,7 +1016,7 @@ namespace Common {
     }
   }
 
-  // r1 [v2]
+  // r1 [v2] or [r1] v2
   Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Value *p_v2)
     : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
   {
@@ -965,6 +1028,12 @@ namespace Common {
       u.expr.r1=p_r1;
       u.expr.v2=p_v2;
       break;
+    case OPTYPE_CHECKSTATE_ANY:
+    case OPTYPE_CHECKSTATE_ALL:
+      if(!p_v2) FATAL_ERROR("Value::Value()");
+      u.expr.r1=p_r1; // may be null if any port or all port
+      u.expr.v2=p_v2;
+      break;
     default:
       FATAL_ERROR("Value::Value()");
     } // switch
@@ -1072,12 +1141,29 @@ namespace Common {
       u.expr.v1=p_v1;
       u.expr.v2=p_v2;
       u.expr.v3=p_v3;
-      break;
+      break;   
     default:
       FATAL_ERROR("Value::Value()");
     } // switch
   }
 
+  // ti1 [v2]
+  Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1,  Value *p_v2)
+    : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
+  {
+    u.expr.v_optype = p_optype;
+    u.expr.state = EXPR_NOT_CHECKED;
+    switch(p_optype) {
+    case OPTYPE_ENCVALUE_UNICHAR:
+      if(!p_ti1 || !p_v2) FATAL_ERROR("Value::Value()");
+      u.expr.ti1=p_ti1;
+      u.expr.v2=p_v2;
+      break;
+    default:
+      FATAL_ERROR("Value::Value()");
+    } // switch
+  }
+  
   // ti1 v2 v3
   Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2, Value *p_v3)
     : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
@@ -1156,6 +1242,7 @@ namespace Common {
     u.expr.state = EXPR_NOT_CHECKED;
     switch(p_optype) {
     case OPTYPE_LOG2STR:
+    case OPTYPE_ANY2UNISTR:
       if (!p_logargs) FATAL_ERROR("Value::Value()");
       u.expr.logargs = p_logargs;
       break;
@@ -1253,9 +1340,31 @@ namespace Common {
     u.expr.state = EXPR_NOT_CHECKED;
     switch(p_optype) {
     case OPTYPE_DECODE:
+    case OPTYPE_DECVALUE_UNICHAR:
       if(!p_r1 || !p_r2) FATAL_ERROR("Value::Value()");
       u.expr.r1=p_r1;
       u.expr.r2=p_r2;
+      // Needed in the case of OPTYPE_DECVALUE_UNICHAR
+      u.expr.v3=NULL;
+      break;
+    default:
+      FATAL_ERROR("Value::Value()");
+    } // switch
+  }
+  
+  // r1 r2 [v3]
+  Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Ttcn::Ref_base *p_r2,
+          Value *p_v3)
+    : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
+  {
+    u.expr.v_optype = p_optype;
+    u.expr.state = EXPR_NOT_CHECKED;
+    switch(p_optype) {
+    case OPTYPE_DECVALUE_UNICHAR:
+      if(!p_r1 || !p_r2 || !p_v3) FATAL_ERROR("Value::Value()");
+      u.expr.r1=p_r1;
+      u.expr.r2=p_r2;
+      u.expr.v3=p_v3;
       break;
     default:
       FATAL_ERROR("Value::Value()");
@@ -1436,6 +1545,9 @@ namespace Common {
     case OPTYPE_DECODE_BASE64:
       u.expr.v1->set_fullname(p_fullname+".<operand>");
       break;
+    case OPTYPE_HOSTID: // [v1]
+      if(u.expr.v1) u.expr.v1->set_fullname(p_fullname+".<operand>");
+      break;
     case OPTYPE_ADD: // v1 v2
     case OPTYPE_SUBTRACT:
     case OPTYPE_MULTIPLY:
@@ -1506,6 +1618,14 @@ namespace Common {
     case OPTYPE_TTCN2STRING:
       u.expr.ti1->set_fullname(p_fullname+".<operand>");
       break;
+    case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
+      u.expr.ti1->set_fullname(p_fullname+".<operand1>");
+      if (u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
+      break;
+    case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
+      u.expr.r1->set_fullname(p_fullname+".<operand1>");
+      u.expr.r2->set_fullname(p_fullname+".<operand2>");
+      if (u.expr.v3) u.expr.v3->set_fullname(p_fullname+".<operand3>");
     case OPTYPE_UNDEF_RUNNING: // r1
     case OPTYPE_TMR_READ:
     case OPTYPE_TMR_RUNNING:
@@ -1553,6 +1673,13 @@ namespace Common {
     case OPTYPE_LOG2STR:
       u.expr.logargs->set_fullname(p_fullname+".<logargs>");
       break;
+    case OPTYPE_ANY2UNISTR:
+      u.expr.logargs->set_fullname(p_fullname+".<logarg>");
+      break;
+    case OPTYPE_CHECKSTATE_ANY: // [r1] v2
+    case OPTYPE_CHECKSTATE_ALL:
+      u.expr.v2->set_fullname(p_fullname+".<operand1>");
+      break;
     default:
       FATAL_ERROR("Value::set_fullname_expr()");
     } // switch
@@ -1616,6 +1743,9 @@ namespace Common {
     case OPTYPE_DECODE_BASE64:
       u.expr.v1->set_my_scope(p_scope);
       break;
+    case OPTYPE_HOSTID: // [v1]
+      if(u.expr.v1) u.expr.v1->set_my_scope(p_scope);
+      break;
     case OPTYPE_ADD: // v1 v2
     case OPTYPE_SUBTRACT:
     case OPTYPE_MULTIPLY:
@@ -1686,6 +1816,15 @@ namespace Common {
     case OPTYPE_TTCN2STRING:
       u.expr.ti1->set_my_scope(p_scope);
       break;
+    case OPTYPE_ENCVALUE_UNICHAR: //ti1 [v2]
+      u.expr.ti1->set_my_scope(p_scope);
+      if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
+      break;
+    case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
+      u.expr.r1->set_my_scope(p_scope);
+      u.expr.r2->set_my_scope(p_scope);
+      if(u.expr.v3) u.expr.v3->set_my_scope(p_scope);
+      break;
     case OPTYPE_UNDEF_RUNNING: // r1
     case OPTYPE_TMR_READ:
     case OPTYPE_TMR_RUNNING:
@@ -1696,6 +1835,11 @@ namespace Common {
       u.expr.r1->set_my_scope(p_scope);
       if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
       break;
+    case OPTYPE_CHECKSTATE_ANY: // [r1] v2
+    case OPTYPE_CHECKSTATE_ALL:
+      if(u.expr.r1) u.expr.r1->set_my_scope(p_scope);
+      u.expr.v2->set_my_scope(p_scope);
+      break;
     case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
       u.expr.r1->set_my_scope(p_scope);
       if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
@@ -1732,6 +1876,7 @@ namespace Common {
        u.expr.v3->set_my_scope(p_scope);
       break;
     case OPTYPE_LOG2STR:
+    case OPTYPE_ANY2UNISTR:
       u.expr.logargs->set_my_scope(p_scope);
       break;
     default:
@@ -1926,6 +2071,9 @@ namespace Common {
       case OPTYPE_REMOVE_BOM:
         u.expr.v1->set_code_section(p_code_section);
         break;
+      case OPTYPE_HOSTID: // [v1]
+        if(u.expr.v1) u.expr.v1->set_code_section(p_code_section);
+        break;
       case OPTYPE_ADD: // v1 v2
       case OPTYPE_SUBTRACT:
       case OPTYPE_MULTIPLY:
@@ -1996,6 +2144,15 @@ namespace Common {
       case OPTYPE_TTCN2STRING:
         u.expr.ti1->set_code_section(p_code_section);
         break;
+      case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
+        u.expr.ti1->set_code_section(p_code_section);
+        if (u.expr.v2) u.expr.v2->set_code_section(p_code_section);
+        break;
+      case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
+        u.expr.r1->set_code_section(p_code_section);
+        u.expr.r2->set_code_section(p_code_section);
+        if (u.expr.v3) u.expr.v3->set_code_section(p_code_section);
+        break;
       case OPTYPE_UNDEF_RUNNING: // r1
       case OPTYPE_TMR_READ:
       case OPTYPE_TMR_RUNNING:
@@ -2006,6 +2163,11 @@ namespace Common {
         u.expr.r1->set_code_section(p_code_section);
         if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
         break;
+      case OPTYPE_CHECKSTATE_ANY: // [r1] v2
+      case OPTYPE_CHECKSTATE_ALL:
+        if(u.expr.r1) u.expr.r1->set_code_section(p_code_section);
+        u.expr.v2->set_code_section(p_code_section);
+        break;
       case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
         u.expr.r1->set_code_section(p_code_section);
         if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
@@ -2047,6 +2209,7 @@ namespace Common {
           u.expr.v3->set_code_section(p_code_section);
       break;
       case OPTYPE_LOG2STR:
+      case OPTYPE_ANY2UNISTR:
         u.expr.logargs->set_code_section(p_code_section);
         break;
       default:
@@ -2467,6 +2630,9 @@ namespace Common {
         u.val_Real = i_mant * pow(static_cast<double>(i_base),
          static_cast<double>(i_exp));
         break; }
+      case V_NOTUSED:
+        clean_up();
+        break;
       default:
         FATAL_ERROR("Value::set_valuetype()");
       } // switch
@@ -2535,6 +2701,15 @@ namespace Common {
         FATAL_ERROR("Value::set_valuetype()");
       }
       break;
+    case V_SET:
+    case V_CHOICE:
+      if (p_valuetype == V_NOTUSED) {
+        clean_up();
+      }
+      else {
+        FATAL_ERROR("Value::set_valuetype()");
+      }
+      break;
     case V_TTCN3_NULL:
       switch (p_valuetype) {
       case V_DEFAULT_NULL:
@@ -2774,6 +2949,8 @@ namespace Common {
       case OPTYPE_ISVALUE:
       case OPTYPE_ISBOUND:
       case OPTYPE_PROF_RUNNING:
+      case OPTYPE_CHECKSTATE_ANY:
+      case OPTYPE_CHECKSTATE_ALL:
         return Type::T_BOOL;
       case OPTYPE_GETVERDICT:
         return Type::T_VERDICT;
@@ -2995,6 +3172,7 @@ namespace Common {
       case OPTYPE_SIZEOF:
       case OPTYPE_DECODE:
       case OPTYPE_ENUM2INT:
+      case OPTYPE_DECVALUE_UNICHAR:
         return Type::T_INT;
       case OPTYPE_BIT2STR:
       case OPTYPE_FLOAT2STR:
@@ -3009,9 +3187,12 @@ namespace Common {
       case OPTYPE_TTCN2STRING:
       case OPTYPE_GET_STRINGENCODING:
       case OPTYPE_ENCODE_BASE64:
+      case OPTYPE_HOSTID:
         return Type::T_CSTR;
       case OPTYPE_INT2UNICHAR:
       case OPTYPE_OCT2UNICHAR:
+      case OPTYPE_ENCVALUE_UNICHAR:
+      case OPTYPE_ANY2UNISTR:
         return Type::T_USTR;
       case OPTYPE_INT2BIT:
       case OPTYPE_HEX2BIT:
@@ -3272,6 +3453,18 @@ namespace Common {
       return "getverdict()";
     case OPTYPE_TESTCASENAME:
       return "testcasename()";
+    case OPTYPE_CHECKSTATE_ANY:
+      if (u.expr.r1) {
+        return "port.checkstate()";
+      } else {
+        return "any port.checkstate()";
+      }
+    case OPTYPE_CHECKSTATE_ALL:
+      if (u.expr.r1) {
+        return "port.checkstate()";
+      } else {
+        return "all port.checkstate()";
+      }
     case OPTYPE_UNARYPLUS: // v1
       return "unary +";
     case OPTYPE_UNARYMINUS:
@@ -3358,6 +3551,8 @@ namespace Common {
       return "encode_base64()";
     case OPTYPE_DECODE_BASE64:
       return "decode_base64()";
+    case OPTYPE_HOSTID: // [v1]
+      return "hostid()";
     case OPTYPE_ADD: // v1 v2
       return "+";
     case OPTYPE_SUBTRACT:
@@ -3412,6 +3607,10 @@ namespace Common {
       return "int2oct()";
     case OPTYPE_OCT2UNICHAR:
       return "oct2unichar()";
+    case OPTYPE_ENCVALUE_UNICHAR:
+      return "encvalue_unichar()";
+    case OPTYPE_DECVALUE_UNICHAR:
+      return "decvalue_unichar()";
     case OPTYPE_SUBSTR:
       return "substr()";
     case OPTYPE_REGEXP:
@@ -3455,6 +3654,8 @@ namespace Common {
       return "isbound()";
     case OPTYPE_LOG2STR:
       return "log2str()";
+    case OPTYPE_ANY2UNISTR:
+      return "any2unistr()";
     case OPTYPE_TTCN2STRING:
       return "ttcn2string()";
     case OPTYPE_PROF_RUNNING:
@@ -5279,7 +5480,8 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
   void Value::chk_expr_operand_encode(ReferenceChain *refch,
     Type::expected_value_t exp_val) {
 
-    Error_Context cntxt(this, "In the parameter of encvalue()");
+    Error_Context cntxt(this, "In the parameter of %s",
+      u.expr.v_optype == OPTYPE_ENCVALUE_UNICHAR ? "encvalue_unichar()" : "encvalue()");
     Type t_chk(Type::T_ERROR);
     Type* t_type;
 
@@ -5297,7 +5499,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       error("Cannot determine type of value");
       goto error;
     }
-
+    
     // todo: fix this
     /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
       error("Expecting a value of a type with coding attributes in first"
@@ -5309,7 +5511,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
     if(!disable_attribute_validation()) {
       t_type->chk_coding(true);
     }
-
+    
     switch (t_type->get_typetype()) {
     case Type::T_UNDEF:
     case Type::T_ERROR:
@@ -5336,9 +5538,10 @@ error:
     set_valuetype(V_ERROR);
   }
 
-  void Value::chk_expr_operands_decode()
+  void Value::chk_expr_operands_decode(operationtype_t p_optype)
   {
-    Error_Context cntxt(this, "In the parameters of decvalue()");
+    Error_Context cntxt(this, "In the parameters of %s",
+      p_optype == OPTYPE_DECVALUE_UNICHAR ? "decvalue_unichar()" : "decvalue()");
     Ttcn::Ref_base* ref = u.expr.r1;
     Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
     Type* t_type = 0;
@@ -5392,9 +5595,22 @@ error:
     if (!t_type) {
       goto error;
     }
-    if (t_type->get_type_refd_last()->get_typetype() != Type::T_BSTR){
-      error("First parameter has to be a bitstring");
-      goto error;
+    switch(p_optype) {
+      case OPTYPE_DECODE:
+        if (t_type->get_type_refd_last()->get_typetype() != Type::T_BSTR){
+          error("First parameter has to be a bitstring");
+          goto error;
+        }
+        break;
+      case OPTYPE_DECVALUE_UNICHAR:
+        if (t_type->get_type_refd_last()->get_typetype() != Type::T_USTR){
+          error("First parameter has to be a universal charstring");
+          goto error;
+        }
+        break; 
+      default:
+        FATAL_ERROR("Value::chk_expr_decode_operands()");
+        break;
     }
 
     ref = u.expr.r2;
@@ -5927,8 +6143,8 @@ error:
     if (!governor) {
       string str;
       ti->append_stringRepr( str);
-      ti->error("Cannot determine the argument type of %s in the`%s' operation.\n"
-                "If type is known, use valuof(<type>: %s) as argument.",
+      ti->error("Cannot determine the argument type of %s in the `%s' operation.\n"
+                "If type is known, use valueof(<type>: %s) as argument.",
                 str.c_str(), get_opname(), str.c_str()); 
       set_valuetype(V_ERROR);
     }
@@ -6399,6 +6615,17 @@ error:
         chk_expr_val_ustr_7bitchars(v1, the, opname);
       }
       break;
+    case OPTYPE_HOSTID:
+      v1=u.expr.v1 ? u.expr.v1 : 0;
+      if (v1)
+      {
+        Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
+        v1->set_lowerid_to_ref();
+        tt1=v1->get_expr_returntype(exp_val);
+        chk_expr_operandtype_cstr(tt1, second, opname, v1);
+        chk_expr_eval_value(v1, t_chk, refch, exp_val);
+      }
+      break;
     case OPTYPE_UNICHAR2OCT: // v1 [v2]
       v1=u.expr.v1;
       {
@@ -6437,6 +6664,30 @@ error:
         chk_expr_eval_value(v2, t_chk, refch, exp_val);
       }
       break;
+    case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
+      chk_expr_operand_encode(refch, exp_val);
+      v2=u.expr.v2 ? u.expr.v2 : 0;
+      if (v2)
+      {
+        Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
+        v2->set_lowerid_to_ref();
+        tt2=v2->get_expr_returntype(exp_val);
+        chk_expr_operandtype_charstr(tt2, second, opname, v2);
+        chk_expr_eval_value(v2, t_chk, refch, exp_val);
+      }
+      break;
+    case OPTYPE_DECVALUE_UNICHAR:
+      chk_expr_operands_decode(OPTYPE_DECVALUE_UNICHAR);
+      v3=u.expr.v3 ? u.expr.v3 : 0;
+      if (v3)
+      {
+        Error_Context cntxt(this, "In the thrid operand of operation `%s'", opname);
+        v3->set_lowerid_to_ref();
+        tt3=v3->get_expr_returntype(exp_val);
+        chk_expr_operandtype_charstr(tt3, third, opname, v3);
+        chk_expr_eval_value(v3, t_chk, refch, exp_val);
+      }
+      break;
     case OPTYPE_ADD: // v1 v2
     case OPTYPE_SUBTRACT:
     case OPTYPE_MULTIPLY:
@@ -6718,7 +6969,7 @@ error:
       chk_expr_operands_int2binstr();
       break;
     case OPTYPE_DECODE:
-      chk_expr_operands_decode();
+      chk_expr_operands_decode(OPTYPE_DECODE);
       break;
     case OPTYPE_SUBSTR:
       {
@@ -6889,6 +7140,18 @@ error:
       chk_expr_operand_activate(u.expr.r1, the, opname);
       chk_expr_dynamic_part(exp_val, true);
       break;
+    case OPTYPE_CHECKSTATE_ANY: // [r1] v2
+    case OPTYPE_CHECKSTATE_ALL:
+      chk_expr_dynamic_part(exp_val, false);
+      v2=u.expr.v2;
+      if(v2) {
+        Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
+        v2->set_lowerid_to_ref();
+        tt2=v2->get_expr_returntype(exp_val);
+       chk_expr_operandtype_cstr(tt2, first, opname, v2);
+       chk_expr_eval_value(v2, t_chk, refch, exp_val);
+      }
+      break;
     case OPTYPE_ACTIVATE_REFD:{ //v1 t_list2
       Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
       chk_expr_operand_activate_refd(u.expr.v1,u.expr.t_list2->get_tis(), parlist, the,
@@ -6955,7 +7218,8 @@ error:
       }
       chk_expr_operands_replace();
       break; }
-    case OPTYPE_LOG2STR: {
+    case OPTYPE_LOG2STR:
+    case OPTYPE_ANY2UNISTR: {
       Error_Context cntxt(this, "In the operand of operation `%s'", opname);
       u.expr.logargs->chk();
       if (!semantic_check_only) u.expr.logargs->join_strings();
@@ -7024,6 +7288,7 @@ error:
     case OPTYPE_MATCH: // v1 t2
     case OPTYPE_ISCHOSEN_T:
     case OPTYPE_LOG2STR:
+    case OPTYPE_ANY2UNISTR:
     case OPTYPE_ENCODE:
     case OPTYPE_DECODE:
     case OPTYPE_ISBOUND:
@@ -7033,6 +7298,11 @@ error:
     case OPTYPE_OCT2UNICHAR:
     case OPTYPE_ENCODE_BASE64:
     case OPTYPE_DECODE_BASE64:
+    case OPTYPE_ENCVALUE_UNICHAR:
+    case OPTYPE_DECVALUE_UNICHAR:
+    case OPTYPE_CHECKSTATE_ANY:
+    case OPTYPE_CHECKSTATE_ALL:
+    case OPTYPE_HOSTID:
       break;
     case OPTYPE_TESTCASENAME: { // -
       if (!my_scope) FATAL_ERROR("Value::evaluate_value()");
@@ -8329,6 +8599,11 @@ error:
       case OPTYPE_UNICHAR2OCT:
       case OPTYPE_ENCODE_BASE64:
       case OPTYPE_DECODE_BASE64:
+      case OPTYPE_ENCVALUE_UNICHAR:
+      case OPTYPE_DECVALUE_UNICHAR:
+      case OPTYPE_CHECKSTATE_ANY:
+      case OPTYPE_CHECKSTATE_ALL:
+      case OPTYPE_HOSTID:
         return true;
       case OPTYPE_COMP_NULL: // -
         return false;
@@ -8463,6 +8738,7 @@ error:
       case OPTYPE_ISCHOSEN_V:
         return u.expr.v1->is_unfoldable(refch, exp_val);
       case OPTYPE_LOG2STR:
+      case OPTYPE_ANY2UNISTR:
       case OPTYPE_TTCN2STRING:
         return true;
       default:
@@ -9542,6 +9818,13 @@ error:
       u.expr.t1->chk_recursions(refch);
       refch.prev_state();
       break;
+    case OPTYPE_HOSTID: // [v1]
+      if (u.expr.v1) {
+        refch.mark_state();
+        u.expr.v1->chk_recursions(refch);
+        refch.prev_state();
+      }
+      break;
     case OPTYPE_ADD: // v1 v2
     case OPTYPE_SUBTRACT:
     case OPTYPE_MULTIPLY:
@@ -9648,6 +9931,25 @@ error:
       u.expr.ti1->chk_recursions(refch);
       refch.prev_state();
       break;
+    case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
+      refch.mark_state();
+      u.expr.ti1->chk_recursions(refch);
+      refch.prev_state();
+      if (u.expr.v2){
+        refch.mark_state();
+        u.expr.v2->chk_recursions(refch);
+        refch.prev_state();
+      }
+      break;
+    case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
+      chk_recursions_expr_decode(u.expr.r1, refch);
+      chk_recursions_expr_decode(u.expr.r2, refch);
+      if (u.expr.v3){
+        refch.mark_state();
+        u.expr.v3->chk_recursions(refch);
+        refch.prev_state();
+      }
+      break;
     case OPTYPE_MATCH: // v1 t2
       refch.mark_state();
       u.expr.v1->chk_recursions(refch);
@@ -9657,6 +9959,7 @@ error:
       refch.prev_state();
       break;
     case OPTYPE_LOG2STR:
+    case OPTYPE_ANY2UNISTR:
       u.expr.logargs->chk_recursions(refch);
       break;
     default:
@@ -9786,6 +10089,9 @@ error:
       break; // self-ref can't happen
     case Ttcn::Template::TEMPLATE_INVOKE:
       break; // assume self-ref can't happen
+    case Ttcn::Template::DECODE_MATCH:
+      self_ref |= chk_expr_self_ref_templ(t->get_decode_target()->get_Template(), lhs);
+      break;
     case Ttcn::Template::TEMPLATE_ERROR:
       //FATAL_ERROR("Value::chk_expr_self_ref_templ()");
       break;
@@ -9808,7 +10114,7 @@ error:
       }
     }
     return gov->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
-      INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT,
+      INCOMPLETE_NOT_ALLOWED, OMIT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT,
       is_str_elem);
   }
 
@@ -9831,6 +10137,8 @@ error:
     case OPTYPE_TMR_RUNNING_ANY: // -
     case OPTYPE_GETVERDICT: // -
     case OPTYPE_PROF_RUNNING: // -
+    case OPTYPE_CHECKSTATE_ANY:
+    case OPTYPE_CHECKSTATE_ALL:
       break; // nothing to do
 
     case OPTYPE_MATCH: // v1 t2
@@ -9878,6 +10186,9 @@ error:
     case OPTYPE_REMOVE_BOM:
       self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
       break;
+    case OPTYPE_HOSTID: // [v1]
+      if (u.expr.v1) self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
+      break;
     case OPTYPE_ADD: // v1 v2
     case OPTYPE_SUBTRACT: // v1 v2
     case OPTYPE_MULTIPLY: // v1 v2
@@ -9939,7 +10250,16 @@ error:
     case OPTYPE_TTCN2STRING:
       self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
       break;
-
+    case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
+      self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
+      if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
+      break;
+    case OPTYPE_DECVALUE_UNICHAR: { // r1 r2 [v3]
+      Common::Assignment *ass = u.expr.r2->get_refd_assignment();
+      self_ref |= (ass == lhs);
+      if (u.expr.v3) self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
+      goto label_r1;
+      break; }
     case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
       // component.create -- assume no self-ref
     case OPTYPE_ACTIVATE: // r1
@@ -9948,14 +10268,16 @@ error:
       // boolvar := a_timer.running -- assume no self-ref
       break;
       break;
-
+      
+    case OPTYPE_ANY2UNISTR:
     case OPTYPE_LOG2STR: {// logargs
       for (size_t i = 0, e = u.expr.logargs->get_nof_logargs(); i < e; ++i) {
         const Ttcn::LogArgument *la = u.expr.logargs->get_logarg_byIndex(i);
         switch (la->get_type()) {
         case Ttcn::LogArgument::L_UNDEF:
         case Ttcn::LogArgument::L_ERROR:
-          FATAL_ERROR("log2str argument type");
+          FATAL_ERROR("%s argument type",
+            u.expr.v_optype == OPTYPE_ANY2UNISTR ? "any2unistr" : "log2str");
           break; // not reached
 
         case Ttcn::LogArgument::L_MACRO:
@@ -10243,6 +10565,28 @@ error:
          if (u.expr.v2) return create_stringRepr_predef2("unichar2oct");
          else return create_stringRepr_predef1("unichar2oct");
       }
+      case OPTYPE_ENCVALUE_UNICHAR: {
+         if (u.expr.v2) return create_stringRepr_predef2("encvalue_unichar");
+         else return create_stringRepr_predef1("encvalue_unichar");
+      }
+      case OPTYPE_HOSTID: {
+        if (u.expr.v1) return create_stringRepr_predef1("hostid");   
+        else return string("hostid()");
+      }
+      case OPTYPE_DECVALUE_UNICHAR: {
+         if (u.expr.v3) {
+           string ret_val("decvalue_unichar");
+           ret_val += '(';
+           ret_val += u.expr.v1->get_stringRepr();
+           ret_val += ", ";
+           ret_val += u.expr.v2->get_stringRepr();
+           ret_val += ", ";
+           ret_val += u.expr.v3->get_stringRepr();
+           ret_val += ')';
+           return ret_val;
+         }
+         else return create_stringRepr_predef2("decvalue_unichar");
+      }
       case OPTYPE_STR2BIT:
         return create_stringRepr_predef1("str2bit");
       case OPTYPE_STR2FLOAT:
@@ -10407,6 +10751,8 @@ error:
        return ret_val; }
       case OPTYPE_LOG2STR:
         return string("log2str(...)");
+      case OPTYPE_ANY2UNISTR:
+        return string("any2unistr(...)");     
       case OPTYPE_MATCH: {
         string ret_val("match(");
         ret_val += u.expr.v1->get_stringRepr();
@@ -10463,6 +10809,22 @@ error:
         return u.expr.r1->get_dispname() + ".running";
       case OPTYPE_TMR_RUNNING_ANY:
         return string("any timer.running");
+      case OPTYPE_CHECKSTATE_ANY:
+      case OPTYPE_CHECKSTATE_ALL: {
+        string ret_val("");
+        if (u.expr.r1) {
+          ret_val += u.expr.r1->get_dispname();
+        } else {
+          if (u.expr.v_optype == OPTYPE_CHECKSTATE_ANY) {
+            ret_val += "any port";
+          } else if (u.expr.v_optype == OPTYPE_CHECKSTATE_ALL) {
+            ret_val += "all port";
+          }
+        }
+        ret_val += "checkstate(";
+        ret_val += u.expr.v2->get_stringRepr();
+        ret_val += ")";
+        return ret_val; }
       case OPTYPE_GETVERDICT:
         return string("getverdict");
       case OPTYPE_ACTIVATE: {
@@ -10621,7 +10983,7 @@ error:
   {
     string ret_val(function_name);
     ret_val += '(';
-    if (u.expr.v_optype == OPTYPE_ENCODE) { // ti1, not v1
+    if (u.expr.v_optype == OPTYPE_ENCODE || u.expr.v_optype == OPTYPE_ENCVALUE_UNICHAR) { // ti1, not v1
       ret_val += u.expr.ti1->get_specific_value()->get_stringRepr();
     }
     else ret_val += u.expr.v1->get_stringRepr();
@@ -11097,6 +11459,9 @@ error:
         FATAL_ERROR("Value::generate_code_init()");
       }
       break;
+    case V_NOTUSED:
+      // unbound value, don't generate anything
+      break;
     default:
       FATAL_ERROR("Value::generate_code_init()");
     }
@@ -11107,20 +11472,18 @@ error:
     return str;
   }
 
-  char *Value::rearrange_init_code(char *str)
+  char *Value::rearrange_init_code(char *str, Common::Module* usage_mod)
   {
     switch (valuetype) {
     case V_REFD: {
       Ttcn::ActualParList *parlist = u.ref.ref->get_parlist();
       if (parlist) {
-       str = parlist->rearrange_init_code(str,
-         u.ref.ref->get_refd_assignment()->get_my_scope()->get_scope_mod_gen());
+       str = parlist->rearrange_init_code(str, usage_mod);
       }
       break; }
     case V_INVOKE: {
-      str = u.invoke.v->rearrange_init_code(str);
-      str = u.invoke.ap_list->rearrange_init_code(str,
-        u.invoke.v->get_expr_governor_last()->get_my_scope()->get_scope_mod_gen());
+      str = u.invoke.v->rearrange_init_code(str, usage_mod);
+      str = u.invoke.ap_list->rearrange_init_code(str, usage_mod);
       break; }
     case V_EXPR:
       switch (u.expr.v_optype) {
@@ -11161,17 +11524,18 @@ error:
       case OPTYPE_GET_STRINGENCODING:
       case OPTYPE_REMOVE_BOM:
       case OPTYPE_DECODE_BASE64:
-        str = u.expr.v1->rearrange_init_code(str);
+        str = u.expr.v1->rearrange_init_code(str, usage_mod);
         break;
       case OPTYPE_DECODE: {
         Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
-        Common::Assignment *ass = u.expr.r1->get_refd_assignment();
-        if (parlist) str = parlist->rearrange_init_code(str, ass->get_my_scope()->get_scope_mod_gen());
+        if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
 
         parlist = u.expr.r2->get_parlist();
-        ass = u.expr.r2->get_refd_assignment();
-        if (parlist) str = parlist->rearrange_init_code(str, ass->get_my_scope()->get_scope_mod_gen());
+        if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
         break; }
+      case OPTYPE_HOSTID:    
+        if (u.expr.v1) str = u.expr.v1->rearrange_init_code(str, usage_mod);
+        break;
       case OPTYPE_ADD:
       case OPTYPE_SUBTRACT:
       case OPTYPE_MULTIPLY:
@@ -11199,35 +11563,35 @@ error:
       case OPTYPE_INT2HEX:
       case OPTYPE_INT2OCT:
       //case OPTYPE_DECODE:
-        str = u.expr.v1->rearrange_init_code(str);
-        str = u.expr.v2->rearrange_init_code(str);
+        str = u.expr.v1->rearrange_init_code(str, usage_mod);
+        str = u.expr.v2->rearrange_init_code(str, usage_mod);
         break;
       case OPTYPE_UNICHAR2OCT: // v1 [v2]
       case OPTYPE_OCT2UNICHAR:
       case OPTYPE_ENCODE_BASE64:
-        str = u.expr.v1->rearrange_init_code(str);
-        if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str);
+        str = u.expr.v1->rearrange_init_code(str, usage_mod);
+        if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str, usage_mod);
         break;
       case OPTYPE_SUBSTR:
-        str = u.expr.ti1->rearrange_init_code(str, my_scope->get_scope_mod_gen());
-        str = u.expr.v2->rearrange_init_code(str);
-        str = u.expr.v3->rearrange_init_code(str);
+        str = u.expr.ti1->rearrange_init_code(str, usage_mod);
+        str = u.expr.v2->rearrange_init_code(str, usage_mod);
+        str = u.expr.v3->rearrange_init_code(str, usage_mod);
         break;
       case OPTYPE_REGEXP:
-        str = u.expr.ti1->rearrange_init_code(str, my_scope->get_scope_mod_gen());
-        str = u.expr.t2->rearrange_init_code(str, my_scope->get_scope_mod_gen());
-        str = u.expr.v3->rearrange_init_code(str);
+        str = u.expr.ti1->rearrange_init_code(str, usage_mod);
+        str = u.expr.t2->rearrange_init_code(str, usage_mod);
+        str = u.expr.v3->rearrange_init_code(str, usage_mod);
         break;
       case OPTYPE_DECOMP:
-        str = u.expr.v1->rearrange_init_code(str);
-        str = u.expr.v2->rearrange_init_code(str);
-        str = u.expr.v3->rearrange_init_code(str);
+        str = u.expr.v1->rearrange_init_code(str, usage_mod);
+        str = u.expr.v2->rearrange_init_code(str, usage_mod);
+        str = u.expr.v3->rearrange_init_code(str, usage_mod);
         break;
       case OPTYPE_REPLACE:
-        str = u.expr.ti1->rearrange_init_code(str, my_scope->get_scope_mod_gen());
-        str = u.expr.v2->rearrange_init_code(str);
-        str = u.expr.v3->rearrange_init_code(str);
-        str = u.expr.ti4->rearrange_init_code(str, my_scope->get_scope_mod_gen());
+        str = u.expr.ti1->rearrange_init_code(str, usage_mod);
+        str = u.expr.v2->rearrange_init_code(str, usage_mod);
+        str = u.expr.v3->rearrange_init_code(str, usage_mod);
+        str = u.expr.ti4->rearrange_init_code(str, usage_mod);
         break;
       case OPTYPE_LENGTHOF:
       case OPTYPE_SIZEOF:
@@ -11235,14 +11599,28 @@ error:
       case OPTYPE_ENCODE:
       case OPTYPE_ISPRESENT:
       case OPTYPE_TTCN2STRING:
-        str = u.expr.ti1->rearrange_init_code(str, my_scope->get_scope_mod_gen());
+        str = u.expr.ti1->rearrange_init_code(str, usage_mod);
+        break;
+      case OPTYPE_ENCVALUE_UNICHAR:
+        str = u.expr.ti1->rearrange_init_code(str, usage_mod);
+        if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str, usage_mod);
         break;
+      case OPTYPE_DECVALUE_UNICHAR: {
+        Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
+        Common::Assignment *ass = u.expr.r1->get_refd_assignment();
+        if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
+
+        parlist = u.expr.r2->get_parlist();
+        ass = u.expr.r2->get_refd_assignment();
+        if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
+        if (u.expr.v3) str = u.expr.v3->rearrange_init_code(str, usage_mod);
+        break; }
       case OPTYPE_ISCHOSEN_T:
-        str = u.expr.t1->rearrange_init_code(str, my_scope->get_scope_mod_gen());
+        str = u.expr.t1->rearrange_init_code(str, usage_mod);
         break;
       case OPTYPE_MATCH:
-        str = u.expr.v1->rearrange_init_code(str);
-        str = u.expr.t2->rearrange_init_code(str, my_scope->get_scope_mod_gen());
+        str = u.expr.v1->rearrange_init_code(str, usage_mod);
+        str = u.expr.t2->rearrange_init_code(str, usage_mod);
         break;
       default:
         // other kinds of expressions cannot appear within templates
@@ -11461,6 +11839,15 @@ error:
       else
         generate_code_expr_predef1(expr, "unichar2oct", u.expr.v1);
       break;
+    case OPTYPE_ENCVALUE_UNICHAR:
+        generate_code_expr_encvalue_unichar(expr);
+      break;
+    case OPTYPE_DECVALUE_UNICHAR:
+        generate_code_expr_decvalue_unichar(expr);
+      break;
+    case OPTYPE_HOSTID:
+      generate_code_expr_hostid(expr);
+      break;
     case OPTYPE_OCT2HEX:
       generate_code_expr_predef1(expr, "oct2hex", u.expr.v1);
       break;
@@ -11672,8 +12059,7 @@ error:
         expr->expr=mputstr(expr->expr, ".is_bound()");
         break;
       case OPTYPE_ISPRESENT:
-        expr->expr=mputprintf(expr->expr, ".is_present(%s)",
-          omit_in_value_list ? "TRUE" : "");
+        expr->expr=mputprintf(expr->expr, ".is_present()");
         break;
       case OPTYPE_SIZEOF:
         expr->expr=mputstr(expr->expr, ".size_of()");
@@ -11766,6 +12152,10 @@ error:
     case OPTYPE_ACTIVATE: // r1
       generate_code_expr_activate(expr);
       break;
+    case OPTYPE_CHECKSTATE_ANY: // [r1] v2
+    case OPTYPE_CHECKSTATE_ALL:
+      generate_code_expr_checkstate(expr);
+      break;
     case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
       generate_code_expr_activate_refd(expr);
       break;
@@ -11776,6 +12166,7 @@ error:
       generate_code_expr_execute_refd(expr);
       break;
     case OPTYPE_LOG2STR:
+    case OPTYPE_ANY2UNISTR:
       u.expr.logargs->generate_code_expr(expr);
       break;
     case OPTYPE_TTCN2STRING: {
@@ -12312,7 +12703,7 @@ error:
         is_templ ? ".valueof()" : "");
     Code::free_expr(&expr2);
   }
-
+  
   void Value::generate_code_expr_decode(expression_struct *expr)
   {
     expression_struct expr1, expr2;
@@ -12397,6 +12788,226 @@ error:
     Code::free_expr(&expr1);
     Code::free_expr(&expr2);
   }
+  
+void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
+  {
+    Value* v1 = 0;
+
+    Template* templ = u.expr.ti1->get_Template()->get_template_refd_last();
+    if (templ->get_templatetype() == Template::SPECIFIC_VALUE)
+      v1 = templ->get_specific_value();
+    Type* gov_last = templ->get_my_governor()->get_type_refd_last();
+
+    expression_struct expr2;
+    Code::init_expr(&expr2);
+
+    bool is_templ = false;
+    switch (templ->get_templatetype()) {
+    case Template::SPECIFIC_VALUE:
+      v1->generate_code_expr_mandatory(&expr2);
+      break;
+    default:
+      u.expr.ti1->generate_code(&expr2);
+      is_templ = true;
+      break;
+    }
+
+    if (!gov_last->is_coding_by_function()) {
+      const string& tmp_id = get_temporary_id();
+      const string& tmp_buf_id = get_temporary_id();
+      const string& tmp_ref_id = get_temporary_id();
+      expr->preamble = mputprintf(expr->preamble, "OCTETSTRING %s;\n",
+        tmp_id.c_str());
+      expr->preamble = mputprintf(expr->preamble, "TTCN_Buffer %s;\n",
+        tmp_buf_id.c_str());
+      if (expr2.preamble) { // copy preamble setting up the argument, if any
+        expr->preamble = mputstr(expr->preamble, expr2.preamble);
+        expr->preamble = mputc  (expr->preamble, '\n');
+      }
+      expr->preamble = mputprintf(expr->preamble, "%s const& %s = %s",
+        gov_last->get_genname_typedescriptor(
+          u.expr.ti1->get_Template()->get_my_scope()
+        ).c_str(),
+        tmp_ref_id.c_str(),
+        expr2.expr);
+      if (is_templ) // make a value out of the template, if needed
+        expr->preamble = mputprintf(expr->preamble, ".valueof()");
+      expr->preamble = mputprintf(expr->preamble,
+        ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
+        tmp_ref_id.c_str(),
+        gov_last->get_genname_typedescriptor(
+          u.expr.ti1->get_Template()->get_my_scope()
+        ).c_str(),
+        tmp_buf_id.c_str(),
+        gov_last->get_coding(true).c_str()
+      );
+      expr->preamble = mputstr(expr->preamble, ");\n");
+      expr->preamble = mputprintf(expr->preamble, "%s.get_string(%s);\n",
+        tmp_buf_id.c_str(),
+        tmp_id.c_str()
+      );
+      const char * v2_code = NULL;
+      if(u.expr.v2) {
+        v2_code = generate_code_char_coding_check(expr, u.expr.v2, "encvalue_unichar");
+      }
+      expr->expr = mputprintf(expr->expr, "oct2unichar(%s", tmp_id.c_str());
+      if(u.expr.v2) {
+        expr->expr = mputprintf(expr->expr, ", %s", v2_code);
+      } else {
+        expr->expr = mputprintf(expr->expr, ", \"UTF-8\"");  //default
+      }
+      expr->expr = mputprintf(expr->expr, ")");
+      if (expr2.postamble)
+        expr->postamble = mputstr(expr->postamble, expr2.postamble);
+    } else
+      expr->expr = mputprintf(expr->expr, "%s(%s%s)",
+        gov_last->get_coding(true).c_str(), expr2.expr,
+        is_templ ? ".valueof()" : "");
+    Code::free_expr(&expr2);
+  }
+
+  void Value::generate_code_expr_decvalue_unichar(expression_struct *expr)
+  {
+    expression_struct expr1, expr2;
+    Code::init_expr(&expr1);
+    Code::init_expr(&expr2);
+    u.expr.r1->generate_code(&expr1);
+    u.expr.r2->generate_code(&expr2);
+
+    Type* _type = u.expr.r2->get_refd_assignment()->get_Type()->
+      get_field_type(u.expr.r2->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE)->
+      get_type_refd_last();
+
+    if (expr1.preamble)
+      expr->preamble = mputprintf(expr->preamble, "%s", expr1.preamble);
+    if (expr2.preamble)
+      expr->preamble = mputprintf(expr->preamble, "%s", expr2.preamble);
+
+    if (!_type->is_coding_by_function()) {
+      const string& tmp_id = get_temporary_id();
+      const string& buffer_id = get_temporary_id();
+      const string& retval_id = get_temporary_id();
+      const bool optional = u.expr.r2->get_refd_assignment()->get_Type()->
+        field_is_optional(u.expr.r2->get_subrefs());
+
+      const char* v3_code = NULL;
+      if(u.expr.v3) {
+        v3_code = generate_code_char_coding_check(expr, u.expr.v3, "decvalue_unichar");
+      }
+      expr->preamble = mputprintf(expr->preamble,
+        "TTCN_Buffer %s(unichar2oct(%s, %s));\n"
+        "INTEGER %s;\n"
+        "TTCN_EncDec::set_error_behavior("
+        "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
+        "TTCN_EncDec::clear_error();\n",
+        buffer_id.c_str(),
+        expr1.expr,
+        u.expr.v3 ? v3_code : "\"UTF-8\"",
+        retval_id.c_str()
+      );
+      expr->preamble = mputprintf(expr->preamble,
+        "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
+        expr2.expr,
+        optional ? "()" : "",
+          _type->get_genname_typedescriptor(
+            u.expr.r2->get_my_scope()
+          ).c_str(),
+          buffer_id.c_str(),
+          _type->get_coding(false).c_str()
+      );
+      expr->preamble = mputprintf(expr->preamble,
+        "switch (TTCN_EncDec::get_last_error_type()) {\n"
+        "case TTCN_EncDec::ET_NONE: {\n"
+        "%s.cut();\n"
+        "OCTETSTRING %s;\n"
+        "%s.get_string(%s);\n"
+        "%s = oct2unichar(%s, %s);\n"
+        "%s = 0;\n"
+        "}break;\n"
+        "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
+        "case TTCN_EncDec::ET_LEN_ERR:\n"
+        "%s = 2;\n"
+        "break;\n"
+        "default:\n"
+        "%s = 1;\n"
+        "}\n"
+        "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
+        "TTCN_EncDec::EB_DEFAULT);\n"
+        "TTCN_EncDec::clear_error();\n",
+        buffer_id.c_str(),
+        tmp_id.c_str(),
+        buffer_id.c_str(),
+        tmp_id.c_str(),
+        expr1.expr,
+        tmp_id.c_str(),
+        u.expr.v3 ? v3_code : "\"UTF-8\"",
+        retval_id.c_str(),
+        retval_id.c_str(),
+        retval_id.c_str()
+      );
+      expr->expr = mputprintf(expr->expr, "%s", retval_id.c_str());
+    } else
+      expr->expr = mputprintf(expr->expr, "%s(%s, %s)",
+        _type->get_coding(false).c_str(), expr1.expr, expr2.expr);
+    if (expr1.postamble)
+      expr->postamble = mputprintf(expr->postamble, "%s", expr1.postamble);
+    if (expr2.postamble)
+      expr->postamble = mputprintf(expr->postamble, "%s", expr2.postamble);
+    Code::free_expr(&expr1);
+    Code::free_expr(&expr2);
+  }
+  
+  void Value::generate_code_expr_checkstate(expression_struct *expr)
+  {
+    if (u.expr.r1) { 
+      // It is a port if r1 is not null
+      u.expr.r1->generate_code_const_ref(expr);
+      expr->expr = mputstr(expr->expr, ".");
+    } else {
+      // it is an any or all port if r1 is null
+      if (u.expr.v_optype == OPTYPE_CHECKSTATE_ANY) {
+       expr->expr = mputstr(expr->expr, "PORT::any_");
+      } else if (u.expr.v_optype == OPTYPE_CHECKSTATE_ALL) {
+        expr->expr = mputstr(expr->expr, "PORT::all_");
+      } else {
+        FATAL_ERROR("Value::generate_code_expr_checkstate()");
+      }
+    }
+    expr->expr = mputstr(expr->expr, "check_port_state(");
+    u.expr.v2->generate_code_expr_mandatory(expr);
+    expr->expr = mputstr(expr->expr, ")");
+  }
+  
+  void Value::generate_code_expr_hostid(expression_struct *expr)
+  {
+    expr->expr = mputstr(expr->expr, "TTCN_Runtime::get_host_address(");
+    if (u.expr.v1) u.expr.v1->generate_code_expr_mandatory(expr);
+    else expr->expr = mputstr(expr->expr, "CHARSTRING(\"Ipv4orIpv6\")");
+    expr->expr = mputstr(expr->expr, ")");
+  }
+  
+  char* Value::generate_code_char_coding_check(expression_struct *expr, Value *v, const char *name)
+  {
+    expression_struct expr2;
+    Code::init_expr(&expr2);
+    v->generate_code_expr_mandatory(&expr2);
+    expr->preamble = mputprintf(expr->preamble,
+      "if (\"UTF-8\" != %s && \"UTF-16\" != %s && \"UTF-16LE\" != %s && \n"
+      "  \"UTF-16BE\" != %s && \"UTF-32\" != %s && \"UTF-32LE\" != %s && \n"
+      "  \"UTF-32BE\" != %s) {\n"
+      "   TTCN_error(\"%s: Invalid encoding parameter: %%s\", (const char*)%s);\n"
+      "}\n", //todo errorbehaviour?
+      expr2.expr,
+      expr2.expr,
+      expr2.expr,
+      expr2.expr,
+      expr2.expr,
+      expr2.expr,
+      expr2.expr,
+      name,
+      expr2.expr);
+    return expr2.expr;
+  }
 
   char *Value::generate_code_init_choice(char *str, const char *name)
   {
@@ -12878,6 +13489,9 @@ error:
       FATAL_ERROR("Value::has_single_expr()");
     case V_INT:
       return u.val_Int->is_native_fit();
+    case V_NOTUSED:
+      // should only happen when generating code for an unbound record/set value
+      return false;
     default:
       // other value types (literal values) do not need temporary reference
       return true;
@@ -13048,12 +13662,17 @@ error:
     case OPTYPE_GETVERDICT:
     case OPTYPE_TESTCASENAME:
     case OPTYPE_PROF_RUNNING:
+    case OPTYPE_CHECKSTATE_ANY:
+    case OPTYPE_CHECKSTATE_ALL:
+    case OPTYPE_HOSTID:
       return true;
     case OPTYPE_ENCODE:
     case OPTYPE_DECODE:
     case OPTYPE_ISBOUND:
     case OPTYPE_ISPRESENT:
     case OPTYPE_TTCN2STRING:
+    case OPTYPE_ENCVALUE_UNICHAR:
+    case OPTYPE_DECVALUE_UNICHAR:
       return false;
     case OPTYPE_UNARYPLUS: // v1
     case OPTYPE_UNARYMINUS:
@@ -13154,6 +13773,7 @@ error:
     case OPTYPE_VALUEOF: // ti1
       return u.expr.ti1->has_single_expr();
     case OPTYPE_LOG2STR:
+    case OPTYPE_ANY2UNISTR:
       return u.expr.logargs->has_single_expr();
     case OPTYPE_MATCH: // v1 t2
       return u.expr.v1->has_single_expr() &&
This page took 0.039244 seconds and 5 git commands to generate.