-///////////////////////////////////////////////////////////////////////////////
-// 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"
#include "ttcn3/Attributes.hh"
#include "../common/JSON_Tokenizer.hh"
+#include "ttcn3/Ttcn2Json.hh"
#include <math.h>
#include <regex.h>
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_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:
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;
break;
case OPTYPE_LOG2STR:
+ case OPTYPE_ANY2UNISTR:
u.expr.logargs = p.u.expr.logargs->clone();
break;
default:
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_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:
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_LOG2STR:
+ case OPTYPE_ANY2UNISTR:
delete u.expr.logargs;
break;
default:
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
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()");
}
}
- // 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)
{
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
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)
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;
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()");
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:
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:
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
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:
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:
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);
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:
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:
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:
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);
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:
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
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:
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;
case OPTYPE_SIZEOF:
case OPTYPE_DECODE:
case OPTYPE_ENUM2INT:
+ case OPTYPE_DECVALUE_UNICHAR:
return Type::T_INT;
case OPTYPE_BIT2STR:
case OPTYPE_FLOAT2STR:
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:
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:
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:
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:
return "isbound()";
case OPTYPE_LOG2STR:
return "log2str()";
+ case OPTYPE_ANY2UNISTR:
+ return "any2unistr()";
case OPTYPE_TTCN2STRING:
return "ttcn2string()";
case OPTYPE_PROF_RUNNING:
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;
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"
if(!disable_attribute_validation()) {
t_type->chk_coding(true);
}
-
+
switch (t_type->get_typetype()) {
case Type::T_UNDEF:
case Type::T_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;
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;
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);
}
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;
{
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:
chk_expr_operands_int2binstr();
break;
case OPTYPE_DECODE:
- chk_expr_operands_decode();
+ chk_expr_operands_decode(OPTYPE_DECODE);
break;
case OPTYPE_SUBSTR:
{
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,
}
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();
case OPTYPE_MATCH: // v1 t2
case OPTYPE_ISCHOSEN_T:
case OPTYPE_LOG2STR:
+ case OPTYPE_ANY2UNISTR:
case OPTYPE_ENCODE:
case OPTYPE_DECODE:
case OPTYPE_ISBOUND:
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()");
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;
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:
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:
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);
refch.prev_state();
break;
case OPTYPE_LOG2STR:
+ case OPTYPE_ANY2UNISTR:
u.expr.logargs->chk_recursions(refch);
break;
default:
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; // not reached
+ //FATAL_ERROR("Value::chk_expr_self_ref_templ()");
+ break;
// default:
// FATAL_ERROR("todo ttype %d", t->get_templatetype());
// break; // and hope for the best
}
}
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);
}
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
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
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
// 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:
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:
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();
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: {
{
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();
FATAL_ERROR("Value::generate_code_init()");
}
break;
+ case V_NOTUSED:
+ // unbound value, don't generate anything
+ break;
default:
FATAL_ERROR("Value::generate_code_init()");
}
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) {
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:
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:
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
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;
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()");
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;
generate_code_expr_execute_refd(expr);
break;
case OPTYPE_LOG2STR:
+ case OPTYPE_ANY2UNISTR:
u.expr.logargs->generate_code_expr(expr);
break;
case OPTYPE_TTCN2STRING: {
if (expr2.postamble)
expr->postamble = mputstr(expr->postamble, expr2.postamble);
} else
- expr->expr = mputprintf(expr->expr, "%s(%s)",
- gov_last->get_coding(true).c_str(), expr2.expr);
+ 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_decode(expression_struct *expr)
{
expression_struct expr1, expr2;
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)
{
return str;
}
- /** This type contains the JSON encoding type of an omitted optional field */
- enum omitted_json_value_t {
- NOT_OMITTED, // the field is not omitted
- OMITTED_ABSENT, // the omitted field is not present in the JSON object
- OMITTED_NULL // the omitted field is set to 'null' in the JSON object
- };
-
- /** JSON code for omitted optional fields of can be generated in 2 ways:
- * - the field is not present in the JSON object or
- * - the field is present and its value is 'null'.
- * Because of this all record/set values containing omitted fields have 2^N
- * possible JSON encodings, where N is the number of omitted fields.
- *
- * This function helps go through all the possible encodings, by generating
- * the next combination from a previous one.
- *
- * The algorithm is basically adding 1 to a binary number (where OMITTED_ABSENT
- * is zero, OMITTED_NULL is one, all NOT_OMITTEDs are ignored and the first bit
- * is the least significant bit).
- *
- * Usage: generate the first combination, where all omitted fields are absent
- * (=all zeros), and keep calling this function until the last combination
- * (where all omitted fields are 'null', = all ones) is reached.
- *
- * @return true, if the next combination was successfully generated, or
- * false, when called with the last combination */
- static bool next_omitted_json_combo(int* omitted_fields, size_t len)
- {
- for (size_t i = 0; i < len; ++i) {
- if (omitted_fields[i] == OMITTED_ABSENT) {
- omitted_fields[i] = OMITTED_NULL;
- for (size_t j = 0; j < i; ++j) {
- if (omitted_fields[j] == OMITTED_NULL) {
- omitted_fields[j] = OMITTED_ABSENT;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- void Value::generate_json_value(JSON_Tokenizer& json, bool allow_special_float /* = true */)
+ void Value::generate_json_value(JSON_Tokenizer& json,
+ bool allow_special_float, /* = true */
+ bool union_value_list, /* = false */
+ Ttcn::JsonOmitCombination* omit_combo /* = NULL */)
{
switch (valuetype) {
case V_INT:
json.put_next_token(JSON_TOKEN_ARRAY_START);
if (!u.val_vs->is_indexed()) {
for (size_t i = 0; i < u.val_vs->get_nof_vs(); ++i) {
- u.val_vs->get_v_byIndex(i)->generate_json_value(json);
+ u.val_vs->get_v_byIndex(i)->generate_json_value(json, allow_special_float,
+ union_value_list, omit_combo);
}
}
else {
// look for the entry with index equal to i
for (size_t j = 0; j < u.val_vs->get_nof_ivs(); ++j) {
if (u.val_vs->get_iv_byIndex(j)->get_index()->get_val_Int()->get_val() == (Int)i) {
- u.val_vs->get_iv_byIndex(j)->get_value()->generate_json_value(json);
+ u.val_vs->get_iv_byIndex(j)->get_value()->generate_json_value(json,
+ allow_special_float, union_value_list, omit_combo);
break;
}
}
// omitted fields have 2 possible JSON values (the field is absent, or it's
// present with value 'null'), each combination of omitted values must be
// generated
+ if (omit_combo == NULL) {
+ FATAL_ERROR("Value::generate_json_value - no combo");
+ }
size_t len = get_nof_comps();
- int* omitted_fields = new int[len]; // stores one combination
+ // generate the JSON object from the present combination
+ json.put_next_token(JSON_TOKEN_OBJECT_START);
for (size_t i = 0; i < len; ++i) {
- if (get_se_comp_byIndex(i)->get_value()->valuetype == V_OMIT) {
- // all omitted fields are absent in the first combination
- omitted_fields[i] = OMITTED_ABSENT;
+ Ttcn::JsonOmitCombination::omit_state_t state = omit_combo->get_state(this, i);
+ if (state == Ttcn::JsonOmitCombination::OMITTED_ABSENT) {
+ // the field is absent, don't insert anything
+ continue;
+ }
+ // use the field's alias, if it has one
+ const char* alias = NULL;
+ if (my_governor != NULL) {
+ JsonAST* field_attrib = my_governor->get_comp_byName(
+ get_se_comp_byIndex(i)->get_name())->get_type()->get_json_attributes();
+ if (field_attrib != NULL) {
+ alias = field_attrib->alias;
+ }
+ }
+ json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
+ get_se_comp_byIndex(i)->get_name().get_ttcnname().c_str());
+ if (state == Ttcn::JsonOmitCombination::OMITTED_NULL) {
+ json.put_next_token(JSON_TOKEN_LITERAL_NULL);
}
else {
- omitted_fields[i] = NOT_OMITTED;
+ get_se_comp_byIndex(i)->get_value()->generate_json_value(json,
+ allow_special_float, union_value_list, omit_combo);
}
}
- do {
- // generate the JSON object from the present combination
- json.put_next_token(JSON_TOKEN_OBJECT_START);
- for (size_t i = 0; i < len; ++i) {
- if (omitted_fields[i] == OMITTED_ABSENT) {
- // the field is absent, don't insert anything
- continue;
- }
- // use the field's alias, if it has one
- const char* alias = NULL;
- if (my_governor != NULL) {
- JsonAST* field_attrib = my_governor->get_comp_byName(
- get_se_comp_byIndex(i)->get_name())->get_type()->get_json_attributes();
- if (field_attrib != NULL) {
- alias = field_attrib->alias;
- }
- }
- json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
- get_se_comp_byIndex(i)->get_name().get_ttcnname().c_str());
- if (omitted_fields[i] == OMITTED_NULL) {
- json.put_next_token(JSON_TOKEN_LITERAL_NULL);
- }
- else {
- get_se_comp_byIndex(i)->get_value()->generate_json_value(json);
- }
- }
- json.put_next_token(JSON_TOKEN_OBJECT_END);
- } // generate the next combination, until all combinations have been processed
- while (next_omitted_json_combo(omitted_fields, len));
+ json.put_next_token(JSON_TOKEN_OBJECT_END);
break; }
case V_CHOICE: {
- bool as_value = my_governor != NULL &&
+ bool as_value = !union_value_list && my_governor != NULL &&
my_governor->get_type_refd_last()->get_json_attributes() != NULL &&
my_governor->get_type_refd_last()->get_json_attributes()->as_value;
if (!as_value) {
json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
get_alt_name().get_ttcnname().c_str());
}
- get_alt_value()->generate_json_value(json);
+ get_alt_value()->generate_json_value(json, allow_special_float,
+ union_value_list, omit_combo);
if (!as_value) {
json.put_next_token(JSON_TOKEN_OBJECT_END);
}
case V_REFD: {
Value* v = get_value_refd_last();
if (this != v) {
- v->generate_json_value(json);
+ v->generate_json_value(json, allow_special_float, union_value_list, omit_combo);
return;
}
} // no break
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;
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:
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() &&