You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by ji...@apache.org on 2023/12/09 00:46:53 UTC
(daffodil) branch main updated: Give codegen-c somewhat limited dfdl:assert support
This is an automated email from the ASF dual-hosted git repository.
jinterrante pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil.git
The following commit(s) were added to refs/heads/main by this push:
new b4eaa46c0 Give codegen-c somewhat limited dfdl:assert support
b4eaa46c0 is described below
commit b4eaa46c0c6b17b9be7f94772a2e37ae817801f0
Author: John Interrante <in...@research.ge.com>
AuthorDate: Fri Dec 8 09:28:41 2023 -0500
Give codegen-c somewhat limited dfdl:assert support
On the basis that a little support is better than none, allow
codegen-c to generate C code for a limited subset of dfdl:assert
expressions. The use case is to allow generated code to validate or
reject messages using dfdl:assert expressions as well as ranges and
enumerations. The dfdl:assert support is limited to replacing
"../foo/x" and "." with the appropriate pointers and replacing DFDL
named operators ("eq") with C-compatible operators ("==") using find
and replace operators. In the long term, a better approach would be
to add methods to the compiled expression classes to generate C code
directly from the compiled expressions with fuller understanding of
what the parts of the expressions represent.
DAFFODIL-2865
errors.[ch]: Add new ERR_DFDL_ASSERT error code for assertion
expressions which fail.
validators.[ch]: Add new validate_dfdl_assert function for checking
assertion expressions, making sure to handle both recoverable and
non-recoverable assertion failures appropriately.
DaffodilCCodeGenerator.scala: Call AssertStatementGenerateCode to
generate C code for assertion expressions in both empty sequences and
simple elements.
AssertStatementGenerateCode.scala: Generate C code for two types of
assertion expressions: "{ ../../foo/x eq 2 }" as used in empty
sequences and "{ . eq 2 }" as used in simple elements. Anything else
likely won't produce valid C code at this time.
CodeGeneratorState.scala: Make the cExpression function find and
replace even more DFDL named operators with C-compatible operators.
NestedUnion/generated_code.c: Regenerate to show new C code for
assertion expressions in simple elements.
data/nested.struct.{diag{1,2},err{1,2}}.dat: Add new data files which
will deliberately fail assertion expression checks.
infosets/nested.struct.{diag{1,2},err{1,2}}.dat.xml: Add new infoset
files which will deliberately fail assertion expression checks.
{data,infosets}/nested.union.bar.dat{,.xml}: Modify to pass assertion
expression checks.
nested.dfdl.xsd: Add both kinds of assertion expression checks (empty
sequences and simple elements) to test the new codegen-c support.
nested.tdml: Add new validation test cases to check both failure types
of assertion expression checks.
TestNested.scala: Call the new validation test cases.
---
.../daffodil/codegen/c/files/libruntime/errors.c | 1 +
.../daffodil/codegen/c/files/libruntime/errors.h | 1 +
.../codegen/c/files/libruntime/validators.c | 25 ++++++++
.../codegen/c/files/libruntime/validators.h | 5 ++
.../codegen/c/DaffodilCCodeGenerator.scala | 27 +++++++-
.../c/generators/AssertStatementGenerateCode.scala | 56 +++++++++++++++++
.../codegen/c/generators/CodeGeneratorState.scala | 13 +++-
.../src/test/examples/NestedUnion/generated_code.c | 8 +++
.../codegen/c/data/nested.struct.diag1.dat | Bin 0 -> 36 bytes
.../codegen/c/data/nested.struct.diag2.dat | Bin 0 -> 36 bytes
.../daffodil/codegen/c/data/nested.struct.err1.dat | Bin 0 -> 36 bytes
.../daffodil/codegen/c/data/nested.struct.err2.dat | Bin 0 -> 36 bytes
.../daffodil/codegen/c/data/nested.union.bar.dat | Bin 28 -> 28 bytes
...ion.bar.dat.xml => nested.struct.diag1.dat.xml} | 16 +++--
...ion.bar.dat.xml => nested.struct.diag2.dat.xml} | 16 +++--
...nion.bar.dat.xml => nested.struct.err1.dat.xml} | 16 +++--
...nion.bar.dat.xml => nested.struct.err2.dat.xml} | 16 +++--
.../codegen/c/infosets/nested.union.bar.dat.xml | 6 +-
.../org/apache/daffodil/codegen/c/nested.dfdl.xsd | 36 ++++++++++-
.../org/apache/daffodil/codegen/c/nested.tdml | 69 ++++++++++++++++++++-
.../org/apache/daffodil/codegen/c/TestNested.scala | 10 ++-
21 files changed, 283 insertions(+), 38 deletions(-)
diff --git a/daffodil-codegen-c/src/main/resources/org/apache/daffodil/codegen/c/files/libruntime/errors.c b/daffodil-codegen-c/src/main/resources/org/apache/daffodil/codegen/c/files/libruntime/errors.c
index 550e1a575..e076e8948 100644
--- a/daffodil-codegen-c/src/main/resources/org/apache/daffodil/codegen/c/files/libruntime/errors.c
+++ b/daffodil-codegen-c/src/main/resources/org/apache/daffodil/codegen/c/files/libruntime/errors.c
@@ -81,6 +81,7 @@ error_lookup(uint8_t code)
static const ErrorLookup table[ERR__NUM_CODES] = {
{ERR_ARRAY_BOUNDS, "%s count out of bounds\n", FIELD_S},
{ERR_CHOICE_KEY, "no match between choice dispatch key %" PRId64 " and any branch key\n", FIELD_D64},
+ {ERR_DFDL_ASSERT, "Assertion expression failed: %s", FIELD_S},
{ERR_HEXBINARY_ALLOC, "error allocating hexBinary memory -- %" PRId64 " bytes\n", FIELD_D64},
{ERR_LEFTOVER_DATA, "Left over data, at least %i bit(s) remaining after end of parse\n", FIELD_C},
{ERR_PARSE_BOOL, "error parsing binary value %" PRId64 " as either true or false\n", FIELD_D64},
diff --git a/daffodil-codegen-c/src/main/resources/org/apache/daffodil/codegen/c/files/libruntime/errors.h b/daffodil-codegen-c/src/main/resources/org/apache/daffodil/codegen/c/files/libruntime/errors.h
index 62b52c51b..1fe7a26fd 100644
--- a/daffodil-codegen-c/src/main/resources/org/apache/daffodil/codegen/c/files/libruntime/errors.h
+++ b/daffodil-codegen-c/src/main/resources/org/apache/daffodil/codegen/c/files/libruntime/errors.h
@@ -32,6 +32,7 @@ enum ErrorCode
{
ERR_ARRAY_BOUNDS,
ERR_CHOICE_KEY,
+ ERR_DFDL_ASSERT,
ERR_HEXBINARY_ALLOC,
ERR_LEFTOVER_DATA,
ERR_PARSE_BOOL,
diff --git a/daffodil-codegen-c/src/main/resources/org/apache/daffodil/codegen/c/files/libruntime/validators.c b/daffodil-codegen-c/src/main/resources/org/apache/daffodil/codegen/c/files/libruntime/validators.c
index 69f388741..32782b211 100644
--- a/daffodil-codegen-c/src/main/resources/org/apache/daffodil/codegen/c/files/libruntime/validators.c
+++ b/daffodil-codegen-c/src/main/resources/org/apache/daffodil/codegen/c/files/libruntime/validators.c
@@ -38,6 +38,31 @@ validate_array_bounds(const char *name, size_t count, size_t minOccurs, size_t m
}
}
+// Validate element or sequence's dfdl:assert expression returns true
+
+void
+validate_dfdl_assert(bool assertion, const char *expression, bool recoverable, ParserOrUnparserState *pu)
+{
+ // The boolean expression that determines if the assertion is true
+ // is evaluated in generated code and the result passed here, as
+ // well as failure_type which determines whether to issue a diagnostic
+ // which is printed later or an error which terminates processing now.
+ if (!assertion && recoverable)
+ {
+ Diagnostics *diagnostics = get_diagnostics();
+ const Error error = {ERR_DFDL_ASSERT, {.s = expression}};
+
+ add_diagnostic(diagnostics, &error);
+ pu->diagnostics = diagnostics;
+ }
+ else if (!assertion)
+ {
+ static Error error = {ERR_DFDL_ASSERT, {0}};
+ error.arg.s = expression;
+ pu->error = &error;
+ }
+}
+
// Validate element's value is same as its fixed attribute
void
diff --git a/daffodil-codegen-c/src/main/resources/org/apache/daffodil/codegen/c/files/libruntime/validators.h b/daffodil-codegen-c/src/main/resources/org/apache/daffodil/codegen/c/files/libruntime/validators.h
index fb9cca8d6..27133957c 100644
--- a/daffodil-codegen-c/src/main/resources/org/apache/daffodil/codegen/c/files/libruntime/validators.h
+++ b/daffodil-codegen-c/src/main/resources/org/apache/daffodil/codegen/c/files/libruntime/validators.h
@@ -31,6 +31,11 @@
extern void validate_array_bounds(const char *name, size_t count, size_t minOccurs, size_t maxOccurs,
ParserOrUnparserState *pu);
+// Validate element or sequence's dfdl:assert expression returns true
+
+extern void validate_dfdl_assert(bool assertion, const char *expression, bool recoverable,
+ ParserOrUnparserState *pu);
+
// Validate element's value is same as its fixed attribute
extern void validate_fixed_attribute(bool same, const char *element, ParserOrUnparserState *pu);
diff --git a/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/DaffodilCCodeGenerator.scala b/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/DaffodilCCodeGenerator.scala
index 7bedd2fa5..b8dc511d8 100644
--- a/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/DaffodilCCodeGenerator.scala
+++ b/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/DaffodilCCodeGenerator.scala
@@ -25,6 +25,7 @@ import scala.collection.JavaConverters._
import scala.util.Properties.isWin
import org.apache.daffodil.codegen.c.generators.AlignmentFillCodeGenerator
+import org.apache.daffodil.codegen.c.generators.AssertStatementGenerateCode
import org.apache.daffodil.codegen.c.generators.BinaryBooleanCodeGenerator
import org.apache.daffodil.codegen.c.generators.BinaryFloatCodeGenerator
import org.apache.daffodil.codegen.c.generators.BinaryIntegerKnownLengthCodeGenerator
@@ -60,6 +61,8 @@ import org.apache.daffodil.core.grammar.primitives.SpecifiedLengthExplicit
import org.apache.daffodil.core.grammar.primitives.SpecifiedLengthImplicit
import org.apache.daffodil.lib.api.Diagnostic
import org.apache.daffodil.lib.api.WarnID
+import org.apache.daffodil.lib.schema.annotation.props.gen.FailureType
+import org.apache.daffodil.lib.schema.annotation.props.gen.TestKind
import org.apache.daffodil.lib.util.Misc
import org.apache.daffodil.runtime1.api.DFDL
import org.apache.daffodil.runtime1.dsom.SchemaDefinitionError
@@ -247,6 +250,7 @@ class DaffodilCCodeGenerator(root: Root) extends DFDL.CodeGenerator {
*/
object DaffodilCCodeGenerator
extends AlignmentFillCodeGenerator
+ with AssertStatementGenerateCode
with BinaryBooleanCodeGenerator
with BinaryIntegerKnownLengthCodeGenerator
with BinaryFloatCodeGenerator
@@ -263,7 +267,13 @@ object DaffodilCCodeGenerator
case g: Gram if g.isEmpty => noop(g)
// Handle non-empty grams
case g: AlignmentFill => alignmentFillGenerateCode(g, cgState)
- case g: AssertBooleanPrim => noop(g)
+ case g: AssertBooleanPrim =>
+ assertStatementGenerateCode(
+ g.name,
+ g.exprText,
+ g.stmt.failureType == FailureType.RecoverableError,
+ cgState,
+ )
case g: BinaryBoolean => binaryBooleanGenerateCode(g.e, cgState)
case g: BinaryDouble => binaryFloatGenerateCode(g.e, lengthInBits = 64, cgState)
case g: BinaryFloat => binaryFloatGenerateCode(g.e, lengthInBits = 32, cgState)
@@ -306,6 +316,21 @@ object DaffodilCCodeGenerator
private def elementCombinator(g: ElementCombinator, cgState: CodeGeneratorState): Unit = {
cgState.pushElement(g.context)
DaffodilCCodeGenerator.generateCode(g.subComb, cgState)
+ // Also generate code for the element's assert statements
+ g.context.assertStatements.foreach { assert =>
+ assert.testKind match {
+ case TestKind.Pattern =>
+ g.SDW(
+ WarnID.IgnoreDFDLProperty,
+ "Code generation not supported for dfdl:assert pattern stmts",
+ )
+ case TestKind.Expression =>
+ val name = g.name
+ val exprText = assert.testTxt
+ val recoverable = assert.failureType == FailureType.RecoverableError
+ assertStatementGenerateCode(name, exprText, recoverable, cgState)
+ }
+ }
cgState.popElement(g.context)
}
diff --git a/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/generators/AssertStatementGenerateCode.scala b/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/generators/AssertStatementGenerateCode.scala
new file mode 100644
index 000000000..1fa5b4399
--- /dev/null
+++ b/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/generators/AssertStatementGenerateCode.scala
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.daffodil.codegen.c.generators
+
+// Generate C code for two types of assertion expressions:
+//
+// { ../../foo/x eq 2 } as used in empty sequences
+// { . eq 2 } as used in simple elements
+//
+// Anything else likely won't produce valid C code at this time.
+
+trait AssertStatementGenerateCode {
+
+ def assertStatementGenerateCode(
+ name: String,
+ exprText: String,
+ recoverable: Boolean,
+ cgState: CodeGeneratorState,
+ ): Unit = {
+ val indent = if (cgState.hasChoice) INDENT else NO_INDENT
+ val exprWOBraces = exprText.stripPrefix("{").stripSuffix("}").trim()
+ // Handle assertion expressions with "../" as used in empty sequences
+ val modifiedExpr =
+ if (exprWOBraces.startsWith("../"))
+ s"../$exprWOBraces"
+ else
+ exprWOBraces
+ // Handle assertion expressions with "." as used in simple elements
+ val cExpr = cgState.cExpression(modifiedExpr).replaceFirst("^\\. ", s"instance->$name ")
+
+ val initERDStatement = ""
+ val parseStatement =
+ s"""$indent validate_dfdl_assert($cExpr, "$exprText", $recoverable, &pstate->pu);
+ |$indent if (pstate->pu.error) return;""".stripMargin
+ val unparseStatement =
+ s"""$indent validate_dfdl_assert($cExpr, "$exprText", $recoverable, &ustate->pu);
+ |$indent if (ustate->pu.error) return;""".stripMargin
+ cgState.addSimpleTypeStatements(initERDStatement, parseStatement, unparseStatement)
+ }
+
+}
diff --git a/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/generators/CodeGeneratorState.scala b/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/generators/CodeGeneratorState.scala
index 70ac0ca21..743a96786 100644
--- a/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/generators/CodeGeneratorState.scala
+++ b/daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/generators/CodeGeneratorState.scala
@@ -445,15 +445,24 @@ class CodeGeneratorState(private val root: ElementBase) {
},
)
// Match each named operator and replace it with a C operator
- val operator = """(\bidiv\b|\bdiv\b|\bmod\b)""".r
+ val operator =
+ """(\band\b|\bdiv\b|\beq\b|\bge\b|\bgt\b|\bidiv\b|\ble\b|\blt\b|\bmod\b|\bne\b|\bor\b)""".r
val exprWithOperators = operator.replaceAllIn(
exprWithFields,
m => {
val operatorName = m.group(1)
val cOperatorSymbol = operatorName match {
- case "idiv" => "/"
+ case "and" => "&&"
case "div" => "/"
+ case "eq" => "=="
+ case "ge" => ">="
+ case "gt" => ">"
+ case "idiv" => "/"
+ case "le" => "<="
+ case "lt" => "<"
case "mod" => "%"
+ case "ne" => "!="
+ case "or" => "||"
}
cOperatorSymbol
},
diff --git a/daffodil-codegen-c/src/test/examples/NestedUnion/generated_code.c b/daffodil-codegen-c/src/test/examples/NestedUnion/generated_code.c
index 3633e1696..589d2be04 100644
--- a/daffodil-codegen-c/src/test/examples/NestedUnion/generated_code.c
+++ b/daffodil-codegen-c/src/test/examples/NestedUnion/generated_code.c
@@ -236,6 +236,8 @@ foo_data_NestedUnionType__parseSelf(foo_data_NestedUnionType_ *instance, PState
{
parse_be_int32(&instance->a, 32, pstate);
if (pstate->pu.error) return;
+ validate_dfdl_assert(instance->a == 1, "{ . eq 1 }", true, &pstate->pu);
+ if (pstate->pu.error) return;
parse_be_int32(&instance->b, 32, pstate);
if (pstate->pu.error) return;
parse_be_int32(&instance->c, 32, pstate);
@@ -247,6 +249,8 @@ foo_data_NestedUnionType__unparseSelf(const foo_data_NestedUnionType_ *instance,
{
unparse_be_int32(instance->a, 32, ustate);
if (ustate->pu.error) return;
+ validate_dfdl_assert(instance->a == 1, "{ . eq 1 }", true, &ustate->pu);
+ if (ustate->pu.error) return;
unparse_be_int32(instance->b, 32, ustate);
if (ustate->pu.error) return;
unparse_be_int32(instance->c, 32, ustate);
@@ -267,6 +271,8 @@ bar_data_NestedUnionType__parseSelf(bar_data_NestedUnionType_ *instance, PState
if (pstate->pu.error) return;
parse_be_double(&instance->y, 64, pstate);
if (pstate->pu.error) return;
+ validate_dfdl_assert(instance->y == 5.5, "{ . eq 5.5 }", false, &pstate->pu);
+ if (pstate->pu.error) return;
parse_be_double(&instance->z, 64, pstate);
if (pstate->pu.error) return;
}
@@ -278,6 +284,8 @@ bar_data_NestedUnionType__unparseSelf(const bar_data_NestedUnionType_ *instance,
if (ustate->pu.error) return;
unparse_be_double(instance->y, 64, ustate);
if (ustate->pu.error) return;
+ validate_dfdl_assert(instance->y == 5.5, "{ . eq 5.5 }", false, &ustate->pu);
+ if (ustate->pu.error) return;
unparse_be_double(instance->z, 64, ustate);
if (ustate->pu.error) return;
}
diff --git a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/data/nested.struct.diag1.dat b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/data/nested.struct.diag1.dat
new file mode 100644
index 000000000..f821f075f
Binary files /dev/null and b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/data/nested.struct.diag1.dat differ
diff --git a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/data/nested.struct.diag2.dat b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/data/nested.struct.diag2.dat
new file mode 100644
index 000000000..3cd1e8543
Binary files /dev/null and b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/data/nested.struct.diag2.dat differ
diff --git a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/data/nested.struct.err1.dat b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/data/nested.struct.err1.dat
new file mode 100644
index 000000000..c345a9f69
Binary files /dev/null and b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/data/nested.struct.err1.dat differ
diff --git a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/data/nested.struct.err2.dat b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/data/nested.struct.err2.dat
new file mode 100644
index 000000000..07f3de48c
Binary files /dev/null and b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/data/nested.struct.err2.dat differ
diff --git a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/data/nested.union.bar.dat b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/data/nested.union.bar.dat
index a8d472cd4..b1d7dcb15 100644
Binary files a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/data/nested.union.bar.dat and b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/data/nested.union.bar.dat differ
diff --git a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.union.bar.dat.xml b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.struct.diag1.dat.xml
similarity index 82%
copy from daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.union.bar.dat.xml
copy to daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.struct.diag1.dat.xml
index 6688d57f6..87f86b0b0 100644
--- a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.union.bar.dat.xml
+++ b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.struct.diag1.dat.xml
@@ -16,13 +16,17 @@
limitations under the License.
-->
-<idl:NestedUnion xmlns:idl="urn:idl:1.0">
- <tag>4</tag>
+<idl:NestedStruct xmlns:idl="urn:idl:1.0">
<data>
+ <foo>
+ <a>0</a>
+ <b>2</b>
+ <c>3</c>
+ </foo>
<bar>
- <x>1.5</x>
- <y>2.5</y>
- <z>3.5</z>
+ <x>4.5</x>
+ <y>5.5</y>
+ <z>6.5</z>
</bar>
</data>
-</idl:NestedUnion>
+</idl:NestedStruct>
diff --git a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.union.bar.dat.xml b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.struct.diag2.dat.xml
similarity index 82%
copy from daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.union.bar.dat.xml
copy to daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.struct.diag2.dat.xml
index 6688d57f6..aca4664c5 100644
--- a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.union.bar.dat.xml
+++ b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.struct.diag2.dat.xml
@@ -16,13 +16,17 @@
limitations under the License.
-->
-<idl:NestedUnion xmlns:idl="urn:idl:1.0">
- <tag>4</tag>
+<idl:NestedStruct xmlns:idl="urn:idl:1.0">
<data>
+ <foo>
+ <a>1</a>
+ <b>0</b>
+ <c>3</c>
+ </foo>
<bar>
- <x>1.5</x>
- <y>2.5</y>
- <z>3.5</z>
+ <x>4.5</x>
+ <y>5.5</y>
+ <z>6.5</z>
</bar>
</data>
-</idl:NestedUnion>
+</idl:NestedStruct>
diff --git a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.union.bar.dat.xml b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.struct.err1.dat.xml
similarity index 82%
copy from daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.union.bar.dat.xml
copy to daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.struct.err1.dat.xml
index 6688d57f6..c34397a41 100644
--- a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.union.bar.dat.xml
+++ b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.struct.err1.dat.xml
@@ -16,13 +16,17 @@
limitations under the License.
-->
-<idl:NestedUnion xmlns:idl="urn:idl:1.0">
- <tag>4</tag>
+<idl:NestedStruct xmlns:idl="urn:idl:1.0">
<data>
+ <foo>
+ <a>1</a>
+ <b>2</b>
+ <c>3</c>
+ </foo>
<bar>
- <x>1.5</x>
- <y>2.5</y>
- <z>3.5</z>
+ <x>0.5</x>
+ <y>5.5</y>
+ <z>6.5</z>
</bar>
</data>
-</idl:NestedUnion>
+</idl:NestedStruct>
diff --git a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.union.bar.dat.xml b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.struct.err2.dat.xml
similarity index 82%
copy from daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.union.bar.dat.xml
copy to daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.struct.err2.dat.xml
index 6688d57f6..684b74aac 100644
--- a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.union.bar.dat.xml
+++ b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.struct.err2.dat.xml
@@ -16,13 +16,17 @@
limitations under the License.
-->
-<idl:NestedUnion xmlns:idl="urn:idl:1.0">
- <tag>4</tag>
+<idl:NestedStruct xmlns:idl="urn:idl:1.0">
<data>
+ <foo>
+ <a>1</a>
+ <b>2</b>
+ <c>3</c>
+ </foo>
<bar>
- <x>1.5</x>
- <y>2.5</y>
- <z>3.5</z>
+ <x>4.5</x>
+ <y>0.5</y>
+ <z>6.5</z>
</bar>
</data>
-</idl:NestedUnion>
+</idl:NestedStruct>
diff --git a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.union.bar.dat.xml b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.union.bar.dat.xml
index 6688d57f6..0ae9223d4 100644
--- a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.union.bar.dat.xml
+++ b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/infosets/nested.union.bar.dat.xml
@@ -20,9 +20,9 @@
<tag>4</tag>
<data>
<bar>
- <x>1.5</x>
- <y>2.5</y>
- <z>3.5</z>
+ <x>4.5</x>
+ <y>5.5</y>
+ <z>6.5</z>
</bar>
</data>
</idl:NestedUnion>
diff --git a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/nested.dfdl.xsd b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/nested.dfdl.xsd
index a5536ae37..c37f07a61 100644
--- a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/nested.dfdl.xsd
+++ b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/nested.dfdl.xsd
@@ -44,7 +44,15 @@
<xs:complexType name="FooType">
<xs:sequence>
- <xs:element name="a" type="idl:int32"/>
+ <xs:element name="a" type="idl:int32">
+ <!-- Validate field a; recoverable error if fails -->
+ <xs:annotation>
+ <xs:appinfo source="http://www.ogf.org/dfdl/">
+ <dfdl:assert test="{ . eq 1 }"
+ failureType="recoverableError"/>
+ </xs:appinfo>
+ </xs:annotation>
+ </xs:element>
<xs:element name="b" type="idl:int32"/>
<xs:element name="c" type="idl:int32"/>
</xs:sequence>
@@ -53,7 +61,14 @@
<xs:complexType name="BarType">
<xs:sequence>
<xs:element name="x" type="idl:double"/>
- <xs:element name="y" type="idl:double"/>
+ <xs:element name="y" type="idl:double">
+ <!-- Validate field y; processing error if fails -->
+ <xs:annotation>
+ <xs:appinfo source="http://www.ogf.org/dfdl/">
+ <dfdl:assert test="{ . eq 5.5 }"/>
+ </xs:appinfo>
+ </xs:annotation>
+ </xs:element>
<xs:element name="z" type="idl:double"/>
</xs:sequence>
</xs:complexType>
@@ -64,7 +79,24 @@
<xs:complexType>
<xs:sequence>
<xs:element name="foo" type="idl:FooType"/>
+ <!-- Validate field b in foo; recoverable error if fails -->
+ <xs:sequence>
+ <xs:annotation>
+ <xs:appinfo source="http://www.ogf.org/dfdl/">
+ <dfdl:assert test="{ ../data/foo/b eq 2 }"
+ failureType="recoverableError"/>
+ </xs:appinfo>
+ </xs:annotation>
+ </xs:sequence>
<xs:element name="bar" type="idl:BarType"/>
+ <!-- Validate field x in bar; processing error if fails -->
+ <xs:sequence>
+ <xs:annotation>
+ <xs:appinfo source="http://www.ogf.org/dfdl/">
+ <dfdl:assert test="{ ../data/bar/x eq 4.5 }"/>
+ </xs:appinfo>
+ </xs:annotation>
+ </xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
diff --git a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/nested.tdml b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/nested.tdml
index bb8032915..3c1124c01 100644
--- a/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/nested.tdml
+++ b/daffodil-codegen-c/src/test/resources/org/apache/daffodil/codegen/c/nested.tdml
@@ -28,9 +28,18 @@
daffodil test -i -I daffodil nested.tdml
daffodil test -i -I daffodilC nested.tdml
+
+ Or you can debug specific steps in isolation:
+
+ daffodil parse -s nested.dfdl.xsd -o infosets/nested.struct.dat.xml data/nested.struct.dat
+ daffodil unparse -s nested.dfdl.xsd -o data/nested.struct.dat infosets/nested.struct.dat.xml
+
+ daffodil generate c -s nested.dfdl.xsd && make -C c
+ c/daffodil parse -o c/nested.struct.dat.xml data/nested.struct.dat
+ c/daffodil unparse -o c/nested.struct.dat infosets/nested.struct.dat.xml
-->
- <tdml:parserTestCase model="nested.dfdl.xsd" name="nested_struct">
+ <tdml:parserTestCase model="nested.dfdl.xsd" name="nested.struct">
<tdml:document>
<tdml:documentPart type="file">data/nested.struct.dat</tdml:documentPart>
</tdml:document>
@@ -39,7 +48,61 @@
</tdml:infoset>
</tdml:parserTestCase>
- <tdml:parserTestCase model="nested.dfdl.xsd" name="nested_union_bar">
+ <tdml:parserTestCase model="nested.dfdl.xsd" name="nested.struct.diag1">
+ <tdml:document>
+ <tdml:documentPart type="file">data/nested.struct.diag1.dat</tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset type="file">infosets/nested.struct.diag1.dat.xml</tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:validationErrors>
+ <tdml:error>expression</tdml:error>
+ <tdml:error>failed</tdml:error>
+ <tdml:error>. eq 1</tdml:error>
+ </tdml:validationErrors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase model="nested.dfdl.xsd" name="nested.struct.diag2">
+ <tdml:document>
+ <tdml:documentPart type="file">data/nested.struct.diag2.dat</tdml:documentPart>
+ </tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset type="file">infosets/nested.struct.diag2.dat.xml</tdml:dfdlInfoset>
+ </tdml:infoset>
+ <tdml:validationErrors>
+ <tdml:error>expression</tdml:error>
+ <tdml:error>failed</tdml:error>
+ <tdml:error>b eq 2</tdml:error>
+ </tdml:validationErrors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase model="nested.dfdl.xsd"
+ name="nested.struct.err1"
+ root="NestedStruct">
+ <tdml:document>
+ <tdml:documentPart type="file">data/nested.struct.err1.dat</tdml:documentPart>
+ </tdml:document>
+ <tdml:errors>
+ <tdml:error>expression</tdml:error>
+ <tdml:error>failed</tdml:error>
+ <tdml:error>x eq 4.5</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase model="nested.dfdl.xsd"
+ name="nested.struct.err2"
+ root="NestedStruct">
+ <tdml:document>
+ <tdml:documentPart type="file">data/nested.struct.err2.dat</tdml:documentPart>
+ </tdml:document>
+ <tdml:errors>
+ <tdml:error>expression</tdml:error>
+ <tdml:error>failed</tdml:error>
+ <tdml:error>. eq 5.5</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase model="nested.dfdl.xsd" name="nested.union.bar">
<tdml:document>
<tdml:documentPart type="file">data/nested.union.bar.dat</tdml:documentPart>
</tdml:document>
@@ -48,7 +111,7 @@
</tdml:infoset>
</tdml:parserTestCase>
- <tdml:parserTestCase model="nested.dfdl.xsd" name="nested_union_foo">
+ <tdml:parserTestCase model="nested.dfdl.xsd" name="nested.union.foo">
<tdml:document>
<tdml:documentPart type="file">data/nested.union.foo.dat</tdml:documentPart>
</tdml:document>
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/codegen/c/TestNested.scala b/daffodil-test/src/test/scala/org/apache/daffodil/codegen/c/TestNested.scala
index 2744c06d0..1177449ff 100644
--- a/daffodil-test/src/test/scala/org/apache/daffodil/codegen/c/TestNested.scala
+++ b/daffodil-test/src/test/scala/org/apache/daffodil/codegen/c/TestNested.scala
@@ -33,7 +33,11 @@ object TestNested {
class TestNested {
import TestNested._
- @Test def test_nested_struct(): Unit = { runner.runOneTest("nested_struct") }
- @Test def test_nested_union_bar(): Unit = { runner.runOneTest("nested_union_bar") }
- @Test def test_nested_union_foo(): Unit = { runner.runOneTest("nested_union_foo") }
+ @Test def test_nested_struct(): Unit = { runner.runOneTest("nested.struct") }
+ @Test def test_nested_struct_diag1(): Unit = { runner.runOneTest("nested.struct.diag1") }
+ @Test def test_nested_struct_diag2(): Unit = { runner.runOneTest("nested.struct.diag2") }
+ @Test def test_nested_struct_err1(): Unit = { runner.runOneTest("nested.struct.err1") }
+ @Test def test_nested_struct_err2(): Unit = { runner.runOneTest("nested.struct.err2") }
+ @Test def test_nested_union_bar(): Unit = { runner.runOneTest("nested.union.bar") }
+ @Test def test_nested_union_foo(): Unit = { runner.runOneTest("nested.union.foo") }
}