Commit dd2d23a3 authored by BenceJanosSzabo's avatar BenceJanosSzabo
Browse files

XER: allowed constants and module parameters in the defaultForEmpty encoding...


XER: allowed constants and module parameters in the defaultForEmpty encoding instruction (artf190392)

Change-Id: I4a3e0a859f96a5184c5364d771df6961ccdd0bb2
Signed-off-by: default avatarBenceJanosSzabo <bence.janos.szabo@ericsson.com>
parent aabfe14e
......@@ -112,6 +112,7 @@ UnicharPattern::UnicharPattern() : mappings_head(NULL)
if (line_end != NULL) {
*line_end = '\0';
}
//TODO:Valgrind reports uninitialized value coming form here to remove_spaces
// each column ends with a ';', use that as the separator for strtok
char* from_str = remove_spaces(strtok(line, ";"));
size_t from_str_len = from_str != NULL ? strlen(from_str) : 0;
......@@ -123,6 +124,7 @@ UnicharPattern::UnicharPattern() : mappings_head(NULL)
if (from_str_len < 4 || from_str_len > 5) {
TTCN_pattern_warning("Invalid format of case folding file (code column). "
"Case-insensitive universal charstring patterns are disabled.\n");
fclose(fp);
clean_up();
return;
}
......@@ -131,6 +133,7 @@ UnicharPattern::UnicharPattern() : mappings_head(NULL)
if (status == NULL || strlen(status) != 1) {
TTCN_pattern_warning("Invalid format of case folding file (status column). "
"Case-insensitive universal charstring patterns are disabled.\n");
fclose(fp);
clean_up();
return;
}
......@@ -143,6 +146,7 @@ UnicharPattern::UnicharPattern() : mappings_head(NULL)
if (to_str_len < 4 || to_str_len > 5) {
TTCN_pattern_warning("Invalid format of case folding file (mapping column). "
"Case-insensitive universal charstring patterns are disabled.\n");
fclose(fp);
clean_up();
return;
}
......@@ -171,10 +175,12 @@ UnicharPattern::UnicharPattern() : mappings_head(NULL)
// one of the tokens contained a non-hex character
TTCN_pattern_warning("Invalid format of case folding file (character code). "
"Case-insensitive universal charstring patterns are disabled.\n");
fclose(fp);
clean_up();
return;
}
}
fclose(fp);
}
void UnicharPattern::clean_up()
......
......@@ -774,7 +774,7 @@ namespace Common {
void chk_xer_any_element();
void chk_xer_attribute();
void chk_xer_dfe();
Value *new_value_for_dfe(Type *last, const char *dfe_str);
Value *new_value_for_dfe(Type *last, const char *dfe_str, Common::Reference* ref = NULL, bool is_ref_dfe = false);
void target_of_text(string& text);
void chk_xer_embed_values(int num_attributes);
void chk_xer_text();
......
......@@ -695,7 +695,7 @@ void Type::chk_xer_any_element()
} // switch
if (xerattrib->attribute_ || xerattrib->base64_ || xerattrib->untagged_
|| xerattrib->defaultForEmpty_ != NULL
|| (xerattrib->defaultForEmpty_ != NULL || xerattrib->defaultForEmptyIsRef_)
|| xerattrib->whitespace_ != XerAttributes::PRESERVE) {
error("A type with ANY-ELEMENT may not have any of the following encoding instructions: "
"ATTRIBUTE, BASE64, DEFAULT-FOR-EMPTY, PI-OR-COMMENT, UNTAGGED or WHITESPACE");
......@@ -818,17 +818,72 @@ static const string dfe_suffix("_dfe");
* @param last pointer to a Type which is the end of the reference chain,
* usually this->get_type_refd_last()
* @param dfe_str string containing the value from defaultForEmpty
* @param ref Reference containing the reference in defaultForEmpty
* @param is_ref_dfe true if reference is used instead of text in defaultForempty
* @return a newly allocated Common::Value
*/
Value *Type::new_value_for_dfe(Type *last, const char *dfe_str)
Value *Type::new_value_for_dfe(Type *last, const char *dfe_str, Common::Reference* ref, bool is_ref_dfe)
{
string defaultstring(dfe_str);
string defaultstring;
if (is_ref_dfe) {
Value* v = new Value(Value::V_REFD, ref->clone());
v->set_my_scope(get_my_scope()->get_scope_mod());
if (!is_compatible_tt_tt(last->typetype, v->get_expr_governor_last()->typetype, last->is_asn1(), v->get_expr_governor_last()->is_asn1())) {
v->get_reference()->error("Incompatible types were given to defaultForEmpty variant: `%s' instead of `%s'.\n",
v->get_expr_governor_last()->get_typename().c_str(), last->get_typename().c_str());
delete v;
return 0;
}
if (!v->is_unfoldable()) {
switch(v->get_value_refd_last()->get_valuetype()) {
case Value::V_CSTR:
defaultstring = v->get_val_str().c_str();
break;
case Value::V_USTR:
case Value::V_ISO2022STR:
defaultstring = v->get_val_ustr().get_stringRepr_for_pattern();
break;
case Value::V_INT:
defaultstring = Int2string(v->get_val_Int()->get_val());
break;
case Value::V_REAL:
defaultstring = Real2string(v->get_val_Real());
break;
case Value::V_BOOL:
if (v->get_val_bool()) {
defaultstring = "true";
} else {
defaultstring = "false";
}
break;
case Value::V_ENUM: {
Value* v2 = v->get_value_refd_last();
defaultstring = v2->get_val_id()->get_ttcnname().c_str();
break; }
//case Value::V_CHOICE: //In the switch below the choice is handled but
//it is not possible to write DFE for unions???
default:
break;
}
dfe_str = defaultstring.c_str();
} else if (v->get_reference()->get_refd_assignment()->get_asstype() == Assignment::A_MODULEPAR) {
return v;
} else {
v->get_reference()->error("Only strings, constants and module parameters are allowed for a defaultForEmpty value.\n");
delete v;
return 0;
}
delete v;
}
if (!is_ref_dfe) {
defaultstring = dfe_str;
}
switch (last->typetype) {
case T_CSTR:
case T_USTR:
case T_UTF8STRING:
return new Value(Common::Value::V_CSTR,
new string(defaultstring));
return new Value(Common::Value::V_CSTR,
new string(defaultstring));
case T_INT:
case T_INT_A:
......@@ -994,8 +1049,7 @@ void Type::chk_xer_dfe()
}
if (is_charenc() == Yes) {
xerattrib->defaultValue_ = new_value_for_dfe(last, xerattrib->defaultForEmpty_);
xerattrib->defaultValue_ = new_value_for_dfe(last, xerattrib->defaultForEmpty_, xerattrib->defaultForEmptyRef_, xerattrib->defaultForEmptyIsRef_);
if (xerattrib->defaultValue_ != 0) {
xerattrib->defaultValue_->set_genname(this->genname, dfe_suffix);
xerattrib->defaultValue_->set_my_scope(this->my_scope);
......@@ -1019,7 +1073,7 @@ void Type::chk_xer_dfe()
cft = cft->get_type_refd_last();
//typetype_t cftt = cft->get_typetype();
xerattrib->defaultValue_ = new_value_for_dfe(cft, xerattrib->defaultForEmpty_);
xerattrib->defaultValue_ = new_value_for_dfe(cft, xerattrib->defaultForEmpty_, xerattrib->defaultForEmptyRef_, xerattrib->defaultForEmptyIsRef_);
if (xerattrib->defaultValue_ != 0) {
xerattrib->defaultValue_->set_genname(last->genname, string("_dfe"));
xerattrib->defaultValue_->set_my_scope(cft->my_scope);
......@@ -1501,6 +1555,7 @@ void Type::chk_xer_untagged()
if ( has_aa(xerattrib)
|| has_ae(xerattrib)
|| xerattrib->attribute_ || 0 != xerattrib->defaultForEmpty_
|| xerattrib->defaultForEmptyIsRef_
|| xerattrib->embedValues_ || xerattrib->useNil_
|| (xerattrib->useOrder_ && is_asn1()) || xerattrib->useType_) {
error("A type with final encoding attribute UNTAGGED shall not have"
......@@ -1674,6 +1729,7 @@ void Type::chk_xer_use_nil()
if (has_ae(cft->xerattrib)
||has_aa(cft->xerattrib)
||cft->xerattrib->defaultForEmpty_ != 0
||cft->xerattrib->defaultForEmptyIsRef_
||cft->xerattrib->untagged_
||cft->xerattrib->useNil_
||cft->xerattrib->useOrder_
......@@ -2195,7 +2251,7 @@ void Type::chk_xer() { // XERSTUFF semantic check
error("The fractionDigits encoding instruction shall be used with XSD.Decimal types.");
} // if DECIMAL
if (xerattrib->defaultForEmpty_ != 0) {
if (xerattrib->defaultForEmpty_ != 0 || xerattrib->defaultForEmptyIsRef_) {
chk_xer_dfe();
} // if defaultForEmpty
......
......@@ -552,8 +552,10 @@ void Type::generate_code_xerdescriptor(output_struct* target)
const_def cdef;
Code::init_cdef(&cdef);
t->generate_code_object(&cdef, xerattrib->defaultValue_);
cdef.init = xerattrib->defaultValue_->generate_code_init
(cdef.init, xerattrib->defaultValue_->get_lhs_name().c_str());
// Generate the initialization of the dfe values in the post init function
// because the module params are not initialized in the pre init function
target->functions.post_init = xerattrib->defaultValue_->generate_code_init
(target->functions.post_init, xerattrib->defaultValue_->get_lhs_name().c_str());
Code::merge_cdef(target, &cdef);
Code::free_cdef(&cdef);
}
......
......@@ -41,6 +41,8 @@ XerAttributes::XerAttributes()
, block_(false)
, decimal_(false)
, defaultForEmpty_(0)
, defaultForEmptyIsRef_(false)
, defaultForEmptyRef_(0)
, defaultValue_(0)
, element_(false)
, embedValues_(false)
......@@ -83,6 +85,7 @@ XerAttributes::~XerAttributes()
Free(defaultForEmpty_);
delete defaultValue_;
delete defaultForEmptyRef_;
FreeNameChange(name_);
FreeNamespace(namespace_);
......@@ -170,7 +173,10 @@ void XerAttributes::print(const char *type_name) const {
fputs(block_ ? "BLOCK\n" : "", stderr);
fputs(decimal_ ? "DECIMAL\n" : "", stderr);
if (defaultForEmpty_) fprintf(stderr, "DEFAULT-FOR-EMPTY '%s'\n", defaultForEmpty_);
if (defaultForEmpty_)
fprintf(stderr, "DEFAULT-FOR-EMPTY '%s' %s\n",
defaultForEmptyIsRef_ ? defaultForEmptyRef_->get_dispname().c_str() : defaultForEmpty_,
defaultForEmptyIsRef_ ? "(reference) " : "");
if (element_) fputs("ELEMENT\n", stderr);
fputs(embedValues_ ? "EMBED-VALUES\n" : "", stderr);
......@@ -283,6 +289,12 @@ other.print("other");
if (other.defaultForEmpty_ != 0) {
Free(defaultForEmpty_);
defaultForEmpty_ = mcopystr(other.defaultForEmpty_);
defaultForEmptyIsRef_ = other.defaultForEmptyIsRef_;
}
if (other.defaultForEmptyIsRef_ && other.defaultForEmptyRef_ != 0) {
Free(defaultForEmptyRef_);
defaultForEmptyRef_ = other.defaultForEmptyRef_->clone();
}
element_ |= other.element_;
......@@ -396,6 +408,8 @@ bool XerAttributes::empty() const
&& !block_
&& !decimal_
&& defaultForEmpty_ == 0
&& !defaultForEmptyIsRef_
&& !defaultForEmptyRef_
&& !element_
&& !embedValues_
&& !(form_ & LOCALLY_SET)
......
......@@ -26,6 +26,7 @@
#include <limits.h>
#include "../common/memory.h"
#include "datatypes.h"
#include "../compiler2/Setting.hh"
namespace Common {
class Value;
......@@ -155,6 +156,10 @@ public:
bool decimal_;
/// String parsed out from the encoding attribute
char * defaultForEmpty_;
/// True if the defaultForEmpty variant's value is a reference.
bool defaultForEmptyIsRef_;
/// The reference to the defaultForEmpty's value.
Common::Reference* defaultForEmptyRef_;
/// Value object constructed by Type::chk_xer() from defaultForEmpty_
Common::Value *defaultValue_;
/// Global element in XSD
......
......@@ -82,6 +82,11 @@ static void yyprint(FILE *file, int type, const YYSTYPE& value);
} decodetoken;
NamespaceSpecification nsspec;
NamespaceRestriction nsrestr;
struct {
char* str;
Ttcn::Reference* reference;
bool ref;
} dfestruct;
}
%token <intval> XNumber
......@@ -336,7 +341,9 @@ static void yyprint(FILE *file, int type, const YYSTYPE& value);
anyAttributes anyElement optNamespaceRestriction urilist
%type <str> defaultForEmpty name newnameOrKeyword keyword optPrefix quotedURIorAbsent
%type <str> name newnameOrKeyword keyword optPrefix quotedURIorAbsent
%type <dfestruct> defaultForEmpty
%type <nsspec> namespace namespacespecification controlNamespace text
......@@ -404,6 +411,8 @@ namespacespecification
text
controlNamespace
%start XAttribSpec
%%
......@@ -1326,7 +1335,12 @@ XERattribute:
{
mymod->set_controlns($1.uri, $1.prefix);
}
| defaultForEmpty { xerstruct->defaultForEmpty_ = $1; }
| defaultForEmpty
{
xerstruct->defaultForEmpty_ = $1.str;
xerstruct->defaultForEmptyIsRef_ = $1.ref;
xerstruct->defaultForEmptyRef_ = $1.reference;
}
| XKWelement { xerstruct->element_ = true; }
| XKWelementFormQualified { xerstruct->form_ |= XerAttributes::ELEMENT_DEFAULT_QUALIFIED; }
| XKWembedValues { xerstruct->embedValues_ = true; }
......@@ -1487,7 +1501,19 @@ text:
defaultForEmpty:
XKWdefaultForEmpty XKWas Xstring
{ $$ = $3; }
{ $$.str = $3; $$.ref = false; $$.reference = NULL; }
| XKWdefaultForEmpty XKWas XIdentifier
{ $$.reference = new Ttcn::Reference($3);
$$.reference->set_location(infile, @$);
$$.ref = true;
$$.str = NULL;
}
| XKWdefaultForEmpty XKWas XIdentifier '.' XIdentifier
{ $$.reference = new Ttcn::Reference($3, $5);
$$.reference->set_location(infile, @$);
$$.ref = true;
$$.str = NULL;
}
;
fractionDigits:
......
/******************************************************************************
* 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:
* Szabo, Bence Janos
*
******************************************************************************/
module dfe_ref_SE { //^In TTCN-3 module `dfe_ref_SE'://
const octetstring c_oct := 'AA'O;
type record DFEConst { //^In type definition//
charstring cs, //^In record field \`cs\'\:// //^error: DEFAULT\-FOR\-EMPTY not supported for character\-encodable type DFEConst_cs//
universal charstring us, //^In record field \`us\'\:// //^error: DEFAULT\-FOR\-EMPTY not supported for character\-encodable type DFEConst_us//
integer i, //^In record field \`i\'\:// //^error: DEFAULT\-FOR\-EMPTY not supported for character\-encodable type DFEConst_i//
float f, //^In record field \`f\'\:// //^error: DEFAULT\-FOR\-EMPTY not supported for character\-encodable type DFEConst_f//
boolean b //^In record field \`b\'\:// //^error: DEFAULT\-FOR\-EMPTY not supported for character\-encodable type DFEConst_b//
}
with {
variant "element";
variant (cs) "defaultForEmpty as c_oct"; //^error: Incompatible types were given to defaultForEmpty variant\: \`octetstring\' instead of \`charstring\'\.//
variant (us) "defaultForEmpty as c_oct"; //^error: Incompatible types were given to defaultForEmpty variant\: \`octetstring\' instead of \`universal charstring\'\.//
variant (i) "defaultForEmpty as c_oct"; //^error: Incompatible types were given to defaultForEmpty variant\: \`octetstring\' instead of \`integer\'\.//
variant (f) "defaultForEmpty as c_oct"; //^error: Incompatible types were given to defaultForEmpty variant\: \`octetstring\' instead of \`float\'\.//
variant (b) "defaultForEmpty as c_oct"; //^error: Incompatible types were given to defaultForEmpty variant\: \`octetstring\' instead of \`boolean\'\.//
}
}
with {
encode "XML"
}
......@@ -11,7 +11,7 @@
* Szabo, Bence Janos
*
******************************************************************************/
module emb_first_opt_SE {
module emb_first_opt_OK {
type record e1 {
record of universal charstring field_1 optional /* no default in TTCN-3, optional is now allowed */
......
......@@ -9,9 +9,10 @@
* Balasko, Jeno
* Baranyi, Botond
* Raduly, Csaba
* Szabo, Bence Janos
*
******************************************************************************/
module untagged_noncharenc_SE {
module untagged_noncharenc_OK {
type record R2 {
hexstring os
......
......@@ -8,6 +8,7 @@
* Contributors:
* Balasko, Jeno
* Raduly, Csaba
* Szabo, Bence Janos
*
******************************************************************************/
module DefaultForEmpty {
......@@ -79,9 +80,85 @@ testcase decode_dfe() runs on DFE
CHECK_DECODE(exer_dec_dfe, str_dfe_e_dec, DFEProduct, dfeval);
}
//===========================================================================//
const charstring cs := "cs";
const universal charstring us := "us";
const integer i := 1;
const float f := 1.0;
const boolean b := true;
DECLARE_EXER_ENCODERS(DFEConst, dfe_const);
type record DFEConst {
charstring cs,
universal charstring us,
integer i,
float f,
boolean b
}
with {
variant "element";
variant (cs) "defaultForEmpty as cs";
variant (us) "defaultForEmpty as us";
variant (i) "defaultForEmpty as i";
variant (f) "defaultForEmpty as f";
variant (b) "defaultForEmpty as b";
}
const universal charstring str_dfe_const_e := "<DFEConst>\n\t<cs/>\n\t<us/>\n\t<i/>\n\t<f/>\n\t<b/>\n</DFEConst>\n\n";
const DFEConst dfeval_exp := { cs, us, i, f, b };
testcase decode_dfe_const() runs on DFE
{
CHECK_DECODE(exer_dec_dfe_const, str_dfe_const_e, DFEConst, dfeval_exp);
}
//===========================================================================//
modulepar charstring mp_cs; // "mp_cs"
modulepar universal charstring mp_us; // "mp_us"
modulepar integer mp_i; // 3
modulepar float mp_f; // 3.0
modulepar boolean mp_b; // true
DECLARE_EXER_ENCODERS(DFEMP, dfe_mp);
type record DFEMP {
charstring cs,
universal charstring us,
integer i,
float f,
boolean b
}
with {
variant "element";
variant (cs) "defaultForEmpty as mp_cs";
variant (us) "defaultForEmpty as mp_us";
variant (i) "defaultForEmpty as mp_i";
variant (f) "defaultForEmpty as mp_f";
variant (b) "defaultForEmpty as mp_b";
}
const universal charstring str_dfe_mp_e := "<DFEMP>\n\t<cs/>\n\t<us/>\n\t<i/>\n\t<f/>\n\t<b/>\n</DFEMP>\n\n";
const DFEMP dfeval_mp_exp := { "mp_cs", "mp_us", 3, 3.0, true };
testcase decode_dfe_mp() runs on DFE
{
CHECK_DECODE(exer_dec_dfe_mp, str_dfe_mp_e, DFEMP, dfeval_mp_exp);
}
control {
execute(encode_dfe());
execute(decode_dfe());
execute(decode_dfe_const());
execute(decode_dfe_mp());
}
}
......
......@@ -49,3 +49,10 @@ LogEventTypes := Detailed
#EndTestcase = "echo"
# This is to annoy me because the runtime leaks the name of external commands
# in single mode
[MODULE_PARAMETERS]
mp_cs := "mp_cs";
mp_us := "mp_us";
mp_i := 3;
mp_f := 3.0;
mp_b := true;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment