You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by sl...@apache.org on 2021/02/03 19:07:37 UTC
[incubator-daffodil] branch master updated: Update debugger support
of found delimiters/fields/diffs
This is an automated email from the ASF dual-hosted git repository.
slawrence pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-daffodil.git
The following commit(s) were added to refs/heads/master by this push:
new e29292b Update debugger support of found delimiters/fields/diffs
e29292b is described below
commit e29292b9e7e4d2e16deaaa342fc5a97176267ea6
Author: Steve Lawrence <sl...@apache.org>
AuthorDate: Tue Jan 26 14:45:55 2021 -0500
Update debugger support of found delimiters/fields/diffs
- Change how the debugger records the previous state. Currently it
copies the state from the "before" function, which is called at the
beginning of a parser. This meant that the "info diff" command only
ever showed the diff of a single parser, which could lead to missing
some differences in trace output. Instead, each time the debugger
pauses, we capture that state and use it as the previous state the
next time the debugger pauses.
- Refactor all debugger act commands to no longer accept a previous
state. There are only two commands that use this and they can both
access Debugger state to get the previous processor state when needed.
Greatly simplifies the debugger code.
- Refactor how diff's are calculated so that all the logic is moved into
the individual command objects that care about that piece of
information. Now, any info command that is "diffable" must implement
the InfoDiffable trait and the 'diff' function. The "info diff"
command now automatically finds all commands that implement this trait
and will call this diff function. This simplifies the "info diff"
command and makes it so it doesn't need to know anything about other
info commands or anything about the state.
- Creates a new InfoSimpleValue trait to be used for "info" commands that
only show a single value. This trait only requires implementation of
a single getSomeValue function, which is used to provide a default
implementation of the the act() and diff() functions. This reduces a
lot of boilerplate in a handful of simple info commands.
- Add diff support for "info hidden" using the new InfoSimpleValue trait
- Instead of "info foundDelimiter" showing both the found delimiter and
the found field, it now only shows the found delimiter. This also adds
a new "info foundField" command to show the found field that "info
foundDelimiter" used to show. This makes the code less complex and
gives the user more control over. Both commands implement the new
InfoSimpleValue trait, so now show up in "info diff" output. When
diffs are found, the output looks like this:
diff:
foundDelimiter: (no value) -> ,
foundField: (no value) -> smith
The above shows that a comma delimiter was found and that the field
preceding that delimiter was "smith".
- Add/tweak existing CLI debugger tests to improve test coverage related
to "info diff" command.
DAFFODIL-758
---
.../apache/daffodil/debugger/TestCLIDebugger.scala | 82 +++-
.../daffodil/debugger/InteractiveDebugger.scala | 447 +++++++++++----------
.../apache/daffodil/events/ParseEventHandler.scala | 8 +-
.../apache/daffodil/processors/DataProcessor.scala | 4 +-
.../daffodil/processors/ProcessorStateBases.scala | 27 +-
.../daffodil/processors/unparsers/UState.scala | 2 +
6 files changed, 327 insertions(+), 243 deletions(-)
diff --git a/daffodil-cli/src/it/scala/org/apache/daffodil/debugger/TestCLIDebugger.scala b/daffodil-cli/src/it/scala/org/apache/daffodil/debugger/TestCLIDebugger.scala
index d6df06f..3ff7f00 100644
--- a/daffodil-cli/src/it/scala/org/apache/daffodil/debugger/TestCLIDebugger.scala
+++ b/daffodil-cli/src/it/scala/org/apache/daffodil/debugger/TestCLIDebugger.scala
@@ -1217,7 +1217,7 @@ class TestCLIdebugger {
}
}
- @Test def test_CLI_Debugger_info_diff(): Unit = {
+ @Test def test_CLI_Debugger_info_diff_01(): Unit = {
val schemaFile = Util.daffodilPath("daffodil-test/src/test/resources/org/apache/daffodil/section07/variables/variables_01.dfdl.xsd")
val inputFile = Util.daffodilPath("daffodil-cli/src/it/resources/org/apache/daffodil/CLI/input/input1.txt")
val (testSchemaFile, testInputFile) = if (Util.isWindows) (Util.cmdConvert(schemaFile), Util.cmdConvert(inputFile)) else (schemaFile, inputFile)
@@ -1231,15 +1231,89 @@ class TestCLIdebugger {
shell.sendLine("display info diff")
shell.expect(contains("(debug)"))
shell.sendLine("step")
- shell.expect(contains("No differences"))
+ shell.expect(contains("(no differences)"))
shell.sendLine("step")
- shell.expect(contains("No differences"))
+ shell.expect(contains("(no differences)"))
shell.sendLine("step")
shell.expect(contains("variable: tns:v_with_default: 42 (default) -> 42 (read)"))
shell.sendLine("step")
shell.expect(contains("variable: tns:v_no_default: (undefined) -> 42 (set)"))
shell.sendLine("step")
- shell.expect(contains("No differences"))
+ shell.expect(contains("childIndex: 1 -> 2"))
+ shell.sendLine("step")
+ shell.expect(contains("variable: tns:v_no_default: 42 (set) -> 42 (read)"))
+ shell.sendLine("step")
+ shell.expect(contains("<d>42</d>"))
+ shell.expect(contains("<e>42</e>"))
+ } finally {
+ shell.close()
+ }
+ }
+
+ @Test def test_CLI_Debugger_info_diff_02(): Unit = {
+ val schemaFile = Util.daffodilPath("daffodil-test/src/test/resources/org/apache/daffodil/section06/entities/charClassEntities.dfdl.xsd")
+ val inputFile = Util.daffodilPath("daffodil-cli/src/it/resources/org/apache/daffodil/CLI/input/input1.txt")
+ val (testSchemaFile, testInputFile) = if (Util.isWindows) (Util.cmdConvert(schemaFile), Util.cmdConvert(inputFile)) else (schemaFile, inputFile)
+
+ val shell = if (Util.isWindows) Util.start("", envp = DAFFODIL_JAVA_OPTS) else Util.start("")
+
+ try {
+ val cmd = String.format("%s -d parse -s %s -r matrix %s", Util.binPath, testSchemaFile, testInputFile)
+ shell.sendLine(cmd)
+ shell.expect(contains("(debug)"))
+ shell.sendLine("display info diff")
+ shell.expect(contains("(debug)"))
+ shell.sendLine("step")
+ shell.sendLine("step")
+ shell.sendLine("step")
+ shell.sendLine("step")
+ shell.sendLine("step")
+ shell.sendLine("step")
+ shell.expect(contains("bitPosition: 0 -> 8"))
+ shell.expect(contains("foundDelimiter: (no value) -> ,"))
+ shell.expect(contains("foundField: (no value) -> 0"))
+ shell.sendLine("step")
+ shell.sendLine("step")
+ shell.expect(contains("childIndex: 1 -> 2"))
+ shell.expect(contains("groupIndex: 1 -> 2"))
+ shell.expect(contains("occursIndex: 1 -> 2"))
+ shell.sendLine("step")
+ shell.expect(contains("bitPosition: 8 -> 16"))
+ shell.expect(contains("foundDelimiter: , -> (no value)"))
+ shell.expect(contains("foundField: 0 -> (no value)"))
+ shell.sendLine("quit")
+ } finally {
+ shell.close()
+ }
+ }
+
+ @Test def test_CLI_Debugger_info_diff_03(): Unit = {
+ val schemaFile = Util.daffodilPath("daffodil-cli/src/it/resources/org/apache/daffodil/CLI/cli_schema.dfdl.xsd")
+ val inputFile = Util.daffodilPath("daffodil-cli/src/it/resources/org/apache/daffodil/CLI/input/input6.txt")
+ val (testSchemaFile, testInputFile) = if (Util.isWindows) (Util.cmdConvert(schemaFile), Util.cmdConvert(inputFile)) else (schemaFile, inputFile)
+
+ val shell = if (Util.isWindows) Util.start("", envp = DAFFODIL_JAVA_OPTS) else Util.start("")
+
+ try {
+ val cmd = String.format("%s -d parse -s %s -r e %s", Util.binPath, testSchemaFile, testInputFile)
+ shell.sendLine(cmd)
+ shell.expect(contains("(debug)"))
+ shell.sendLine("display info diff")
+ shell.expect(contains("(debug)"))
+ shell.sendLine("step")
+ shell.sendLine("step")
+ shell.expect(contains("hidden: false -> true"))
+ shell.sendLine("step")
+ shell.sendLine("step")
+ shell.sendLine("step")
+ shell.sendLine("step")
+ shell.sendLine("step")
+ shell.sendLine("step")
+ shell.sendLine("step")
+ shell.sendLine("step")
+ shell.sendLine("step")
+ shell.sendLine("step")
+ shell.expect(contains("hidden: true -> false"))
shell.sendLine("quit")
} finally {
shell.close()
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
index 35f8e31..0e55ea7 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
@@ -17,39 +17,40 @@
package org.apache.daffodil.debugger
-import org.apache.daffodil.exceptions.Assert
-import org.apache.daffodil.schema.annotation.props.gen.Representation
-import org.apache.daffodil.processors._
-import org.apache.daffodil.infoset._
-import org.apache.daffodil.processors.parsers._
-import org.apache.daffodil.xml.XMLUtils
-import org.apache.daffodil.xml.GlobalQName
-import org.apache.daffodil.xml.QName
import java.io.File
+
+import scala.collection.JavaConverters._
+
+import jline.console.completer.AggregateCompleter
import jline.console.completer.Completer
import jline.console.completer.StringsCompleter
-import jline.console.completer.AggregateCompleter
-import org.apache.daffodil.util.Enum
-import org.apache.daffodil.dsom.ExpressionCompilerClass
-import org.apache.daffodil.dpath.NodeInfo
+
+import org.apache.daffodil.BasicComponent
+import org.apache.daffodil.api.DaffodilTunables
import org.apache.daffodil.dpath.ExpressionEvaluationException
-import org.apache.daffodil.util.DPathUtil
-import org.apache.daffodil.util.Misc
-import org.apache.daffodil.oolag.ErrorsNotYetRecorded
-import org.apache.daffodil.processors.unparsers.UState
-import org.apache.daffodil.processors.unparsers.Unparser
+import org.apache.daffodil.dpath.NodeInfo
+import org.apache.daffodil.dsom.ExpressionCompilerClass
import org.apache.daffodil.dsom.RelativePathPastRootError
-import org.apache.daffodil.exceptions.UnsuppressableException
-import scala.collection.mutable
import org.apache.daffodil.dsom.RuntimeSchemaDefinitionError
-import org.apache.daffodil.util.Misc
+import org.apache.daffodil.exceptions.Assert
+import org.apache.daffodil.exceptions.UnsuppressableException
import org.apache.daffodil.infoset.InfosetElement
import org.apache.daffodil.infoset.XMLTextInfosetOutputter
-import org.apache.daffodil.processors.parsers.ConvertTextCombinatorParser
+import org.apache.daffodil.infoset._
+import org.apache.daffodil.oolag.ErrorsNotYetRecorded
import org.apache.daffodil.oolag.OOLAG._
-import scala.collection.JavaConverters._
-import org.apache.daffodil.api.DaffodilTunables
-import org.apache.daffodil.BasicComponent
+import org.apache.daffodil.processors._
+import org.apache.daffodil.processors.parsers.ConvertTextCombinatorParser
+import org.apache.daffodil.processors.parsers._
+import org.apache.daffodil.processors.unparsers.UState
+import org.apache.daffodil.processors.unparsers.Unparser
+import org.apache.daffodil.schema.annotation.props.gen.Representation
+import org.apache.daffodil.util.DPathUtil
+import org.apache.daffodil.util.Enum
+import org.apache.daffodil.util.Misc
+import org.apache.daffodil.xml.GlobalQName
+import org.apache.daffodil.xml.QName
+import org.apache.daffodil.xml.XMLUtils
abstract class InteractiveDebuggerRunner {
def init(id: InteractiveDebugger): Unit
@@ -136,12 +137,16 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
var debugState: DebugState.Type = DebugState.Pause
- override def init(parser: Parser): Unit = {
+ var previousProcessorState: StateForDebugger = _
+
+ override def init(state: PState, parser: Parser): Unit = {
runner.init(this)
+ previousProcessorState = state.copyStateForDebugger
}
- override def init(unparser: Unparser): Unit = {
+ override def init(state: UState, unparser: Unparser): Unit = {
runner.init(this)
+ previousProcessorState = state.copyStateForDebugger
}
override def fini(parser: Parser): Unit = {
@@ -152,11 +157,11 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
runner.fini
}
- def debugStep(before: StateForDebugger, after: ParseOrUnparseState, processor: Processor, ignoreBreakpoints: Boolean): Unit = {
+ def debugStep(state: ParseOrUnparseState, processor: Processor, ignoreBreakpoints: Boolean): Unit = {
debugState = debugState match {
- case _ if ((after.processorStatus ne Success) && DebuggerConfig.breakOnFailure) => DebugState.Pause
+ case _ if ((state.processorStatus ne Success) && DebuggerConfig.breakOnFailure) => DebugState.Pause
case DebugState.Continue | DebugState.Trace if !ignoreBreakpoints => {
- findBreakpoint(after, processor) match {
+ findBreakpoint(state, processor) match {
case Some(bp) => {
debugPrintln("breakpoint %s: %s %s".format(bp.id, bp.breakpoint, bp.condition.getOrElse("")))
DebugState.Pause
@@ -173,12 +178,12 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
val rawDisplays = dc.displays
val displays = rawDisplays.filter(_.enabled)
displays.foreach { d =>
- runCommand(d.cmd, before, after, processor)
+ runCommand(d.cmd, state, processor)
}
- if (after.processorStatus ne Success) {
+ if (state.processorStatus ne Success) {
debugPrintln("failure:")
- debugPrintln("%s".format(after.diagnostics.head.getMessage()), " ")
+ debugPrintln("%s".format(state.diagnostics.head.getMessage()), " ")
}
if (debugState == DebugState.Trace) {
@@ -190,8 +195,10 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
while (debugState == DebugState.Pause) {
val args = readCmd
- debugState = runCommand(args, before, after, processor)
+ debugState = runCommand(args, state, processor)
}
+
+ previousProcessorState = state.copyStateForDebugger
}
private def isInteresting(parser: Parser): Boolean = {
@@ -207,58 +214,35 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
}
override def startElement(state: PState, parser: Parser): Unit = {
- debugStep(state, state, parser, false)
+ debugStep(state, parser, false)
}
override def endElement(state: UState, unparser: Unparser): Unit = {
- debugStep(state, state, unparser, false)
+ debugStep(state, unparser, false)
}
- private val parseStack = new mutable.ArrayStack[(StateForDebugger, Parser)]
+ override def before(before: PState, parser: Parser): Unit = {}
- override def before(before: PState, parser: Parser): Unit = {
- if (isInteresting(parser)) {
- parseStack.push((before.copyStateForDebugger, parser))
- }
- }
- override def after(after: PState, parser: Parser): Unit = {
+ override def after(state: PState, parser: Parser): Unit = {
if (isInteresting(parser)) {
- val (before, beforeParser) = parseStack.pop
- Assert.invariant(beforeParser eq parser)
- debugStep(before, after, parser, DebuggerConfig.breakOnlyOnCreation)
+ debugStep(state, parser, DebuggerConfig.breakOnlyOnCreation)
}
}
- override def beforeRepetition(before: PState, processor: Parser): Unit = {
- parseStack.push((before.copyStateForDebugger, processor))
- }
+ override def beforeRepetition(before: PState, processor: Parser): Unit = {}
- override def afterRepetition(after: PState, processor: Parser): Unit = {
- val (_, beforeParser) = parseStack.pop
- Assert.invariant(beforeParser eq processor)
- }
+ override def afterRepetition(after: PState, processor: Parser): Unit = {}
private def isInteresting(unparser: Unparser): Boolean = {
true
}
- private val unparseStack = new mutable.ArrayStack[(StateForDebugger, Unparser)]
-
override def before(before: UState, unparser: Unparser): Unit = {
- if (isInteresting(unparser)) {
- unparseStack.push((before.copyStateForDebugger, unparser))
- }
- while (debugState == DebugState.Pause) {
- val args = readCmd
- debugState = runCommand(args, before, before, unparser)
- }
}
- override def after(after: UState, unparser: Unparser): Unit = {
+ override def after(state: UState, unparser: Unparser): Unit = {
if (isInteresting(unparser)) {
- val (before, beforeUnparser) = unparseStack.pop
- Assert.invariant(beforeUnparser eq unparser)
- debugStep(before, after, unparser, false)
+ debugStep(state, unparser, DebuggerConfig.breakOnlyOnCreation)
}
}
@@ -426,9 +410,9 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
foundBreakpoint
}
- private def runCommand(cmd: Seq[String], before: StateForDebugger, after: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ private def runCommand(cmd: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
try {
- DebugCommandBase(cmd, before, after, processor)
+ DebugCommandBase(cmd, state, processor)
} catch {
case e: DebugException => {
debugPrintln(e)
@@ -465,7 +449,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
}
/**********************************/
- /** Commands **/
+/** Commands **/
/**********************************/
abstract class DebugCommand {
@@ -476,14 +460,14 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
val subcommands: Seq[DebugCommand] = Seq()
val hidden = false
- def apply(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def apply(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
validate(args)
- act(args, prestate, state, processor)
+ act(args, state, processor)
}
def validate(args: Seq[String]): Unit
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type
override def equals(that: Any): Boolean = {
that match {
@@ -684,11 +668,11 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
override lazy val short = ""
override val subcommands = Seq(Break, Clear, Complete, Condition, Continue, Delete, Disable, Display, Enable, Eval, Help, History, Info, Quit, Set, Step, Trace)
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val subcmd = args.head
val subcmdArgs = args.tail
val subcmdActor = subcommands.find(_ == subcmd).get
- val newState = subcmdActor.act(subcmdArgs, prestate, state, processor)
+ val newState = subcmdActor.act(subcmdArgs, state, processor)
newState
}
@@ -715,7 +699,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|
|Example: break foo""".stripMargin
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val bp = new Breakpoint(DebuggerConfig.breakpointIndex, args.head)
DebuggerConfig.breakpoints += bp
debugPrintln("%s: %s".format(bp.id, bp.breakpoint))
@@ -732,7 +716,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|Clear the screen.""".stripMargin
override lazy val short = "cl"
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
print(27: Char)
print('[')
print("2J")
@@ -753,7 +737,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|breakpoints are ignored.""".stripMargin
override lazy val short = "comp"
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
DebuggerConfig.breakpoints.foreach(_.disable)
DebuggerConfig.displays.foreach(_.disable)
DebugState.Continue
@@ -790,7 +774,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
}
}
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val id = args.head.toInt
val expression = args.tail.mkString(" ")
val expressionWithBraces =
@@ -811,7 +795,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|Continue parsing the input data until a breakpoint is encountered. At
|which point, pause parsing and display a debugger console to the user.""".stripMargin
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
DebugState.Continue
}
}
@@ -827,10 +811,10 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
| delete display 1""".stripMargin
override val subcommands = Seq(DeleteBreakpoint, DeleteDisplay)
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val subcmd = args.head
val subcmdArgs = args.tail
- subcommands.find(_ == subcmd).get.act(subcmdArgs, prestate, state, processor)
+ subcommands.find(_ == subcmd).get.act(subcmdArgs, state, processor)
DebugState.Pause
}
@@ -843,7 +827,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|
|Example: delete breakpoint 1""".stripMargin
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val id = args.head.toInt
DebuggerConfig.breakpoints.find(_.id == id) match {
case Some(b) => DebuggerConfig.breakpoints -= b
@@ -863,7 +847,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|Example: delete display 1""".stripMargin
override lazy val short = "di"
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val id = args.head.toInt
DebuggerConfig.displays.find(d => d.id == id) match {
case Some(d) => DebuggerConfig.displays -= d
@@ -886,10 +870,10 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
override lazy val short = "dis"
override val subcommands = Seq(DisableBreakpoint, DisableDisplay)
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val subcmd = args.head
val subcmdArgs = args.tail
- subcommands.find(_ == subcmd).get.act(subcmdArgs, prestate, state, processor)
+ subcommands.find(_ == subcmd).get.act(subcmdArgs, state, processor)
DebugState.Pause
}
@@ -903,7 +887,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|
|Example: disable breakpoint 1""".stripMargin
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val id = args.head.toInt
DebuggerConfig.breakpoints.find(_.id == id) match {
case Some(b) => b.disable
@@ -924,7 +908,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|Example: disable display 1""".stripMargin
override lazy val short = "di"
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val id = args.head.toInt
DebuggerConfig.displays.find(_.id == id) match {
case Some(d) => d.disable
@@ -947,7 +931,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
override lazy val short = "di"
override val subcommands = Seq(Eval, Info, Clear)
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
DebuggerConfig.displays += new Display(DebuggerConfig.displayIndex, args)
DebuggerConfig.displayIndex += 1
DebugState.Pause
@@ -965,10 +949,10 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
| enable display 1""".stripMargin
override val subcommands = Seq(EnableBreakpoint, EnableDisplay)
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val subcmd = args.head
val subcmdArgs = args.tail
- subcommands.find(_ == subcmd).get.act(subcmdArgs, prestate, state, processor)
+ subcommands.find(_ == subcmd).get.act(subcmdArgs, state, processor)
DebugState.Pause
}
@@ -982,7 +966,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|
|Example: enable breakpoint 1""".stripMargin
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val id = args.head.toInt
DebuggerConfig.breakpoints.find(_.id == id) match {
case Some(b) => b.enable
@@ -1002,7 +986,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|
|Example: enable display 1""".stripMargin
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val id = args.head.toInt
DebuggerConfig.displays.find(_.id == id) match {
case Some(d) => d.enable
@@ -1029,7 +1013,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
}
}
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val expressionList = args
val expression = expressionList.mkString(" ")
@@ -1127,7 +1111,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
// no validation
}
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
DebugCommandBase.help(args)
DebugState.Pause
}
@@ -1146,7 +1130,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|Example: history
| history out.txt""".stripMargin
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
args.size match {
case 0 => {
debugPrintln("%s:".format(name))
@@ -1205,6 +1189,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
InfoDiff,
InfoDisplays,
InfoFoundDelimiter,
+ InfoFoundField,
InfoGroupIndex,
InfoHidden,
InfoInfoset,
@@ -1279,12 +1264,12 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
}
}
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val infocmds = buildInfoCommands(args)
infocmds.foreach { cmds =>
val cmd :: args = cmds
val action = subcommands.find(_ == cmd).get
- action.act(args, prestate, state, processor)
+ action.act(args, state, processor)
}
DebugState.Pause
}
@@ -1307,33 +1292,62 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
}
}
- object InfoBitLimit extends DebugCommand with DebugCommandValidateZeroArgs {
+ trait InfoDiffable {
+ /**
+ * Outputs any differences between previousProcessorState and state for the mixed in debugger command
+ *
+ * Differences should be displayed via the debugPrintln command. Output
+ * should include the command name and two space indentation (e.g. pass
+ * in " " as the second argument of debugPrintln).
+ *
+ * @return true if any differences were found and output, false otherwise
+ */
+ def diff(pre: StateForDebugger, post: StateForDebugger): Boolean
+ }
+
+ trait InfoSimpleValue[A] extends InfoDiffable { self: DebugCommand =>
+
+ def getSomeValue(state: StateForDebugger): Option[A]
+
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ val strValue = getSomeValue(state).map(_.toString).getOrElse("(no value)")
+ debugPrintln("%s: %s".format(self.name, strValue))
+ DebugState.Pause
+ }
+
+ def diff(pre: StateForDebugger, post: StateForDebugger): Boolean = {
+ val valPre = getSomeValue(pre)
+ val valPost = getSomeValue(post)
+ if (valPre != valPost) {
+ val strPre = valPre.map(_.toString).getOrElse("(no value)")
+ val strPost = valPost.map(_.toString).getOrElse("(no value)")
+ debugPrintln("%s: %s -> %s".format(self.name, strPre, strPost), " ")
+ true
+ } else {
+ false
+ }
+ }
+ }
+
+ object InfoBitLimit extends DebugCommand with DebugCommandValidateZeroArgs with InfoSimpleValue[Long] {
val name = "bitLimit"
override lazy val short = "bl"
val desc = "display the current bit limit"
val longDesc = desc
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
- if (state.bitLimit0b.isDefined) {
- debugPrintln("%s: %d".format(name, state.bitLimit0b.get))
- } else {
- debugPrintln("%s: no bit limit set".format(name))
- }
- DebugState.Pause
+
+ def getSomeValue(state: StateForDebugger): Option[Long] = {
+ if (state.bitLimit0b.isDefined) Some(state.bitLimit0b.get) else None
}
}
- object InfoBitPosition extends DebugCommand with DebugCommandValidateZeroArgs {
+ object InfoBitPosition extends DebugCommand with DebugCommandValidateZeroArgs with InfoSimpleValue[Long] {
val name = "bitPosition"
override lazy val short = "bp"
val desc = "display the current bit position"
val longDesc = desc
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
- if (state.bitPos != -1) {
- debugPrintln("%s: %d".format(name, state.bitPos))
- } else {
- debugPrintln("%s: no bit position set".format(name))
- }
- DebugState.Pause
+
+ def getSomeValue(state: StateForDebugger): Option[Long] = {
+ if (state.bitPos0b != -1) Some(state.bitPos0b) else None
}
}
@@ -1341,7 +1355,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
val name = "breakpoints"
val desc = "display the current breakpoints"
val longDesc = desc
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
if (DebuggerConfig.breakpoints.size == 0) {
debugPrintln("%s: no breakpoints set".format(name))
} else {
@@ -1357,18 +1371,14 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
}
}
- object InfoChildIndex extends DebugCommand with DebugCommandValidateZeroArgs {
+ object InfoChildIndex extends DebugCommand with DebugCommandValidateZeroArgs with InfoSimpleValue[Long] {
val name = "childIndex"
override lazy val short = "ci"
val desc = "display the current child index"
val longDesc = desc
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
- if (state.childPos != -1) {
- debugPrintln("%s: %d".format(name, state.childPos))
- } else {
- debugPrintln("%s: not a child element".format(name))
- }
- DebugState.Pause
+
+ def getSomeValue(state: StateForDebugger): Option[Long] = {
+ if (state.childPos != -1) Some(state.childPos) else None
}
}
@@ -1393,7 +1403,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
}
}
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
debugPrintln("%s:".format(name))
val rep = if (args.size > 0) {
args(0).toLowerCase match {
@@ -1420,7 +1430,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
DebuggerConfig.dataLength
}
- printData(rep, len, prestate, state, processor)
+ printData(rep, len, previousProcessorState, state, processor)
DebugState.Pause
}
}
@@ -1431,7 +1441,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
val longDesc = desc
override lazy val short = "ds"
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
debugPrintln("%s:".format(name))
state match {
@@ -1457,50 +1467,18 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
object InfoDiff extends DebugCommand with DebugCommandValidateZeroArgs {
val name = "diff"
override lazy val short = "diff"
- val desc = "display the differences from the previous state"
+ val desc = "display differences since the previous pause in the debugger"
val longDesc = desc
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+
+ private lazy val infoDiffables = Info.subcommands.collect { case diffable: InfoDiffable => diffable }
+
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
debugPrintln("%s:".format(name))
- var diff = false
- (prestate, state) match {
- case (prestate: StateForDebugger, state: ParseOrUnparseState) => {
- if (prestate.bytePos != state.bytePos) { debugPrintln("position (bytes): %d -> %d".format(prestate.bytePos, state.bytePos), " "); diff = true }
- if (prestate.bitLimit0b != state.bitLimit0b) { debugPrintln("bitLimit: %d -> %d".format(prestate.bitLimit0b, state.bitLimit0b), " "); diff = true }
- if (prestate.arrayPos != state.arrayPos) { debugPrintln("occursIndex: %d -> %d".format(prestate.arrayPos, state.arrayPos), " "); diff = true }
- if (prestate.groupPos != state.groupPos) { debugPrintln("groupIndex: %d -> %d".format(prestate.groupPos, state.groupPos), " "); diff = true }
- if (prestate.childPos != state.childPos) { debugPrintln("childIndex: %d -> %d".format(prestate.childPos, state.childPos), " "); diff = true }
- prestate.variableMap.qnames.foreach { qname =>
- val pre_instance = prestate.variableMap.find(qname).get
- val pre_value = pre_instance.value
- val pre_state = pre_instance.state
-
- val cur_instance = state.variableMap.find(qname).get
- val cur_value = cur_instance.value
- val cur_state = cur_instance.state
-
- if (pre_value != cur_value || pre_state != cur_state) {
- debugPrintln("variable: %s: %s -> %s".format(
- qname,
- InfoVariables.variableInstanceToDebugString(pre_instance),
- InfoVariables.variableInstanceToDebugString(cur_instance),
- ), " ")
- diff = true
- }
- }
- }
- case _ => // ok
+ val differencesExist = infoDiffables.foldLeft(false) { case (foundDiff, ic) =>
+ ic.diff(previousProcessorState, state) || foundDiff
}
- (prestate, state) match {
- case (prestate: StateForDebugger, state: PState) => {
- // nothing yet that is specific to Parser
- }
- case (prestate: StateForDebugger, state: UState) => {
- // nothing yet that is specific to Unparser
- }
- case _ => Assert.impossibleCase()
- }
- if (diff == false) {
- debugPrintln("No differences", " ")
+ if (!differencesExist) {
+ debugPrintln("(no differences)", " ")
}
DebugState.Pause
@@ -1512,7 +1490,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
override lazy val short = "di"
val desc = "display the current 'display' expressions"
val longDesc = desc
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
if (DebuggerConfig.displays.size == 0) {
debugPrintln("%s: no displays set".format(name))
} else {
@@ -1528,55 +1506,59 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
}
}
- object InfoFoundDelimiter extends DebugCommand with DebugCommandValidateZeroArgs {
+ object InfoFoundDelimiter extends DebugCommand with DebugCommandValidateZeroArgs with InfoSimpleValue[String] {
val name = "foundDelimiter"
override lazy val short = "fd"
val desc = "display the current found delimiter"
val longDesc = desc
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
- state match {
- case pstate: PState => {
- if (pstate.delimitedParseResult.isDefined) {
- val pr = pstate.delimitedParseResult.get
- debugPrintln("%s:".format(name))
- debugPrintln("foundField: %s".format(Misc.remapStringToVisibleGlyphs(pr.field.get)), " ")
- debugPrintln("foundDelimiter: %s".format(Misc.remapStringToVisibleGlyphs(pr.matchedDelimiterValue.get)), " ")
- } else {
- debugPrintln("%s: nothing found".format(name))
- }
- }
- case ustate: UState => {
- // TODO
- }
- case _ => Assert.impossibleCase()
+
+ def getSomeValue(state: StateForDebugger): Option[String] = {
+ if (state.delimitedParseResult.isDefined) {
+ val dpr = state.delimitedParseResult.get
+ val value = Misc.remapStringToVisibleGlyphs(dpr.matchedDelimiterValue.get)
+ Some(value)
+ } else {
+ None
}
- DebugState.Pause
}
}
- object InfoGroupIndex extends DebugCommand with DebugCommandValidateZeroArgs {
+ object InfoFoundField extends DebugCommand with DebugCommandValidateZeroArgs with InfoSimpleValue[String] {
+ val name = "foundField"
+ override lazy val short = "ff"
+ val desc = "display the current found field when delimiter scanning"
+ val longDesc = desc
+
+ def getSomeValue(state: StateForDebugger): Option[String] = {
+ if (state.delimitedParseResult.isDefined) {
+ val dpr = state.delimitedParseResult.get
+ val value = Misc.remapStringToVisibleGlyphs(dpr.field.get)
+ Some(value)
+ } else {
+ None
+ }
+ }
+ }
+
+ object InfoGroupIndex extends DebugCommand with DebugCommandValidateZeroArgs with InfoSimpleValue[Long] {
val name = "groupIndex"
override lazy val short = "gi"
val desc = "display the current group index"
val longDesc = desc
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
- if (state.groupPos != -1) {
- debugPrintln("%s: %d".format(name, state.groupPos))
- } else {
- debugPrintln("%s: not in a group".format(name))
- }
- DebugState.Pause
+
+ def getSomeValue(state: StateForDebugger): Option[Long] = {
+ if (state.groupPos != -1) Some(state.groupPos) else None
}
}
- object InfoHidden extends DebugCommand with DebugCommandValidateZeroArgs {
+ object InfoHidden extends DebugCommand with DebugCommandValidateZeroArgs with InfoSimpleValue[Boolean] {
val name = "hidden"
override lazy val short = "h"
val desc = "display whether or not we're within the nesting context of a hidden group"
val longDesc = desc
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
- debugPrintln("%s: %b".format(name, state.withinHiddenNest))
- DebugState.Pause
+
+ def getSomeValue(state: StateForDebugger): Some[Boolean] = {
+ Some(state.withinHiddenNest)
}
}
@@ -1585,7 +1567,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
val desc = "display the current infoset"
val longDesc = desc
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
debugPrintln("%s:".format(name))
if (state.hasInfoset) {
@@ -1625,18 +1607,14 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
}
}
- object InfoOccursIndex extends DebugCommand with DebugCommandValidateZeroArgs {
+ object InfoOccursIndex extends DebugCommand with DebugCommandValidateZeroArgs with InfoSimpleValue[Long] {
val name = "occursIndex"
override lazy val short = "oi"
val desc = "display the current array limit"
val longDesc = desc
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
- if (state.arrayPos != -1) {
- debugPrintln("%s: %d".format(name, state.arrayPos))
- } else {
- debugPrintln("%s: not in an array".format(name))
- }
- DebugState.Pause
+
+ def getSomeValue(state: StateForDebugger): Option[Long] = {
+ if (state.arrayPos != -1) Some(state.arrayPos) else None
}
}
@@ -1645,7 +1623,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
override lazy val short = "path"
val desc = "display the current schema component designator/path"
val longDesc = desc
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
debugPrintln("%s: %s".format(name, processor.context.path))
DebugState.Pause
}
@@ -1654,7 +1632,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
abstract class InfoProcessorBase extends DebugCommand with DebugCommandValidateZeroArgs {
val desc = "display the current Daffodil " + name
val longDesc = desc
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
debugPrintln("%s: %s".format(name, processor.toBriefXML(2))) // only 2 levels of output, please!
DebugState.Pause
}
@@ -1669,7 +1647,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
override lazy val short = "pou"
val desc = "display list of unresolved points of uncertainty"
val longDesc = desc
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
state match {
case state: PState => {
debugPrintln("%s:".format(name))
@@ -1692,7 +1670,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
override val name = "unparser"
} with InfoProcessorBase
- object InfoVariables extends DebugCommand {
+ object InfoVariables extends DebugCommand with InfoDiffable {
val name = "variables"
override lazy val short = "v"
val desc = "display in-scope state of variables"
@@ -1718,7 +1696,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
else "%s (%s)".format(vinst.value.value, state)
}
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val vmap = state.variableMap
val allQNames = vmap.qnames
val qnamesToPrint =
@@ -1738,6 +1716,29 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
DebugState.Pause
}
+
+ def diff(pre: StateForDebugger, post: StateForDebugger): Boolean = {
+ pre.variableMap.qnames.foldLeft(false) { case (foundDiff, qname) =>
+ val pre_instance = pre.variableMap.find(qname).get
+ val pre_value = pre_instance.value
+ val pre_state = pre_instance.state
+
+ val cur_instance = post.variableMap.find(qname).get
+ val cur_value = cur_instance.value
+ val cur_state = cur_instance.state
+
+ if (pre_value != cur_value || pre_state != cur_state) {
+ debugPrintln("variable: %s: %s -> %s".format(
+ qname,
+ variableInstanceToDebugString(pre_instance),
+ variableInstanceToDebugString(cur_instance),
+ ), " ")
+ foundDiff || true
+ } else {
+ foundDiff
+ }
+ }
+ }
}
}
@@ -1748,7 +1749,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|
|Immediately abort all processing.""".stripMargin
override lazy val short = "q"
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
sys.exit(1)
}
}
@@ -1765,10 +1766,10 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
override val subcommands = Seq(SetBreakOnFailure, SetBreakOnlyOnCreation, SetDataLength, SetInfosetLines, SetInfosetParents, SetRemoveHidden, SetRepresentation, SetWrapLength)
override lazy val short = "set"
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val subcmd = args.head
val subcmdArgs = args.tail
- subcommands.find(_ == subcmd).get.act(subcmdArgs, prestate, state, processor)
+ subcommands.find(_ == subcmd).get.act(subcmdArgs, state, processor)
DebugState.Pause
}
@@ -1785,7 +1786,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|Example: set breakOnlyOnCreation false""".stripMargin
override lazy val short = "booc"
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val state = args.head
DebuggerConfig.breakOnlyOnCreation =
if (state == "true" || state == "1") {
@@ -1810,7 +1811,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|Example: set breakOnFailure true""".stripMargin
override lazy val short = "bof"
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val state = args.head
DebuggerConfig.breakOnFailure =
if (state == "true" || state == "1") {
@@ -1835,7 +1836,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
| set dataLength -1""".stripMargin
override lazy val short = "dl"
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
DebuggerConfig.dataLength = args.head.toInt
DebugState.Pause
}
@@ -1854,7 +1855,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|Example: set infosetLines 25""".stripMargin
override lazy val short = "il"
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
DebuggerConfig.infosetLines = args.head.toInt
DebugState.Pause
}
@@ -1873,7 +1874,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|Example: set infosetParents 2""".stripMargin
override lazy val short = "ip"
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
DebuggerConfig.infosetParents = args.head.toInt
DebugState.Pause
}
@@ -1892,7 +1893,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|Example: set removeHidden true""".stripMargin
override lazy val short = "rh"
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
val state = args.head
DebuggerConfig.removeHidden =
if (state == "true" || state == "1") {
@@ -1928,7 +1929,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
}
}
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
DebuggerConfig.representation = args.head.toLowerCase match {
case "text" => Representation.Text
case "binary" => Representation.Binary
@@ -1950,7 +1951,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
| set wrapLength -1""".stripMargin
override lazy val short = "wl"
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
DebuggerConfig.wrapLength = args.head.toInt
DebugState.Pause
}
@@ -1964,7 +1965,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|
|Perform a single parse action, pause parsing, and display a debugger
|prompt.""".stripMargin
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
DebugState.Step
}
}
@@ -1978,7 +1979,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
|while running display commands after every parse step. When a
|breakpoint is encountered, pause parsing and display a debugger
|console to the user.""".stripMargin
- def act(args: Seq[String], prestate: StateForDebugger, state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
+ def act(args: Seq[String], state: ParseOrUnparseState, processor: Processor): DebugState.Type = {
DebugState.Trace
}
}
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/events/ParseEventHandler.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/events/ParseEventHandler.scala
index 4426a5d..61eeba4 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/events/ParseEventHandler.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/events/ParseEventHandler.scala
@@ -34,7 +34,7 @@ trait EventHandler {
/**
* Parser Events
*/
- def init(processor: Parser): Unit = {
+ def init(state: PState, processor: Parser): Unit = {
//do nothing
}
@@ -77,7 +77,7 @@ trait EventHandler {
/**
* Unparser Events
*/
- def init(processor: Unparser): Unit = {
+ def init(state: UState, processor: Unparser): Unit = {
//do nothing
}
@@ -142,7 +142,7 @@ trait MultipleEventHandler extends EventHandler with Serializable {
/**
* Parser Events
*/
- override def init(processor: Parser): Unit = { if (!(handlers eq Nil)) handlers.foreach { _.init(processor) } }
+ override def init(state: PState, processor: Parser): Unit = { if (!(handlers eq Nil)) handlers.foreach { _.init(state, processor) } }
override def before(state: PState, processor: Parser): Unit = { if (!(handlers eq Nil)) handlers.foreach { _.before(state, processor) } }
@@ -173,7 +173,7 @@ trait MultipleEventHandler extends EventHandler with Serializable {
/**
* Unparser Events
*/
- override def init(processor: Unparser): Unit = { if (!(handlers eq Nil)) handlers.foreach { _.init(processor) } }
+ override def init(state: UState, processor: Unparser): Unit = { if (!(handlers eq Nil)) handlers.foreach { _.init(state, processor) } }
override def before(state: UState, processor: Unparser): Unit = { if (!(handlers eq Nil)) handlers.foreach { _.before(state, processor) } }
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/DataProcessor.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/DataProcessor.scala
index a8ea86a..3f8c9f9 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/DataProcessor.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/DataProcessor.scala
@@ -434,7 +434,7 @@ class DataProcessor private (
addEventHandler(debugger)
state.notifyDebugging(true)
}
- state.dataProc.get.init(ssrd.parser)
+ state.dataProc.get.init(state, ssrd.parser)
doParse(ssrd.parser, state)
val pr = new ParseResult(this, state)
if (!pr.isProcessingError) {
@@ -574,7 +574,7 @@ class DataProcessor private (
addEventHandler(debugger)
unparserState.notifyDebugging(true)
}
- unparserState.dataProc.get.init(ssrd.unparser)
+ unparserState.dataProc.get.init(unparserState, ssrd.unparser)
out.setPriorBitOrder(ssrd.elementRuntimeData.defaultBitOrder)
doUnparse(unparserState)
unparserState.evalSuspensions(isFinal = true)
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/ProcessorStateBases.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/ProcessorStateBases.scala
index 2b0b99f..dce06e7 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/ProcessorStateBases.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/ProcessorStateBases.scala
@@ -71,23 +71,27 @@ import org.apache.daffodil.dsom.DPathCompileInfo
* contains member functions for everything the debugger needs to be able to observe.
*/
trait StateForDebugger {
- def bytePos: Long
+ def currentLocation: DataLocation
+ def bitPos0b: Long
+ def bitLimit0b: MaybeULong
def childPos: Long
def groupPos: Long
- def currentLocation: DataLocation
def arrayPos: Long
- def bitLimit0b: MaybeULong
def variableMap: VariableMap
+ def delimitedParseResult: Maybe[dfa.ParseResult]
+ def withinHiddenNest: Boolean
}
case class TupleForDebugger(
- val bytePos: Long,
+ val currentLocation: DataLocation,
+ val bitPos0b: Long,
+ val bitLimit0b: MaybeULong,
val childPos: Long,
val groupPos: Long,
- val currentLocation: DataLocation,
val arrayPos: Long,
- val bitLimit0b: MaybeULong,
- val variableMap: VariableMap)
+ val variableMap: VariableMap,
+ val delimitedParseResult: Maybe[dfa.ParseResult],
+ val withinHiddenNest: Boolean)
extends StateForDebugger
trait SetProcessorMixin {
@@ -427,13 +431,15 @@ abstract class ParseOrUnparseState protected (
def copyStateForDebugger = {
TupleForDebugger(
- bytePos,
+ currentLocation,
+ bitPos0b,
+ bitLimit0b,
childPos,
groupPos,
- currentLocation,
arrayPos,
- bitLimit0b,
variableMap.copy(), // deep copy since variableMap is mutable
+ delimitedParseResult,
+ withinHiddenNest,
)
}
@@ -564,6 +570,7 @@ final class CompileState(tci: DPathCompileInfo, maybeDataProc: Maybe[DataProcess
def dataStream = Nope
def groupPos: Long = 0L
def hasInfoset: Boolean = infoset_.isDefined
+ def delimitedParseResult = Nope
private lazy val infoset_ : Maybe[DIElement] = Nope
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/unparsers/UState.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/unparsers/UState.scala
index 1fb399f..617f484 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/unparsers/UState.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/unparsers/UState.scala
@@ -352,6 +352,8 @@ abstract class UState(
}
final val releaseUnneededInfoset: Boolean = !areDebugging && tunable.releaseUnneededInfoset
+
+ def delimitedParseResult = Nope
}
/**