mbeckerle closed pull request #102: Added tests that exercise ambiguous
separator/terminator case.
URL: https://github.com/apache/incubator-daffodil/pull/102
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/Runtime.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/Runtime.scala
index 5e3a67eac..4235be313 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/Runtime.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/Runtime.scala
@@ -220,25 +220,28 @@ class DataProcessor(val ssrd: SchemaSetRuntimeData)
}
private def doParse(p: Parser, state: PState) {
+ var wasThrow = true
try {
- this.startElement(state, p)
- p.parse1(state)
- this.endElement(state, p)
- //
- // After the end of all processing, we still call things that ask for the
- // ERD, and expect to find it on the processor.context. If we don't set
- // this, then the processor.context is Nope (because it is set on the
- // way into a parser, and unset back when a parser unwinds). We
- // want it to do this wind/unwind, but here at the ultimate top
- // level we want to defeat that final unwind
- // so that subsequent use of the state can generally work and have a
context.
- //
- state.setMaybeProcessor(Maybe(p))
+ try {
+ this.startElement(state, p)
+ p.parse1(state)
+ this.endElement(state, p)
+ //
+ // After the end of all processing, we still call things that ask for
the
+ // ERD, and expect to find it on the processor.context. If we don't set
+ // this, then the processor.context is Nope (because it is set on the
+ // way into a parser, and unset back when a parser unwinds). We
+ // want it to do this wind/unwind, but here at the ultimate top
+ // level we want to defeat that final unwind
+ // so that subsequent use of the state can generally work and have a
context.
+ //
+ state.setMaybeProcessor(Maybe(p))
+
+ wasThrow = false
+ } finally {
+ state.verifyFinalState(wasThrow)
+ }
- /* Verify that all stacks are empty */
- Assert.invariant(state.mpstate.arrayIndexStack.length == 1)
- Assert.invariant(state.mpstate.groupIndexStack.length == 1)
- Assert.invariant(state.mpstate.childIndexStack.length == 1)
} catch {
// technically, runtime shouldn't throw. It's really too heavyweight a
construct. And "failure"
// when parsing isn't exceptional, it's routine behavior. So ought not
be implemented via an
@@ -278,8 +281,6 @@ class DataProcessor(val ssrd: SchemaSetRuntimeData)
}
}
- state.dataInputStream.inputSource.compact
- state.dataInputStream.validateFinalStreamState
}
def unparse(inputter: InfosetInputter, output: DFDL.Output):
DFDL.UnparseResult = {
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PState.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PState.scala
index 35be2a07c..7c8746b0a 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PState.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PState.scala
@@ -125,15 +125,21 @@ class MPState private () {
val escapeSchemeEVCache = new MStackOfMaybe[EscapeSchemeParserHelper]
- //var wasAnyArrayElementNonZeroLength = false
- //var wasLastArrayElementZeroLength = true
-
private def init {
arrayIndexStack.push(1L)
groupIndexStack.push(1L)
childIndexStack.push(1L)
delimitersLocalIndexStack.push(-1)
}
+
+ def verifyFinalState(): Unit = {
+ // The current values of the top of these stacks might have
+ // changed, but the fact that they are just 1 deep should be restored.
+ Assert.invariant(arrayIndexStack.length == 1)
+ Assert.invariant(groupIndexStack.length == 1)
+ Assert.invariant(childIndexStack.length == 1)
+ Assert.invariant(delimitersLocalIndexStack.length == 1)
+ }
}
final class PState private (
@@ -323,6 +329,26 @@ final class PState private (
}
override lazy val (regexMatchBuffer, regexMatchBitPositionBuffer) =
dataProcArg.regexMatchState.get
+
+ /**
+ * Verify that the state is left where we expect it to be after
+ * a normal parse. I.e., stacks have been popped back to their original
state,
+ * pools - all items returned, etc.
+ *
+ * If for some reason parsing ends with a throw (not supposed to, but just
if)
+ * then all bets are off, so this must be called ONLY on a normal return
from parse call.
+ * That is, the parse can succeed or fail with diagnostics, but it must have
returned normally.
+ */
+ def verifyFinalState(wasThrow: Boolean): Unit = {
+ if (!wasThrow) {
+ Assert.invariant(this.discriminatorStack.length == 1)
+ mpstate.verifyFinalState()
+ }
+ // These we check regardless of throw or not.
+ markPool.finalCheck
+ dataInputStream.inputSource.compact // discard any storage that can be
freed.
+ dataInputStream.validateFinalStreamState
+ }
}
object PState {
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/section16/array_optional_elem/ArrayOptionalElem.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/section16/array_optional_elem/ArrayOptionalElem.tdml
index 136148a78..1d6627f92 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/section16/array_optional_elem/ArrayOptionalElem.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/section16/array_optional_elem/ArrayOptionalElem.tdml
@@ -17,9 +17,12 @@
-->
<tdml:testSuite suiteName="Array-OptionalElemTests"
- description="Section 16 - Arrays and Optional Elements"
xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"
- xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ct="http://w3.ibm.com/xmlns/dfdl/ctInfoset"
+ description="Section 16 - Arrays and Optional Elements"
+ xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"
+ xmlns:fn="http://www.w3.org/2005/xpath-functions"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ex="http://example.com"
xmlns:daf="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext"
defaultRoundTrip="true">
@@ -667,8 +670,68 @@
</xs:sequence>
</xs:complexType>
</xs:element>
+
+ <xs:element name="ambigSep">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="a" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:sequence>
+ <!--
+ Point of this discriminator is to make sure it doesn't
interfere
+ with the point-of-uncertainty associated with separated
sequence
+ elements below.
+ -->
+ <xs:annotation><xs:appinfo source="http://www.ogf.org/dfdl/">
+ <dfdl:discriminator>{ fn:true() }</dfdl:discriminator>
+ </xs:appinfo></xs:annotation>
+ </xs:sequence>
+ <xs:sequence dfdl:separator=":" dfdl:terminator="::"
+ dfdl:separatorPosition="infix">
+ <xs:element name="x" type="xs:int" minOccurs="0"
maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
</tdml:defineSchema>
+
+ <tdml:parserTestCase name="ambigSep1" root="ambigSep"
+ model="array-ockImplicitSeparators.dfdl.xsd"
+ roundTrip="onePass"
+ description="test that separator can be prefix of terminator, yet the
longest match works."
+ >
+ <tdml:document><![CDATA[1:2:3::]]></tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:ambigSep>
+ <a>
+ <x>1</x>
+ <x>2</x>
+ <x>3</x>
+ </a>
+ </ex:ambigSep>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
+ <tdml:parserTestCase name="ambigSep2" root="ambigSep"
+ model="array-ockImplicitSeparators.dfdl.xsd"
+ roundTrip="onePass"
+ description="test that separator can be prefix of terminator, yet the
longest match works."
+ >
+ <tdml:document><![CDATA[::]]></tdml:document>
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <ex:ambigSep><a></a></ex:ambigSep>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
<tdml:parserTestCase name="occursCountKindImplicitSeparators01a"
root="te_root"
model="array-ockImplicitSeparators.dfdl.xsd"
diff --git
a/daffodil-test/src/test/scala/org/apache/daffodil/section16/array_optional_elem/TestArrayOptionalElem.scala
b/daffodil-test/src/test/scala/org/apache/daffodil/section16/array_optional_elem/TestArrayOptionalElem.scala
index de4a50f24..601111755 100644
---
a/daffodil-test/src/test/scala/org/apache/daffodil/section16/array_optional_elem/TestArrayOptionalElem.scala
+++
b/daffodil-test/src/test/scala/org/apache/daffodil/section16/array_optional_elem/TestArrayOptionalElem.scala
@@ -84,4 +84,8 @@ class TestArrayOptionalElem {
@Test def test_occursCountKindImplicitSeparators04() {
runner.runOneTest("occursCountKindImplicitSeparators04") }
@Test def test_occursCountKindImplicitSeparators05() {
runner.runOneTest("occursCountKindImplicitSeparators05") }
@Test def test_occursCountKindImplicitSeparatorsUnparser() {
runner.runOneTest("occursCountKindImplicitSeparatorsUnparser") }
+
+ @Test def test_ambigSep1() { runner.runOneTest("ambigSep1") }
+ @Test def test_ambigSep2() { runner.runOneTest("ambigSep2") }
+
}
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services