diff --git a/compiler2/Type_chk.cc b/compiler2/Type_chk.cc index 1e2745345f44ca5e22cb1e45b2c976dfda37d21f..1b6abd4e81e4a0b13c5ef64e44f512242b679770 100644 --- a/compiler2/Type_chk.cc +++ b/compiler2/Type_chk.cc @@ -2188,7 +2188,14 @@ void Type::chk_xer() { // XERSTUFF semantic check if (last->typetype != T_REAL) { error("DECIMAL shall only be assigned to a real type"); } - } // if DECIMAL + if (xerattrib->has_fractionDigits_) { + if (xerattrib->fractionDigits_ < 0) { + error("The value of fractionDigits must be equal or greater than zero"); + } + } + } else if (xerattrib->has_fractionDigits_) { + error("The fractionDigits encoding instruction shall be used with XSD.Decimal types."); + } // if DECIMAL if (xerattrib->defaultForEmpty_ != 0) { chk_xer_dfe(); diff --git a/compiler2/Type_codegen.cc b/compiler2/Type_codegen.cc index b57e19abeeaf9c925d092988e90493b8ba196e59..a0716185a67b99091ffb5be21c6a1c495295a163 100644 --- a/compiler2/Type_codegen.cc +++ b/compiler2/Type_codegen.cc @@ -505,7 +505,7 @@ void Type::generate_code_xerdescriptor(output_struct* target) int atrib=0, any_atr=0, any_elem=0, base64=0, decimal=0, embed=0, list=0, text=0, untagged=0, use_nil=0, use_number=0, use_order=0, use_qname=0, use_type_attr=0, ws=0, has_1untag=0, form_qualified=0, any_from=0, - any_except=0, nof_ns_uris=0, blocked=0; + any_except=0, nof_ns_uris=0, blocked=0, fractionDigits=-1; const char* dfe_str = 0; char** ns_uris = 0; char* oftype_descr_name = 0; @@ -527,6 +527,7 @@ void Type::generate_code_xerdescriptor(output_struct* target) embed = xerattrib->embedValues_; form_qualified = (xerattrib->form_ & XerAttributes::QUALIFIED) || (xerattrib->element_); // a global element is always qualified + fractionDigits = xerattrib->has_fractionDigits_ ? xerattrib->fractionDigits_ : -1; list = xerattrib->list_; untagged= xerattrib->untagged_; ws = xerattrib->whitespace_; @@ -619,12 +620,12 @@ void Type::generate_code_xerdescriptor(output_struct* target) } target->source.global_vars = mputstrn(target->source.global_vars, "};\n", 3); } - + // Generate the XER descriptor itself target->source.global_vars = mputprintf(target->source.global_vars, "const XERdescriptor_t %s_xer_ = { {\"%s>\\n\", \"%s>\\n\"}," " {%lu, %lu}, %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s, WHITESPACE_%s, %c%s, " - "&%s, %ld, %u, %s, %s };\n", + "&%s, %ld, %u, %s, %s, %i };\n", gennameown_str, bxer_name.c_str(), last_s.c_str(), // names (unsigned long)bxer_len, (unsigned long)last_len, // lengths @@ -654,7 +655,8 @@ void Type::generate_code_xerdescriptor(output_struct* target) ns_index, nof_ns_uris, (ns_uris_var ? ns_uris_var : "NULL"), - (oftype_descr_name ? oftype_descr_name : "NULL") + (oftype_descr_name ? oftype_descr_name : "NULL"), + fractionDigits ); Free(ns_uris_var); diff --git a/compiler2/XerAttributes.cc b/compiler2/XerAttributes.cc index 4ddde8e3122070c2662f323f3a400bf3dae6989c..ce62386428d390ac8d5cd26aaade935800f26da4 100644 --- a/compiler2/XerAttributes.cc +++ b/compiler2/XerAttributes.cc @@ -10,6 +10,7 @@ * Baranyi, Botond * Raduly, Csaba * Szabados, Kristof + * Szabo, Bence Janos * ******************************************************************************/ /* @@ -44,6 +45,8 @@ XerAttributes::XerAttributes() , element_(false) , embedValues_(false) , form_(UNSET) +, has_fractionDigits_(false) +, fractionDigits_(0) , hex_(false) , list_(false) , name_(nochange) @@ -171,6 +174,7 @@ void XerAttributes::print(const char *type_name) const { if (element_) fputs("ELEMENT\n", stderr); fputs(embedValues_ ? "EMBED-VALUES\n" : "", stderr); fputs((form_ & QUALIFIED) ? "FORM AS QUALIFIED\n" : "", stderr); + if (has_fractionDigits_) fprintf(stderr, "FRACTIONDIGITS '%i'\n", fractionDigits_); fputs(hex_ ? "hexBinary" : "", stderr); fputs(list_ ? "LIST\n" : "", stderr); @@ -283,6 +287,8 @@ other.print("other"); element_ |= other.element_; embedValues_ |= other.embedValues_; form_ = other.form_; + has_fractionDigits_ = other.has_fractionDigits_; + fractionDigits_ = other.fractionDigits_; hex_ |= other.hex_; list_ |= other.list_; if (other.name_.kw_ != NamespaceSpecification::NO_MANGLING) { @@ -386,6 +392,7 @@ bool XerAttributes::empty() const && !element_ && !embedValues_ && !(form_ & LOCALLY_SET) + && !has_fractionDigits_ && !hex_ && !list_ && name_.kw_ == NamespaceSpecification::NO_MANGLING diff --git a/compiler2/XerAttributes.hh b/compiler2/XerAttributes.hh index c3e550de75dc56d9166d0ee799d3cd015c871557..c6b44ae71e1139ca336435581b0681b818794b67 100644 --- a/compiler2/XerAttributes.hh +++ b/compiler2/XerAttributes.hh @@ -9,6 +9,7 @@ * Balasko, Jeno * Baranyi, Botond * Raduly, Csaba + * Szabo, Bence Janos * ******************************************************************************/ /* @@ -161,6 +162,10 @@ public: bool embedValues_; /// Qualified or unqualified form for local elements and attributes unsigned short form_; + // True if there was fractionDigits variant + bool has_fractionDigits_; + // fractionDigits on float number + int fractionDigits_; /// XSD:hexBinary bool hex_; /// space-separated values for record-of/set-of diff --git a/compiler2/ttcn3/rawAST.l b/compiler2/ttcn3/rawAST.l index 00a714172433670ee2db19055a66d3fd3849f8de..1fdb1f774cfcbe4fbb13cb2b3e1653d0863489f4 100644 --- a/compiler2/ttcn3/rawAST.l +++ b/compiler2/ttcn3/rawAST.l @@ -357,6 +357,7 @@ element RETURN(XKWelement); elementFormQualified RETURN(XKWelementFormQualified); embedValues RETURN(XKWembedValues); form RETURN(XKWform); +fractionDigits RETURN(XKWfractionDigits); list RETURN(XKWlist); name RETURN(XKWname); namespace RETURN(XKWnamespace); diff --git a/compiler2/ttcn3/rawAST.y b/compiler2/ttcn3/rawAST.y index 18142e314c9f0d5d993af38c64ec8ff2b5dc3c75..945b4bc933a52e0b12c65752a1beb1a2398fd5b2 100644 --- a/compiler2/ttcn3/rawAST.y +++ b/compiler2/ttcn3/rawAST.y @@ -194,6 +194,7 @@ static void yyprint(FILE *file, int type, const YYSTYPE& value); %token XKWelementFormQualified "elementFormQualified" %token XKWembedValues "embedValues" %token XKWform "form" +%token XKWfractionDigits "fractionDigits" %token XKWlist "list" %token XKWname "name" %token XKWnamespace "namespace" @@ -333,7 +334,7 @@ static void yyprint(FILE *file, int type, const YYSTYPE& value); %type <nsspec> namespace namespacespecification controlNamespace text -%type <intval> whiteSpace +%type <intval> whiteSpace fractionDigits /* destructors */ %destructor { Free($$); } @@ -1311,6 +1312,7 @@ XERattribute: | XKWelementFormQualified { xerstruct->form_ |= XerAttributes::ELEMENT_DEFAULT_QUALIFIED; } | XKWembedValues { xerstruct->embedValues_ = true; } | form { xerstruct->form_ |= $1; } + | fractionDigits { xerstruct->fractionDigits_ = $1; xerstruct->has_fractionDigits_ = true; } | XKWlist { xerstruct->list_ = true; } | name { /* overwrites any previous name */ @@ -1469,6 +1471,10 @@ defaultForEmpty: { $$ = $3; } ; +fractionDigits: + XKWfractionDigits XNumber + { $$ = $2; } + whiteSpace: diff --git a/core/Float.cc b/core/Float.cc index e01479804506c5fc2cb6d5bce07fc881b07afcff..d1820b2f6055d8fbf206696676314995cef39c8a 100644 --- a/core/Float.cc +++ b/core/Float.cc @@ -872,6 +872,14 @@ int FLOAT::XER_encode(const XERdescriptor_t& p_td, n = snprintf(buf, sizeof(buf), "%s", XER_NEG_INF_STR); } else { n = snprintf(buf, sizeof(buf), "%f", (double)float_value); + if (p_td.fractionDigits != -1) { + char *p = strchr(buf, '.'); + if (p != NULL) { + int offset = p_td.fractionDigits == 0 ? 0 : p_td.fractionDigits + 1; + p[offset] = 0; + n = strlen(buf); + } + } } p_buf.put_s((size_t)n, (const unsigned char*)buf); } @@ -966,6 +974,18 @@ tagless: const char * value = (const char *)reader.Value(); if (value) { if (is_float(value)) { + if (exer && (p_td.xer_bits & XER_DECIMAL) && p_td.fractionDigits != -1) { + char *p = strchr((char*)value, '.'); + if (p != NULL) { + unsigned int fraction_digits_pos = (int)(p - value) + 1 + p_td.fractionDigits; + if (fraction_digits_pos < strlen(value)) { + TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_FLOAT_TR, + "The float value (%s) contains too many fractionDigits. Expected %i or less.", + value, + p_td.fractionDigits); + } + } + } bound_flag = true; sscanf(value, "%lf", &float_value); } else if (strcmp(XER_NAN_STR, value) == 0 ) { @@ -1008,6 +1028,18 @@ tagless: const char * value = (const char*)reader.Value(); if (value) { if (is_float(value)) { + if (exer && (p_td.xer_bits & XER_DECIMAL) && p_td.fractionDigits != -1) { + char *p = strchr((char*)value, '.'); + if (p != NULL) { + unsigned int fraction_digits_pos = (int)(p - value) + 1 + p_td.fractionDigits; + if (fraction_digits_pos < strlen(value)) { + TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_FLOAT_TR, + "The float value (%s) contains too many fractionDigits. Expected %i or less.", + value, + p_td.fractionDigits); + } + } + } bound_flag = true; sscanf(value, "%lf", &float_value); } else if (strcmp("NaN", value) == 0 ) { diff --git a/core/XER.hh b/core/XER.hh index c2bea32e094f664c2e9e84c1194e3537052d4d5b..d78c2e94cba36830d0fd24f6e683edc883977fc1 100644 --- a/core/XER.hh +++ b/core/XER.hh @@ -279,6 +279,12 @@ struct XERdescriptor_t /** Points to the element type's XER descriptor in case of 'record of' and 'set of' types */ const XERdescriptor_t* oftype_descr; + + /** Fraction digits value + * It is already checked that is must not be a negative number. + * The -1 value is used to determine if fractionDigits encoding instruction is present, + * so if the value is -1, no checks will be made. */ + const int fractionDigits; }; /** Information related to the embedded values in XML encoding @@ -448,7 +454,7 @@ void check_namespace_restrictions(const XERdescriptor_t& p_td, const char* p_xml extern const XERdescriptor_t type_name##_xer_ = { \ { xmlname ">\n", xmlname ">\n" }, \ { 2+sizeof(xmlname)-1, 2+sizeof(xmlname)-1 }, \ - 0UL, WHITESPACE_PRESERVE, NULL, NULL, 0, 0, NULL, NULL } + 0UL, WHITESPACE_PRESERVE, NULL, NULL, 0, 0, NULL, NULL, -1 } // The compiler should fold the two identical strings into one # define XER_STRUCT_COPY(cpy,original) \ diff --git a/function_test/Semantic_Analyser/xer/fractionDigits_SE.ttcn b/function_test/Semantic_Analyser/xer/fractionDigits_SE.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..9e1a47dc8a71c289ffe62379901a3b69ac48f9ad --- /dev/null +++ b/function_test/Semantic_Analyser/xer/fractionDigits_SE.ttcn @@ -0,0 +1,40 @@ +/****************************************************************************** + * 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 fractionDigits_SE { //^In TTCN-3 module `fractionDigits_SE':// + +type float MyFloat //^In type definition// //^error: The fractionDigits encoding instruction shall be used with XSD\.Decimal types\.// +with { + variant "fractionDigits 2"; +}; + + +type float MyFloat2 +with { + variant "fractionDigits 2"; + variant "XSD:decimal" +}; + +type float MyFloat3; + +type record MyRec { //^In type definition// + MyFloat3 myfloat //^In record field// //^error: The fractionDigits encoding instruction shall be used with XSD\.Decimal types// +} +with { + variant (myfloat) "fractionDigits 2"; + variant (myfloat) "attribute"; +}; + + +} +with { + encode "XML"; +} diff --git a/function_test/XER_EncDec/XER_EncDec_TD.script b/function_test/XER_EncDec/XER_EncDec_TD.script index 7a0c238df3952b0a390029df406e58e278e3f0b9..4e5a7e3c6383da808bc337b814cf78dbd8e250e5 100644 --- a/function_test/XER_EncDec/XER_EncDec_TD.script +++ b/function_test/XER_EncDec/XER_EncDec_TD.script @@ -71,6 +71,189 @@ A 2014-04-29 EBOTBAR New document .*---------------------------------------------------------------------* :h4. Encoding record template with explicitly unspecified field .*---------------------------------------------------------------------* + +.*---------------------------------------------------------------------* +:h4. Too many fraction digits when fractionDigits is 2 +.*---------------------------------------------------------------------* +:xmp tab=0. + +<TC - Too many fraction digits when fractionDigits is 2> + +<STATIC> + +type component Test_CT{}; + +<TTCN_TC:PURE_EXEC> + +type float MyFloat +with { + encode "XML"; + variant "fractionDigits 2"; + variant "XSD:decimal"; +}; + +external function ef_xer_dec(in octetstring par) return MyFloat + with { extension "prototype(convert) decode (XER:XER_EXTENDED) errorbehavior(ALL:ERROR)" } + +testcase tc_dec_fractiondigits() runs on Test_CT { + var universal charstring xml := "<MyFloat>1234567890.111</MyFloat>\n"; + ef_xer_dec(unichar2oct(xml)); + setverdict(pass); +} + +control { + execute(tc_dec_fractiondigits()); +} + +<RESULT> + +Dynamic test case error: While XER-decoding type '@Temp.MyFloat': The float value (1234567890.111) contains too many fractionDigits. Expected 2 or less + +<END_TC> + +:exmp. + +.*---------------------------------------------------------------------* +:h4. Too many fraction digits when fractionDigits is 0 +.*---------------------------------------------------------------------* +:xmp tab=0. + +<TC - Too many fraction digits when fractionDigits is 0> + +<STATIC> + +type component Test_CT{}; + +<TTCN_TC:PURE_EXEC> + +type float MyFloat +with { + encode "XML"; + variant "fractionDigits 0"; + variant "XSD:decimal"; +}; + +external function ef_xer_dec(in octetstring par) return MyFloat + with { extension "prototype(convert) decode (XER:XER_EXTENDED) errorbehavior(ALL:ERROR)" } + +testcase tc_dec_fractiondigits() runs on Test_CT { + var universal charstring xml := "<MyFloat>1234567890.1</MyFloat>\n"; + ef_xer_dec(unichar2oct(xml)); + setverdict(pass); +} + +control { + execute(tc_dec_fractiondigits()); +} + +<RESULT> + +Dynamic test case error: While XER-decoding type '@Temp.MyFloat': The float value (1234567890.1) contains too many fractionDigits. Expected 0 or less + +<END_TC> + +:exmp. + + +.*---------------------------------------------------------------------* +:h4. Too many fraction digits when fractionDigits is 2 in attribute +.*---------------------------------------------------------------------* +:xmp tab=0. + +<TC - Too many fraction digits when fractionDigits is 2 in attribute> + +<STATIC> + +type component Test_CT{}; + +<TTCN_TC:PURE_EXEC> + +type float MyFloat +with { + encode "XML"; + variant "XSD:decimal"; +}; + +type record MyRec { + MyFloat myfloat +} +with { + encode "XML"; + variant (myfloat) "fractionDigits 2"; + variant (myfloat) "attribute"; +}; + +external function ef_xer_dec(in octetstring par) return MyRec + with { extension "prototype(convert) decode (XER:XER_EXTENDED) errorbehavior(ALL:ERROR)" } + +testcase tc_dec_fractiondigits_attr() runs on Test_CT { + var universal charstring xml := "<MyRec myfloat='1234567890.111'></MyRec>\n"; + ef_xer_dec(unichar2oct(xml)); + setverdict(pass); +} + +control { + execute(tc_dec_fractiondigits_attr()); +} + +<RESULT> + +Dynamic test case error: While XER-decoding type '@Temp.MyRec': Component 'myfloat': The float value (1234567890.111) contains too many fractionDigits. Expected 2 or less. + +<END_TC> + +:exmp. + +.*---------------------------------------------------------------------* +:h4. Too many fraction digits when fractionDigits is 0 in attribute +.*---------------------------------------------------------------------* +:xmp tab=0. + +<TC - Too many fraction digits when fractionDigits is 0 in attribute> + +<STATIC> + +type component Test_CT{}; + +<TTCN_TC:PURE_EXEC> + +type float MyFloat +with { + encode "XML"; + variant "XSD:decimal"; +}; + +type record MyRec { + MyFloat myfloat +} +with { + encode "XML"; + variant (myfloat) "fractionDigits 0"; + variant (myfloat) "attribute"; +}; + +external function ef_xer_dec(in octetstring par) return MyRec + with { extension "prototype(convert) decode (XER:XER_EXTENDED) errorbehavior(ALL:ERROR)" } + +testcase tc_dec_fractiondigits_attr() runs on Test_CT { + var universal charstring xml := "<MyRec myfloat='1234567890.1'></MyRec>\n"; + ef_xer_dec(unichar2oct(xml)); + setverdict(pass); +} + +control { + execute(tc_dec_fractiondigits_attr()); +} + +<RESULT> + +Dynamic test case error: While XER-decoding type '@Temp.MyRec': Component 'myfloat': The float value (1234567890.1) contains too many fractionDigits. Expected 0 or less. + +<END_TC> + +:exmp. + + :xmp tab=0. <TC - Encoding record with any element from unqualified namespace> diff --git a/regression_test/XML/TTCNandXML/FractionDigitsTest.ttcnpp b/regression_test/XML/TTCNandXML/FractionDigitsTest.ttcnpp new file mode 100644 index 0000000000000000000000000000000000000000..725daa9491d19384ba55c5bcde9c97e2b32f0e13 --- /dev/null +++ b/regression_test/XML/TTCNandXML/FractionDigitsTest.ttcnpp @@ -0,0 +1,264 @@ +/****************************************************************************** + * 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 FractionDigitsTest { + +modulepar boolean FractionDigitsTest_verbose := false; +#define verbose FractionDigitsTest_verbose + +#include "../macros.ttcnin" + +type float MyFloatDecimal2 +with { + variant "XSD:decimal" + variant "fractionDigits 2" +} + +type float MyFloatDecimal0 +with { + variant "XSD:decimal" + variant "fractionDigits 0" +} + +type record MyRec { + MyFloatDecimal2 myfloat +} +with { + variant (myfloat) "fractionDigits 2"; + variant (myfloat) "attribute"; +}; + + +type component FDT {} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +DECLARE_XER_ENCODERS(MyFloatDecimal2, fdec2) +DECLARE_EXER_ENCODERS(MyFloatDecimal2, fdec2) + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +const MyFloatDecimal2 myfdec2 := 12345.6789; +const universal charstring c_myfxml2_bxer := "<MyFloatDecimal2>12345.678900</MyFloatDecimal2>\n"; +const universal charstring c_myfxml2_exer := "<MyFloatDecimal2>12345.67</MyFloatDecimal2>\n"; + +const MyFloatDecimal2 myfdec2_2 := 12345.1; +const universal charstring c_myfxml2_2_bxer := "<MyFloatDecimal2>12345.100000</MyFloatDecimal2>\n"; +const universal charstring c_myfxml2_2_exer := "<MyFloatDecimal2>12345.10</MyFloatDecimal2>\n"; + +const MyFloatDecimal2 myfdec2_3 := 12345E-4; +const universal charstring c_myfxml2_3_bxer := "<MyFloatDecimal2>1.234500</MyFloatDecimal2>\n"; +const universal charstring c_myfxml2_3_exer := "<MyFloatDecimal2>1.23</MyFloatDecimal2>\n"; + +const MyFloatDecimal2 myfdec2_4 := 12345E-1; +const universal charstring c_myfxml2_4_bxer := "<MyFloatDecimal2>1234.500000</MyFloatDecimal2>\n"; +const universal charstring c_myfxml2_4_exer := "<MyFloatDecimal2>1234.50</MyFloatDecimal2>\n"; + +const MyFloatDecimal2 myfdec2_5 := 12345E+0; +const universal charstring c_myfxml2_5_bxer := "<MyFloatDecimal2>12345.000000</MyFloatDecimal2>\n"; +const universal charstring c_myfxml2_5_exer := "<MyFloatDecimal2>12345.00</MyFloatDecimal2>\n"; + +const MyFloatDecimal2 myfdec2_6 := 12345E-0; +const universal charstring c_myfxml2_6_bxer := "<MyFloatDecimal2>12345.000000</MyFloatDecimal2>\n"; +const universal charstring c_myfxml2_6_exer := "<MyFloatDecimal2>12345.00</MyFloatDecimal2>\n"; + +const MyFloatDecimal2 myfdec2_7 := 12345E+1; +const universal charstring c_myfxml2_7_bxer := "<MyFloatDecimal2>123450.000000</MyFloatDecimal2>\n"; +const universal charstring c_myfxml2_7_exer := "<MyFloatDecimal2>123450.00</MyFloatDecimal2>\n"; + +const MyFloatDecimal2 myfdec2_8 := 1234567890.0987654321; +const universal charstring c_myfxml2_8_bxer := "<MyFloatDecimal2>1234567890.098770</MyFloatDecimal2>\n"; +const universal charstring c_myfxml2_8_exer := "<MyFloatDecimal2>1234567890.09</MyFloatDecimal2>\n"; + +testcase float_decimal_enc2() runs on FDT +{ + CHECK_METHOD(bxer_enc_fdec2, myfdec2, c_myfxml2_bxer); + CHECK_METHOD(exer_enc_fdec2, myfdec2, c_myfxml2_exer); + + CHECK_METHOD(bxer_enc_fdec2, myfdec2_2, c_myfxml2_2_bxer); + CHECK_METHOD(exer_enc_fdec2, myfdec2_2, c_myfxml2_2_exer); + + CHECK_METHOD(bxer_enc_fdec2, myfdec2_3, c_myfxml2_3_bxer); + CHECK_METHOD(exer_enc_fdec2, myfdec2_3, c_myfxml2_3_exer); + + CHECK_METHOD(bxer_enc_fdec2, myfdec2_4, c_myfxml2_4_bxer); + CHECK_METHOD(exer_enc_fdec2, myfdec2_4, c_myfxml2_4_exer); + + CHECK_METHOD(bxer_enc_fdec2, myfdec2_5, c_myfxml2_5_bxer); + CHECK_METHOD(exer_enc_fdec2, myfdec2_5, c_myfxml2_5_exer); + + CHECK_METHOD(bxer_enc_fdec2, myfdec2_6, c_myfxml2_6_bxer); + CHECK_METHOD(exer_enc_fdec2, myfdec2_6, c_myfxml2_6_exer); + + CHECK_METHOD(bxer_enc_fdec2, myfdec2_7, c_myfxml2_7_bxer); + CHECK_METHOD(exer_enc_fdec2, myfdec2_7, c_myfxml2_7_exer); + + CHECK_METHOD(bxer_enc_fdec2, myfdec2_8, c_myfxml2_8_bxer); + CHECK_METHOD(exer_enc_fdec2, myfdec2_8, c_myfxml2_8_exer); +} + +testcase float_decimal_dec2() runs on FDT +{ + CHECK_DECODE(bxer_dec_fdec2, c_myfxml2_bxer, MyFloatDecimal2, myfdec2); + CHECK_DECODE(exer_dec_fdec2, c_myfxml2_exer, MyFloatDecimal2, 12345.670000); + + CHECK_DECODE(bxer_dec_fdec2, c_myfxml2_2_bxer, MyFloatDecimal2, myfdec2_2); + CHECK_DECODE(exer_dec_fdec2, c_myfxml2_2_exer, MyFloatDecimal2, 12345.100000); + + CHECK_DECODE(bxer_dec_fdec2, c_myfxml2_3_bxer, MyFloatDecimal2, myfdec2_3); + CHECK_DECODE(exer_dec_fdec2, c_myfxml2_3_exer, MyFloatDecimal2, 1.230000); + + CHECK_DECODE(bxer_dec_fdec2, c_myfxml2_4_bxer, MyFloatDecimal2, myfdec2_4); + CHECK_DECODE(exer_dec_fdec2, c_myfxml2_4_exer, MyFloatDecimal2, 1234.500000); + + CHECK_DECODE(bxer_dec_fdec2, c_myfxml2_5_bxer, MyFloatDecimal2, myfdec2_5); + CHECK_DECODE(exer_dec_fdec2, c_myfxml2_5_exer, MyFloatDecimal2, 12345.000000); + + CHECK_DECODE(bxer_dec_fdec2, c_myfxml2_6_bxer, MyFloatDecimal2, myfdec2_6); + CHECK_DECODE(exer_dec_fdec2, c_myfxml2_6_exer, MyFloatDecimal2, 12345.000000); + + CHECK_DECODE(bxer_dec_fdec2, c_myfxml2_7_bxer, MyFloatDecimal2, myfdec2_7); + CHECK_DECODE(exer_dec_fdec2, c_myfxml2_7_exer, MyFloatDecimal2, 123450.000000); + + CHECK_DECODE(bxer_dec_fdec2, c_myfxml2_8_bxer, MyFloatDecimal2, myfdec2_8); + CHECK_DECODE(exer_dec_fdec2, c_myfxml2_8_exer, MyFloatDecimal2, 1234567890.090000); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +DECLARE_XER_ENCODERS(MyFloatDecimal0, fdec0) +DECLARE_EXER_ENCODERS(MyFloatDecimal0, fdec0) + +const MyFloatDecimal0 myfdec0 := 12345.6789; +const universal charstring c_myfxml0_bxer := "<MyFloatDecimal0>12345.678900</MyFloatDecimal0>\n"; +const universal charstring c_myfxml0_exer := "<MyFloatDecimal0>12345</MyFloatDecimal0>\n"; + +const MyFloatDecimal0 myfdec0_2 := 12345.1; +const universal charstring c_myfxml0_2_bxer := "<MyFloatDecimal0>12345.100000</MyFloatDecimal0>\n"; +const universal charstring c_myfxml0_2_exer := "<MyFloatDecimal0>12345</MyFloatDecimal0>\n"; + +const MyFloatDecimal0 myfdec0_3 := 12345E-4; +const universal charstring c_myfxml0_3_bxer := "<MyFloatDecimal0>1.234500</MyFloatDecimal0>\n"; +const universal charstring c_myfxml0_3_exer := "<MyFloatDecimal0>1</MyFloatDecimal0>\n"; + +const MyFloatDecimal0 myfdec0_4 := 12345E-1; +const universal charstring c_myfxml0_4_bxer := "<MyFloatDecimal0>1234.500000</MyFloatDecimal0>\n"; +const universal charstring c_myfxml0_4_exer := "<MyFloatDecimal0>1234</MyFloatDecimal0>\n"; + +const MyFloatDecimal0 myfdec0_5 := 12345E+0; +const universal charstring c_myfxml0_5_bxer := "<MyFloatDecimal0>12345.000000</MyFloatDecimal0>\n"; +const universal charstring c_myfxml0_5_exer := "<MyFloatDecimal0>12345</MyFloatDecimal0>\n"; + +const MyFloatDecimal0 myfdec0_6 := 12345E-0; +const universal charstring c_myfxml0_6_bxer := "<MyFloatDecimal0>12345.000000</MyFloatDecimal0>\n"; +const universal charstring c_myfxml0_6_exer := "<MyFloatDecimal0>12345</MyFloatDecimal0>\n"; + +const MyFloatDecimal0 myfdec0_7 := 12345E+1; +const universal charstring c_myfxml0_7_bxer := "<MyFloatDecimal0>123450.000000</MyFloatDecimal0>\n"; +const universal charstring c_myfxml0_7_exer := "<MyFloatDecimal0>123450</MyFloatDecimal0>\n"; + +const MyFloatDecimal0 myfdec0_8 := 1234567890.0987654321; +const universal charstring c_myfxml0_8_bxer := "<MyFloatDecimal0>1234567890.098770</MyFloatDecimal0>\n"; +const universal charstring c_myfxml0_8_exer := "<MyFloatDecimal0>1234567890</MyFloatDecimal0>\n"; + +testcase float_decimal_enc0() runs on FDT +{ + CHECK_METHOD(bxer_enc_fdec0, myfdec0, c_myfxml0_bxer); + CHECK_METHOD(exer_enc_fdec0, myfdec0, c_myfxml0_exer); + + CHECK_METHOD(bxer_enc_fdec0, myfdec0_2, c_myfxml0_2_bxer); + CHECK_METHOD(exer_enc_fdec0, myfdec0_2, c_myfxml0_2_exer); + + CHECK_METHOD(bxer_enc_fdec0, myfdec0_3, c_myfxml0_3_bxer); + CHECK_METHOD(exer_enc_fdec0, myfdec0_3, c_myfxml0_3_exer); + + CHECK_METHOD(bxer_enc_fdec0, myfdec0_4, c_myfxml0_4_bxer); + CHECK_METHOD(exer_enc_fdec0, myfdec0_4, c_myfxml0_4_exer); + + CHECK_METHOD(bxer_enc_fdec0, myfdec0_5, c_myfxml0_5_bxer); + CHECK_METHOD(exer_enc_fdec0, myfdec0_5, c_myfxml0_5_exer); + + CHECK_METHOD(bxer_enc_fdec0, myfdec0_6, c_myfxml0_6_bxer); + CHECK_METHOD(exer_enc_fdec0, myfdec0_6, c_myfxml0_6_exer); + + CHECK_METHOD(bxer_enc_fdec0, myfdec0_7, c_myfxml0_7_bxer); + CHECK_METHOD(exer_enc_fdec0, myfdec0_7, c_myfxml0_7_exer); + + CHECK_METHOD(bxer_enc_fdec0, myfdec0_8, c_myfxml0_8_bxer); + CHECK_METHOD(exer_enc_fdec0, myfdec0_8, c_myfxml0_8_exer); +} + +testcase float_decimal_dec0() runs on FDT +{ + CHECK_DECODE(bxer_dec_fdec0, c_myfxml0_bxer, MyFloatDecimal0, myfdec0); + CHECK_DECODE(exer_dec_fdec0, c_myfxml0_exer, MyFloatDecimal0, 12345.000000); + + CHECK_DECODE(bxer_dec_fdec0, c_myfxml0_2_bxer, MyFloatDecimal0, myfdec0_2); + CHECK_DECODE(exer_dec_fdec0, c_myfxml0_2_exer, MyFloatDecimal0, 12345.000000); + + CHECK_DECODE(bxer_dec_fdec0, c_myfxml0_3_bxer, MyFloatDecimal0, myfdec0_3); + CHECK_DECODE(exer_dec_fdec0, c_myfxml0_3_exer, MyFloatDecimal0, 1.000000); + + CHECK_DECODE(bxer_dec_fdec0, c_myfxml0_4_bxer, MyFloatDecimal0, myfdec0_4); + CHECK_DECODE(exer_dec_fdec0, c_myfxml0_4_exer, MyFloatDecimal0, 1234.000000); + + CHECK_DECODE(bxer_dec_fdec0, c_myfxml0_5_bxer, MyFloatDecimal0, myfdec0_5); + CHECK_DECODE(exer_dec_fdec0, c_myfxml0_5_exer, MyFloatDecimal0, 12345.000000); + + CHECK_DECODE(bxer_dec_fdec0, c_myfxml0_6_bxer, MyFloatDecimal0, myfdec0_6); + CHECK_DECODE(exer_dec_fdec0, c_myfxml0_6_exer, MyFloatDecimal0, 12345.000000); + + CHECK_DECODE(bxer_dec_fdec0, c_myfxml0_7_bxer, MyFloatDecimal0, myfdec0_7); + CHECK_DECODE(exer_dec_fdec0, c_myfxml0_7_exer, MyFloatDecimal0, 123450.000000); + + CHECK_DECODE(bxer_dec_fdec0, c_myfxml0_8_bxer, MyFloatDecimal0, myfdec0_8); + CHECK_DECODE(exer_dec_fdec0, c_myfxml0_8_exer, MyFloatDecimal0, 1234567890.000000); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +DECLARE_XER_ENCODERS(MyRec, frec) +DECLARE_EXER_ENCODERS(MyRec, frec) + +const MyRec c_myrec := { myfloat := 1234.5678 }; + +const universal charstring c_myrec_bxer := "<MyRec>\n\t<myfloat>1234.567800</myfloat>\n</MyRec>\n\n"; + +const universal charstring c_myrec_exer := "<MyRec myfloat='1234.56'/>\n\n"; + +testcase float_decimal_attr_enc() runs on FDT { + CHECK_METHOD(bxer_enc_frec, c_myrec, c_myrec_bxer); + CHECK_METHOD(exer_enc_frec, c_myrec, c_myrec_exer); +} + +testcase float_decimal_attr_dec() runs on FDT { + CHECK_DECODE(bxer_dec_frec, c_myrec_bxer, MyRec, c_myrec); + var MyRec local_rec := c_myrec; + local_rec.myfloat := 1234.560000; + CHECK_DECODE(exer_dec_frec, c_myrec_exer, MyRec, local_rec); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +control { + execute(float_decimal_enc2()); + execute(float_decimal_dec2()); + + execute(float_decimal_enc0()); + execute(float_decimal_dec0()); + + execute(float_decimal_attr_enc()); + execute(float_decimal_attr_dec()); +} + +} +with { encode "XML" } + diff --git a/regression_test/XML/TTCNandXML/config.cfg b/regression_test/XML/TTCNandXML/config.cfg index 6e95da598df528448987a76c5d0ebcc4a52cb053..f2344b4a52b2e21d46e12b5758c7ccb0338c6cdb 100644 --- a/regression_test/XML/TTCNandXML/config.cfg +++ b/regression_test/XML/TTCNandXML/config.cfg @@ -29,6 +29,7 @@ DFEAttribTest #DFEAttribTest.stopper Marx Regressions +FractionDigitsTest [LOGGING] FileMask := LOG_ALL | USER | DEBUG_ENCDEC diff --git a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_decimal_fractiondigits_e.ttcn b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_decimal_fractiondigits_e.ttcn index 02874c961381ac6c4dc9619ab3837be832b8e3f8..d6b7347fd23e4881de566c6740394083bf2b5036 100644 --- a/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_decimal_fractiondigits_e.ttcn +++ b/regression_test/XML/XmlWorkflow/XmlTest_expectedTtcns/www_example_org_decimal_fractiondigits_e.ttcn @@ -47,6 +47,7 @@ import from XSD all; type XSD.Decimal CelsiusBodyTemp (-9999.0 .. 9999.0) with { variant "name as uncapitalized"; + variant "fractionDigits 1"; }; @@ -60,6 +61,7 @@ with { variant "name as uncapitalized"; variant "useUnion"; variant "element"; + variant (alt_) "fractionDigits 1"; variant (alt_) "name as ''"; variant (alt_1) "name as ''"; variant (alt_2) "name as ''"; diff --git a/regression_test/compileonly/Makefile b/regression_test/compileonly/Makefile index f76cf23ffd0a79dfd917044d26a7ab0f2d654802..34a50e9d6a642cbfbdf2cadd7ca08ccb8b499d4d 100644 --- a/regression_test/compileonly/Makefile +++ b/regression_test/compileonly/Makefile @@ -13,6 +13,7 @@ # Kovacs, Ferenc # Raduly, Csaba # Szabados, Kristof +# Szabo, Bence Janos # Szabo, Janos Zoltan – initial implementation # ############################################################################## @@ -26,7 +27,8 @@ CODIRS := dynamicTemplate styleGuide topLevelPdu \ openType optionalAssignCompare portConstructor \ isbound namedActualParameters assignmentNotation \ attribQualif HT48786 selectCase openTypeNames \ - defaultParamUsageBeforeDecl deterministic readFromFile + defaultParamUsageBeforeDecl deterministic readFromFile \ + asn1_hyphen all dep clean distclean: for dir in $(CODIRS); do $(MAKE) -C $$dir $@ || exit; done diff --git a/usrguide/referenceguide.doc b/usrguide/referenceguide.doc index e9360f8584229b00214a8cc2a3c8b13a59e3921a..51752b91fb522c85e489a9c3321629659ffde80c 100644 Binary files a/usrguide/referenceguide.doc and b/usrguide/referenceguide.doc differ diff --git a/xsdconvert/RootType.cc b/xsdconvert/RootType.cc index 1798667e138a5dceea3a941fffd6b23d11164bf6..efad1b93599b84939d81816a67ce606241014856 100644 --- a/xsdconvert/RootType.cc +++ b/xsdconvert/RootType.cc @@ -168,7 +168,7 @@ void RootType::addVariant(const VariantMode var, const Mstring& var_value, const variantstring = "\"whiteSpace " + var_value + "\""; break; case V_fractionDigits: - //variantstring = "\"fractionDigits " + var_value + "\""; + variantstring = "\"fractionDigits " + var_value + "\""; break; } diff --git a/xsdconvert/SimpleType.cc b/xsdconvert/SimpleType.cc index 6a277e2f371b1fb6639eca0467e8b5afcb8f3d3f..4be2edf2d565be8deed6ea959e4950831862f162 100644 --- a/xsdconvert/SimpleType.cc +++ b/xsdconvert/SimpleType.cc @@ -227,7 +227,7 @@ void SimpleType::loadWithValues() { value.modified = true; break; case n_fractionDigits: - //addVariant(V_fractionDigits, atts.value); + addVariant(V_fractionDigits, atts.value); break; case n_label: addComment(Mstring("LABEL:"));