From 731585ab036bf6869749999e02edf565c23dd515 Mon Sep 17 00:00:00 2001
From: BenceJanosSzabo <bence.janos.szabo@ericsson.com>
Date: Thu, 20 Oct 2016 08:55:17 +0200
Subject: [PATCH] embed values with omitted fields now works properly (Bug
 506209)

Change-Id: I76540837816c7f510db97ad31d1e3214648968d5
Signed-off-by: BenceJanosSzabo <bence.janos.szabo@ericsson.com>
---
 compiler2/record.c                            |  15 +-
 core2/Basetype2.cc                            |   2 +-
 .../EmbedValuesOptional.ttcnpp                | 145 ++++++++++++++++++
 3 files changed, 159 insertions(+), 3 deletions(-)

diff --git a/compiler2/record.c b/compiler2/record.c
index fea74106c..1f9b0522f 100644
--- a/compiler2/record.c
+++ b/compiler2/record.c
@@ -2321,7 +2321,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
       if (sdef->xerEmbedValuesPossible) {
         src = mputprintf(src,
           "  if (e_xer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&\n"
-          "      %s%s%s emb_val->embval_index < field_%s%s.size_of()) {\n"
+          "      %s%s%s %s%s%s emb_val->embval_index < field_%s%s.size_of()) {\n"
           "    field_%s%s[emb_val->embval_index].XER_encode(\n"
           "      UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n"
           "    ++emb_val->embval_index;\n"
@@ -2329,12 +2329,19 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
           , sdef->elements[0].isOptional ? "field_" : ""
           , sdef->elements[0].isOptional ? sdef->elements[0].name : ""
           , sdef->elements[0].isOptional ? ".ispresent() &&" : ""
+          , sdef->elements[i].isOptional ? "field_" : ""
+          , sdef->elements[i].isOptional ? sdef->elements[i].name : ""
+          , sdef->elements[i].isOptional ? ".ispresent() &&" : ""
           , sdef->elements[0].name
           , sdef->elements[0].isOptional ? "()" : "", sdef->elements[0].name
           , sdef->elements[0].isOptional ? "()" : "");
       }
     } /* next field when not USE-ORDER */
-
+  
+  if (i <= start_at + num_attributes + 1 || sdef->xerUseOrderPossible) {
+    src = mputprintf(src, "  (void)emb_val_parent;\n"); // Silence unused warning
+  }
+  
   if (sdef->xerEmbedValuesPossible) {
     src = mputprintf(src,
       "  if (0 != emb_val) {\n"
@@ -3036,6 +3043,10 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
     }
   } /* next field */
   
+  if (i == start_at + num_attributes) {
+    src = mputprintf(src, "  (void)emb_val_parent;\n"); // Silence unused warning
+  }
+  
   if (sdef->xerEmbedValuesPossible) {
     /* read and store embedValues text if present */
     src = mputprintf(src,
diff --git a/core2/Basetype2.cc b/core2/Basetype2.cc
index 50e3acaba..c62c657d5 100644
--- a/core2/Basetype2.cc
+++ b/core2/Basetype2.cc
@@ -4437,7 +4437,7 @@ int Record_Type::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
 
         // Now the next embed-values string (NOT affected by USE-ORDER!)
         if (exer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&
-            embed_values != NULL && emb_val->embval_index < embed_values->size_of()) {
+            embed_values != NULL && emb_val->embval_index < embed_values->size_of() && ordered->get_at(ai)->is_present()) {
           embed_values->get_at(emb_val->embval_index)->XER_encode(UNIVERSAL_CHARSTRING_xer_
             , p_buf, flavor | EMBED_VALUES, indent+1, 0);
           ++emb_val->embval_index;
diff --git a/regression_test/XML/EXER-whitepaper/EmbedValuesOptional.ttcnpp b/regression_test/XML/EXER-whitepaper/EmbedValuesOptional.ttcnpp
index d24b5433d..21e0345c0 100644
--- a/regression_test/XML/EXER-whitepaper/EmbedValuesOptional.ttcnpp
+++ b/regression_test/XML/EXER-whitepaper/EmbedValuesOptional.ttcnpp
@@ -472,6 +472,148 @@ testcase dec_enil_opt() runs on EMBO
   CHECK_DECODE(exer_dec_en_opt, estr_gone_opt_omit, ENil_opt, gone_opt_omit);
 }
 
+
+/********************* EMBED-VALUES and Optional fields *********************/
+
+
+type record EmbedValuesOptFields {
+  record of universal charstring embed,
+  integer first optional,
+  integer second optional,
+  integer third optional
+}
+with {
+  variant "embedValues";
+}
+
+const EmbedValuesOptFields c_opt_fields := {
+  embed := { "She was ", "or", "!" },
+  first := omit,
+  second := 17,
+  third := 18
+}
+
+const universal charstring bstr_opt_fields_first :=
+"<EmbedValuesOptFields>"&
+"\n\t<embed>"&
+"\n\t\t<UNIVERSAL_CHARSTRING>She was </UNIVERSAL_CHARSTRING>"&
+"\n\t\t<UNIVERSAL_CHARSTRING>or</UNIVERSAL_CHARSTRING>"&
+"\n\t\t<UNIVERSAL_CHARSTRING>!</UNIVERSAL_CHARSTRING>"&
+"\n\t</embed>"&
+"\n\t<second>17</second>"&
+"\n\t<third>18</third>"&
+"\n</EmbedValuesOptFields>"&
+"\n"&
+"\n";
+
+const universal charstring estr_opt_fields_first :=
+"<EmbedValuesOptFields>She was "&
+"<second>17</second>or"&
+"<third>18</third>!"&
+"</EmbedValuesOptFields>\n";
+
+const universal charstring bstr_opt_fields_second :=
+"<EmbedValuesOptFields>"&
+"\n\t<embed>"&
+"\n\t\t<UNIVERSAL_CHARSTRING>She was </UNIVERSAL_CHARSTRING>"&
+"\n\t\t<UNIVERSAL_CHARSTRING>or</UNIVERSAL_CHARSTRING>"&
+"\n\t\t<UNIVERSAL_CHARSTRING>!</UNIVERSAL_CHARSTRING>"&
+"\n\t</embed>"&
+"\n\t<first>16</first>"&
+"\n\t<third>18</third>"&
+"\n</EmbedValuesOptFields>"&
+"\n"&
+"\n";
+
+const universal charstring estr_opt_fields_second :=
+"<EmbedValuesOptFields>She was "&
+"<first>16</first>or"&
+"<third>18</third>!"&
+"</EmbedValuesOptFields>\n";
+
+const universal charstring bstr_opt_fields_third :=
+"<EmbedValuesOptFields>"&
+"\n\t<embed>"&
+"\n\t\t<UNIVERSAL_CHARSTRING>She was </UNIVERSAL_CHARSTRING>"&
+"\n\t\t<UNIVERSAL_CHARSTRING>or</UNIVERSAL_CHARSTRING>"&
+"\n\t\t<UNIVERSAL_CHARSTRING>!</UNIVERSAL_CHARSTRING>"&
+"\n\t</embed>"&
+"\n\t<first>16</first>"&
+"\n\t<second>17</second>"&
+"\n</EmbedValuesOptFields>"&
+"\n"&
+"\n";
+
+const universal charstring estr_opt_fields_third :=
+"<EmbedValuesOptFields>She was "&
+"<first>16</first>or"&
+"<second>17</second>!"&
+"</EmbedValuesOptFields>\n";
+
+const universal charstring bstr_opt_fields_all :=
+"<EmbedValuesOptFields>"&
+"\n\t<embed>"&
+"\n\t\t<UNIVERSAL_CHARSTRING>She was </UNIVERSAL_CHARSTRING>"&
+"\n\t</embed>"&
+"\n</EmbedValuesOptFields>"&
+"\n"&
+"\n";
+
+const universal charstring estr_opt_fields_all :=
+"<EmbedValuesOptFields>She was "&
+"</EmbedValuesOptFields>\n";
+
+DECLARE_XER_ENCODERS(EmbedValuesOptFields, opt_fields);
+DECLARE_EXER_ENCODERS(EmbedValuesOptFields, opt_fields);
+
+testcase enc_opt_fields() runs on EMBO
+{
+  CHECK_METHOD(bxer_enc_opt_fields, c_opt_fields, bstr_opt_fields_first);
+  CHECK_METHOD(exer_enc_opt_fields, c_opt_fields, estr_opt_fields_first);
+
+  var EmbedValuesOptFields local_opt_fields := c_opt_fields;
+  local_opt_fields.first := 16;
+  local_opt_fields.second := omit;
+  CHECK_METHOD(bxer_enc_opt_fields, local_opt_fields, bstr_opt_fields_second);
+  CHECK_METHOD(exer_enc_opt_fields, local_opt_fields, estr_opt_fields_second);
+
+  local_opt_fields.second := 17;
+  local_opt_fields.third := omit;
+  CHECK_METHOD(bxer_enc_opt_fields, local_opt_fields, bstr_opt_fields_third);
+  CHECK_METHOD(exer_enc_opt_fields, local_opt_fields, estr_opt_fields_third);
+
+  local_opt_fields.embed := { "She was " };
+  local_opt_fields.first := omit;
+  local_opt_fields.second := omit;
+  local_opt_fields.third := omit;
+  CHECK_METHOD(bxer_enc_opt_fields, local_opt_fields, bstr_opt_fields_all);
+  CHECK_METHOD(exer_enc_opt_fields, local_opt_fields, estr_opt_fields_all);
+}
+
+testcase dec_opt_fields() runs on EMBO
+{
+  CHECK_DECODE(bxer_dec_opt_fields, bstr_opt_fields_first, EmbedValuesOptFields, c_opt_fields);
+  CHECK_DECODE(exer_dec_opt_fields, estr_opt_fields_first, EmbedValuesOptFields, c_opt_fields);
+
+  var EmbedValuesOptFields local_opt_fields := c_opt_fields;
+  local_opt_fields.first := 16;
+  local_opt_fields.second := omit;
+  CHECK_DECODE(bxer_dec_opt_fields, bstr_opt_fields_second, EmbedValuesOptFields, local_opt_fields);
+  CHECK_DECODE(exer_dec_opt_fields, estr_opt_fields_second, EmbedValuesOptFields, local_opt_fields);
+
+  local_opt_fields.second := 17;
+  local_opt_fields.third := omit;
+  CHECK_DECODE(bxer_dec_opt_fields, bstr_opt_fields_third, EmbedValuesOptFields, local_opt_fields);
+  CHECK_DECODE(exer_dec_opt_fields, estr_opt_fields_third, EmbedValuesOptFields, local_opt_fields);
+
+  local_opt_fields.embed := { "She was " };
+  local_opt_fields.first := omit;
+  local_opt_fields.second := omit;
+  local_opt_fields.third := omit;
+  CHECK_DECODE(bxer_dec_opt_fields, bstr_opt_fields_all, EmbedValuesOptFields, local_opt_fields);
+  CHECK_DECODE(exer_dec_opt_fields, estr_opt_fields_all, EmbedValuesOptFields, local_opt_fields);
+}
+
 control
 {
     execute(encode_emb_all_opt());
@@ -494,6 +636,9 @@ control
 
     execute(enc_enil_opt());
     execute(dec_enil_opt());
+
+    execute(enc_opt_fields());
+    execute(dec_opt_fields());
 }
 
 }
-- 
GitLab