[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[COMMITTED] poke: new command `sdiff' for structured binary diffs
From: |
Jose E. Marchesi |
Subject: |
[COMMITTED] poke: new command `sdiff' for structured binary diffs |
Date: |
Sun, 20 Feb 2022 21:50:31 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) |
This commit introduces a new poke command to generate structured
binary diffs.
2022-02-20 Jose E. Marchesi <jemarch@gnu.org>
* doc/poke.texi (Array Attributes): Update accordingly.
* poke/Makefile.am (dist_pkgdata_DATA): Add pk-diff.pk.
* poke/pk-diff.pk: New file.
* poke/pk-cmd.pk: Load pk-diff.pk.
* etc/poke-dark.css (.diff-plus): New class.
(.diff-minus): Likewise.
(.diff-thunk-header): Likewise.
* etc/poke-bright.css (.diff-minus): Likewise.
(.diff-minus): Likewise.
(.diff-thunk-header): Likewise.
* testsuite/poke.cmd/sdiff-1.pk: New test.
* testsuite/poke.cmd/sdiff-2.pk: Likewise.
* testsuite/poke.cmd/sdiff-3.pk: Likewise.
* testsuite/poke.cmd/sdiff-4.pk: Likewise.
* testsuite/poke.cmd/sdiff-5.pk: Likewise.
* testsuite/poke.cmd/sdiff-6.pk: Likewise.
* testsuite/poke.cmd/sdiff-7.pk: Likewise.
* testsuite/poke.cmd/sdiff-8.pk: Likewise.
* testsuite/Makefile.am (EXTRA_DIST): Add new tests.
---
ChangeLog | 23 +++
doc/poke.texi | 34 ++++-
etc/poke-bright.css | 4 +
etc/poke-dark.css | 4 +
poke/Makefile.am | 2 +-
poke/pk-cmd.pk | 1 +
poke/pk-diff.pk | 333 ++++++++++++++++++++++++++++++++++++++++++
testsuite/Makefile.am | 8 +
testsuite/poke.cmd/sdiff-1.pk | 13 ++
testsuite/poke.cmd/sdiff-2.pk | 13 ++
testsuite/poke.cmd/sdiff-3.pk | 13 ++
testsuite/poke.cmd/sdiff-4.pk | 13 ++
testsuite/poke.cmd/sdiff-5.pk | 13 ++
testsuite/poke.cmd/sdiff-6.pk | 17 +++
testsuite/poke.cmd/sdiff-7.pk | 17 +++
testsuite/poke.cmd/sdiff-8.pk | 14 ++
testsuite/poke.repl/repl.exp | 2 +-
17 files changed, 520 insertions(+), 4 deletions(-)
create mode 100644 poke/pk-diff.pk
create mode 100644 testsuite/poke.cmd/sdiff-1.pk
create mode 100644 testsuite/poke.cmd/sdiff-2.pk
create mode 100644 testsuite/poke.cmd/sdiff-3.pk
create mode 100644 testsuite/poke.cmd/sdiff-4.pk
create mode 100644 testsuite/poke.cmd/sdiff-5.pk
create mode 100644 testsuite/poke.cmd/sdiff-6.pk
create mode 100644 testsuite/poke.cmd/sdiff-7.pk
create mode 100644 testsuite/poke.cmd/sdiff-8.pk
diff --git a/ChangeLog b/ChangeLog
index ca18cb55..41481880 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,28 @@
2022-02-20 Jose E. Marchesi <jemarch@gnu.org>
+ * doc/poke.texi (sdiff): Sketch of section.
+ * poke/Makefile.am (dist_pkgdata_DATA): Add pk-diff.pk.
+ * poke/pk-diff.pk: New file.
+ * poke/pk-cmd.pk: Load pk-diff.pk.
+ * etc/poke-dark.css (.diff-plus): New class.
+ (.diff-minus): Likewise.
+ (.diff-thunk-header): Likewise.
+ * etc/poke-bright.css (.diff-minus): Likewise.
+ (.diff-minus): Likewise.
+ (.diff-thunk-header): Likewise.
+ * testsuite/poke.cmd/sdiff-1.pk: New test.
+ * testsuite/poke.cmd/sdiff-2.pk: Likewise.
+ * testsuite/poke.cmd/sdiff-3.pk: Likewise.
+ * testsuite/poke.cmd/sdiff-4.pk: Likewise.
+ * testsuite/poke.cmd/sdiff-5.pk: Likewise.
+ * testsuite/poke.cmd/sdiff-6.pk: Likewise.
+ * testsuite/poke.cmd/sdiff-7.pk: Likewise.
+ * testsuite/poke.cmd/sdiff-8.pk: Likewise.
+ * testsuite/poke.repl/repl.exp: Update test.
+ * testsuite/Makefile.am (EXTRA_DIST): Add new tests.
+
+2022-02-20 Jose E. Marchesi <jemarch@gnu.org>
+
* libpoke/pkl-tab.y: Fix precedence of EXCOND.
2022-02-18 Jose E. Marchesi <jemarch@gnu.org>
diff --git a/doc/poke.texi b/doc/poke.texi
index 8ec52406..b01c490f 100644
--- a/doc/poke.texi
+++ b/doc/poke.texi
@@ -208,6 +208,7 @@ Commands
* dump:: Binary dumps.
* copy:: Copying data around.
* save:: Save data into a file.
+* sdiff:: Comparing mapped values byte by byte.
* extract:: Extract contents of values to buffers.
* scrabble:: Scrabble memory chunks based on patterns.
@@ -8716,6 +8717,7 @@ The @code{.quit} command behaves exactly like
@code{.exit}.
* dump:: Binary dumps.
* copy:: Copying data around.
* save:: Save data into a file.
+* sdiff:: Comparing mapped values byte by byte.
* extract:: Extract contents of values to memory IOS.
* scrabble:: Scrabble memory chunks based on patterns.
@end menu
@@ -8938,6 +8940,34 @@ before starting writing. If the argument
@command{append} is
set as true, however, it will append to the existing contents of the
file. In this case, the file should exist.
+@node sdiff
+@section @command{sdiff}
+@cindex @command{sdiff}
+
+The @command{sdiff} command provides structured byte differences
+between two mapped values.
+
+This command has the following synopsis:
+
+@example
+sdiff :a @var{any} :b @var{any} [:group_by @var{offset}] \
+ [:values @var{bool}]
+@end example
+
+@noindent
+Where @var{:a} and @var{:b} are two mapped values of the same type.
+
+By default, the bytes are shown in the diff separated by white
+characters. You can alter this behaviour using the @code{group_by}
+parameter.
+
+If @var{values} is true, then include field interpreted values in the
+diff output.
+
+If the two values are not mapped, this command raises @code{E_no_map}.
+If the two values are not of the same type, the output will probably
+not be meaningful.
+
@node extract
@section @command{extract}
@cindex @command{extract}
@@ -8945,7 +8975,7 @@ file. In this case, the file should exist.
Use the @command{extract} command in order to create a temporary
memory IO space with the contents of a mapped value.
-This command the has the following synopsis.
+This command has the following synopsis.
@example
extract :val @var{val} :to @var{ios_name}
@@ -10515,7 +10545,7 @@ Examples:
If the provided index is out of bounds then @code{E_out_of_bounds} is
raised.
@item ename (@var{idx})
-The string @code{".[@var{idx}]"}.
+The string @code{"[@var{idx}]"}.
If the provided index is out of bounds then @code{E_out_of_bounds} is
raised.
diff --git a/etc/poke-bright.css b/etc/poke-bright.css
index f4701d23..2371507a 100644
--- a/etc/poke-bright.css
+++ b/etc/poke-bright.css
@@ -27,6 +27,10 @@
.dump-ascii { color : brown; }
.dump-unknown { color : yellow; }
+.diff-thunk-header { font-weight: bold; }
+.diff-minus { color : red; }
+.diff-plus { color : green; }
+
/* Classes for pickles in pickles/ */
.leb128 { color : grey; }
diff --git a/etc/poke-dark.css b/etc/poke-dark.css
index b1c9bfef..e1fff1dc 100644
--- a/etc/poke-dark.css
+++ b/etc/poke-dark.css
@@ -27,6 +27,10 @@
.dump-ascii { color : brown; }
.dump-unknown { color : yellow; }
+.diff-thunk-header { font-weight: bold; }
+.diff-minus { color : red; }
+.diff-plus { color : green; }
+
/* Classes for pickles in pickles/ */
.leb128 { color : grey; }
diff --git a/poke/Makefile.am b/poke/Makefile.am
index c5b4e634..f5d6a960 100644
--- a/poke/Makefile.am
+++ b/poke/Makefile.am
@@ -26,7 +26,7 @@ BUILT_SOURCES =
EXTRA_DIST =
-dist_pkgdata_DATA = pk-cmd.pk pk-dump.pk pk-save.pk pk-copy.pk \
+dist_pkgdata_DATA = pk-cmd.pk pk-dump.pk pk-save.pk pk-copy.pk pk-diff.pk \
pk-extract.pk pk-scrabble.pk poke.pk pk-settings.pk \
pk-help.pk pk-map.pk pk-table.pk pk-info.pk
diff --git a/poke/pk-cmd.pk b/poke/pk-cmd.pk
index 4eacd48b..d5db0958 100644
--- a/poke/pk-cmd.pk
+++ b/poke/pk-cmd.pk
@@ -23,3 +23,4 @@ load "pk-copy.pk";
load "pk-save.pk";
load "pk-extract.pk";
load "pk-scrabble.pk";
+load "pk-diff.pk";
diff --git a/poke/pk-diff.pk b/poke/pk-diff.pk
new file mode 100644
index 00000000..d6e1e18b
--- /dev/null
+++ b/poke/pk-diff.pk
@@ -0,0 +1,333 @@
+/* pk-diff.pk - Home of the `sdiff' and `bdiff' commands. */
+
+/* Copyright (C) 2022 Jose E. Marchesi */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+var pk_diff_group_by = 1#B;
+var pk_sdiff_print_values = 1;
+
+pk_help_add_topic
+:entry Poke_HelpEntry {
+ category = "commands",
+ topic = "sdiff",
+ summary = "structured binary diff of two mapped values",
+ description= format ("
+Synopsis:
+
+ sdiff :a VAL :b VAL [:values BOOL] [:group_by OFFSET]
+
+Arguments:
+
+ :a (any)
+ First mapped value whose bytes are compared.
+
+ :b (any)
+ Second mapped value whose bytes are compared.
+
+ :values (bool)
+ Whether to include interpreted values in the output.
+ Defaults to %v.
+
+ :group_by (int)
+ How are bytes grouped together in the output. Defaults to
+ `pk_diff_group_by', initially %v.
+
+Note that for the differences to make sense, both values A and B
+should be of the same type.
+
+If any of the specified values are not mapped then `sdiff' raises an
+E_map exception.
+
+See `.doc sdiff' for more information.",
+ pk_sdiff_print_values,
+ pk_diff_group_by),
+ };
+
+var PK_THUNK_ADD = 1;
+var PK_THUNK_REM = 2;
+
+type Pk_Diff_Thunk =
+ struct
+ {
+ type Pk_Diff_Thunk_Line =
+ struct
+ {
+ int kind : kind in [PK_THUNK_ADD, PK_THUNK_REM];
+ string data;
+ string name;
+ string value;
+ };
+
+ int emit_values_p;
+ offset<int,B> group_by = 1#B;
+
+ var A = 0, B = 1;
+ offset<uint<64>,B>[2] offset;
+ offset<uint<64>,B>[2] size;
+ Pk_Diff_Thunk_Line[] lines;
+
+ method reset = (offset<uint<64>,B> aoff = 0#B,
+ offset<uint<64>,B> asiz = 0#B,
+ offset<uint<64>,B> boff = 0#B,
+ offset<uint<64>,B> bsiz = 0#B) void:
+ {
+ offset[A] = aoff;
+ offset[B] = boff;
+ size[A] = asiz;
+ size[B] = bsiz;
+ lines = Pk_Diff_Thunk_Line[]();
+ }
+
+ method append_line = (int kind,
+ byte[] bytes,
+ string name = "",
+ string value = "") void:
+ {
+ fun format_bytes = (byte[] bytes) string:
+ {
+ var x = 1#B;
+ var s = "";
+
+ for (b in bytes)
+ {
+ s += format ("%u8x", b);
+ if (x++ % group_by == 0#B)
+ s += " ";
+ }
+ return s;
+ }
+
+ lines += [Pk_Diff_Thunk_Line { kind = kind,
+ data = format_bytes (bytes),
+ name = name,
+ value = value }];
+ }
+
+ method print_thunk = void:
+ {
+ if (lines'length == 0)
+ return;
+
+ var a_region
+ = size[A] > 0#B ? format ("0x%u8x+%u64d", offset[A]/#B, size[A]/#B) :
"";
+ var b_region
+ = size[B] > 0#B ? format ("0x%u8x+%u64d", offset[B]/#B, size[B]/#B) :
"";
+
+ term_begin_class ("diff-thunk-header");
+ printf ("@@ %s,%s @@\n", a_region, b_region);
+ term_end_class ("diff-thunk-header");
+ var table = Pk_Table { num_columns = emit_values_p ? 3 : 2 };
+ for (line in lines)
+ {
+ table.row (line.kind == PK_THUNK_ADD ? "diff-plus" : "diff-minus");
+ table.column ((line.kind == PK_THUNK_ADD ? "+" : "-") + line.data);
+ table.column (line.name);
+ if (emit_values_p)
+ table.column (line.value);
+ }
+ table.print_table;
+ }
+
+ method change = (offset<uint<64>,B> aoff, offset<uint<64>,B> asiz,
+ offset<uint<64>,B> boff, offset<uint<64>,B> bsiz,
+ byte[] abytes, byte[] bbytes,
+ string aname = "", string bname = "",
+ string avalue = "", string bvalue = "") void:
+ {
+ if (aoff == offset[A] + size[A]
+ && boff == offset[B] + size[B])
+ {
+ size[A] += asiz;
+ size[B] += bsiz;
+ }
+ else
+ {
+ print_thunk;
+ reset (aoff, asiz, boff, bsiz);
+ }
+
+ append_line (PK_THUNK_REM, abytes, aname, avalue);
+ append_line (PK_THUNK_ADD, bbytes, bname, bvalue);
+ }
+
+ method addrem = (int what,
+ offset<uint<64>,B> off, offset<uint<64>,B> siz,
+ byte[] bytes, string name = "", string value = "") void:
+ {
+ var to = what == PK_THUNK_ADD ? B : A;
+
+ if (off == offset[to] + size[to])
+ size[to] += siz;
+ else
+ {
+ print_thunk;
+ if (what == PK_THUNK_ADD)
+ reset :boff off :bsiz siz;
+ else
+ reset :aoff off :asiz siz;
+ }
+
+ append_line (what, bytes, name, value);
+ }
+ };
+
+fun sdiff = (any a, any b,
+ string prefix_a = "a",
+ string prefix_b = "b",
+ int values = pk_sdiff_print_values,
+ offset<uint<64>,B> group_by = pk_diff_group_by,
+ Pk_Diff_Thunk thunk = Pk_Diff_Thunk { emit_values_p = values,
+ group_by = group_by })
+ void:
+{
+ fun format_ename = (string ename) string:
+ {
+ if (ename'length > 0 && ename[0] == '[')
+ return ename;
+ else
+ return "." + ename;
+ }
+
+ fun format_value = (any val) string:
+ {
+ /* Note we don't try to be exhaustive here. */
+ if (val isa string)
+ return format ("%v", val as string);
+ else if (val isa int<64>)
+ return format ("%v", val as int<64>);
+ else if (val isa uint<64>)
+ return format ("%v", val as uint<64>);
+ else if (val isa int<32>)
+ return format ("%v", val as int<32>);
+ else if (val isa uint<32>)
+ return format ("%v", val as uint<32>);
+ else if (val isa int<16>)
+ return format ("%v", val as int<16>);
+ else if (val isa uint<16>)
+ return format ("%v", val as uint<16>);
+ else if (val isa offset<int<64>,B>)
+ return format ("%v", val as offset<int<64>,B>);
+ else if (val isa offset<uint<64>,B>)
+ return format ("%v", val as offset<uint<64>,B>);
+ else if (val isa offset<int<32>,B>)
+ return format ("%v", val as offset<int<32>,B>);
+ else if (val isa offset<uint<32>,B>)
+ return format ("%v", val as offset<uint<32>,B>);
+ else if (val isa offset<int<16>,B>)
+ return format ("%v", val as offset<int<16>,B>);
+ else if (val isa offset<uint<16>,B>)
+ return format ("%v", val as offset<uint<16>,B>);
+ else
+ return "";
+ }
+
+ fun get_elem_bytes = (any v, uint<64> idx) byte[]:
+ {
+ return byte[v'esize (idx)] @ v'ios : v'eoffset (idx);
+ }
+
+ fun elem_simple_p = (any elem, uint<64> idx) int:
+ {
+ try { elem'elem(idx)'elem (0); return 0; }
+ catch (Exception e)
+ {
+ if (e.code == EC_out_of_bounds)
+ return 0;
+ if (e.code != EC_inval)
+ raise e;
+ }
+ return 1;
+ }
+
+ fun sdiff_addrem = (int what, Pk_Diff_Thunk thunk,
+ any val, string prefix, uint<64> idx) void:
+ {
+ for (; idx < val'length; ++idx)
+ {
+ if (val'elem (idx) ?! E_inval)
+ {
+ if (!elem_simple_p (val, idx))
+ sdiff_addrem (what, thunk, val'elem (idx),
+ prefix + format_ename (val'ename (idx)), 0);
+ else
+ thunk.addrem :what what :off val'eoffset (idx) :siz val'esize (idx)
+ :bytes get_elem_bytes (val, idx)
+ :name prefix + format_ename (val'ename (idx))
+ :value format_value (val'elem (idx));
+ }
+ }
+ }
+
+ /* First of all, make sure both values are mapped. */
+ if (!a'mapped || !b'mapped)
+ raise E_map;
+
+ /* Proceed element by element. */
+ var idx = 0UL;
+ for (; idx < a'length; ++idx)
+ {
+ var a_is_present = a'elem (idx) ?! E_inval;
+
+ if (idx >= b'length)
+ {
+ sdiff_addrem (PK_THUNK_REM, thunk, a, prefix_a, idx);
+ break;
+ }
+ else
+ {
+ var b_is_present = b'elem (idx) ?! E_inval;
+
+ if (a_is_present && b_is_present)
+ {
+ var a_full_name = prefix_a + format_ename (a'ename (idx));
+ var b_full_name = prefix_b + format_ename (b'ename (idx));
+
+ /* If the element is non-simple, recurse. */
+ if (!elem_simple_p (a, idx))
+ {
+ sdiff (a'elem (idx), b'elem (idx),
+ a_full_name, b_full_name,
+ values, group_by, thunk);
+ }
+ else
+ {
+ var a_bytes = get_elem_bytes (a, idx);
+ var b_bytes = get_elem_bytes (b, idx);
+
+ if (a_bytes != b_bytes)
+ thunk.change :aoff a'eoffset (idx) :asiz a'esize (idx)
+ :boff b'eoffset (idx) :bsiz b'esize (idx)
+ :abytes a_bytes :bbytes b_bytes
+ :aname a_full_name :bname b_full_name
+ :avalue format_value (a'elem (idx))
+ :bvalue format_value (b'elem (idx));
+ }
+ }
+ else if (b_is_present)
+ sdiff_addrem (PK_THUNK_ADD, thunk, b'elem (idx), prefix_b, 0);
+ else if (a_is_present)
+ sdiff_addrem (PK_THUNK_REM, thunk, a'elem (idx), prefix_a, 0);
+ }
+ }
+
+ /* Now generate ADD thunks for extra elements in `b'. */
+ if (idx < b'length)
+ sdiff_addrem (PK_THUNK_ADD, thunk, b, prefix_b, idx);
+
+ /* There may be a thunk still to be emitted. */
+ thunk.print_thunk;
+ thunk.reset;
+}
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 6c59f9a0..c6cd07c8 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -97,6 +97,14 @@ EXTRA_DIST = \
poke.cmd/scrabble-2.pk \
poke.cmd/scrabble-3.pk \
poke.cmd/scrabble-4.pk \
+ poke.cmd/sdiff-1.pk \
+ poke.cmd/sdiff-2.pk \
+ poke.cmd/sdiff-3.pk \
+ poke.cmd/sdiff-4.pk \
+ poke.cmd/sdiff-5.pk \
+ poke.cmd/sdiff-6.pk \
+ poke.cmd/sdiff-7.pk \
+ poke.cmd/sdiff-8.pk \
poke.cmd/set-endian.pk \
poke.cmd/set-error-on-warning.pk \
poke.cmd/set-error-on-warning-diag.pk \
diff --git a/testsuite/poke.cmd/sdiff-1.pk b/testsuite/poke.cmd/sdiff-1.pk
new file mode 100644
index 00000000..679e764c
--- /dev/null
+++ b/testsuite/poke.cmd/sdiff-1.pk
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x00 0x04 0x12 0x34 0x56 0x78 0x9a 0xbc} } */
+
+type Foo = struct { byte sz; byte[sz] data; };
+
+/* { dg-command { sdiff :a (Foo @ 0#B) :b (Foo @ 1#B) } } */
+/* { dg-output "@@ 0x00\\+1,0x01\\+5 @@\n" } */
+/* { dg-output "-00 +a.sz *\n" } */
+/* { dg-output "\\+04 +b.sz *\n" } */
+/* { dg-output "\\+12 +b.data\\\[0\\\] *\n" } */
+/* { dg-output "\\+34 +b.data\\\[1\\\] *\n" } */
+/* { dg-output "\\+56 +b.data\\\[2\\\] *\n" } */
+/* { dg-output "\\+78 +b.data\\\[3\\\] *\n" } */
diff --git a/testsuite/poke.cmd/sdiff-2.pk b/testsuite/poke.cmd/sdiff-2.pk
new file mode 100644
index 00000000..4fb0e84d
--- /dev/null
+++ b/testsuite/poke.cmd/sdiff-2.pk
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x00 0x02 0x12 0x34 0x56 0x78 0x9a 0xbc 0xde 0xf0} } */
+
+type Foo = struct { byte sz; int[sz] data; };
+
+/* { dg-command {.set endian little} } */
+/* { dg-command {.set obase 16} } */
+/* { dg-command { sdiff :a (Foo @ 0#B) :b (Foo @ 1#B) :group_by 2#B} } */
+/* { dg-output "@@ 0x00\\+1,0x01\\+9 @@\n" } */
+/* { dg-output "-00 +a.sz *\n" } */
+/* { dg-output "\\+02 +b.sz *\n" } */
+/* { dg-output "\\+1234 5678 +b.data\\\[0\\\] +0x78563412\n" } */
+/* { dg-output "\\+9abc def0 +b.data\\\[1\\\] +0xf0debc9a\n" } */
diff --git a/testsuite/poke.cmd/sdiff-3.pk b/testsuite/poke.cmd/sdiff-3.pk
new file mode 100644
index 00000000..c7e82559
--- /dev/null
+++ b/testsuite/poke.cmd/sdiff-3.pk
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x00 0x02 0x12 0x34 0x56 0x78 0x9a 0xbc 0xde 0xf0} } */
+
+type Foo = struct { byte sz; int[sz] data; };
+
+/* { dg-command {.set endian little} } */
+/* { dg-command {.set obase 16} } */
+/* { dg-command { sdiff :a (Foo @ 0#B) :b (Foo @ 1#B) :group_by 1#B} } */
+/* { dg-output "@@ 0x00\\+1,0x01\\+9 @@\n" } */
+/* { dg-output "-00 +a.sz *\n" } */
+/* { dg-output "\\+02 +b.sz *\n" } */
+/* { dg-output "\\+12 34 56 78 +b.data\\\[0\\\] +0x78563412\n" } */
+/* { dg-output "\\+9a bc de f0 +b.data\\\[1\\\] +0xf0debc9a\n" } */
diff --git a/testsuite/poke.cmd/sdiff-4.pk b/testsuite/poke.cmd/sdiff-4.pk
new file mode 100644
index 00000000..1c065350
--- /dev/null
+++ b/testsuite/poke.cmd/sdiff-4.pk
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x00 0x02 0x12 0x34 0x56 0x78 0x9a 0xbc 0xde 0xf0} } */
+
+type Foo = struct { byte sz; int[sz] data; };
+
+/* { dg-command {.set endian little} } */
+/* { dg-command {.set obase 16} } */
+/* { dg-command { sdiff :a (Foo @ 0#B) :b (Foo @ 1#B) :group_by 4#B} } */
+/* { dg-output "@@ 0x00\\+1,0x01\\+9 @@\n" } */
+/* { dg-output "-00 +a.sz *\n" } */
+/* { dg-output "\\+02 +b.sz *\n" } */
+/* { dg-output "\\+12345678 +b.data\\\[0\\\] +0x78563412\n" } */
+/* { dg-output "\\+9abcdef0 +b.data\\\[1\\\] +0xf0debc9a\n" } */
diff --git a/testsuite/poke.cmd/sdiff-5.pk b/testsuite/poke.cmd/sdiff-5.pk
new file mode 100644
index 00000000..7f541bf7
--- /dev/null
+++ b/testsuite/poke.cmd/sdiff-5.pk
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x00 0x04 0x12 0x34 0x56 0x78 0x9a 0xbc} } */
+
+type Foo = struct { byte sz; byte[sz] data; };
+
+/* { dg-command { sdiff :a (Foo @ 1#B) :b (Foo @ 0#B) } } */
+/* { dg-output "@@ 0x01\\+5,0x00\\+1 @@\n" } */
+/* { dg-output "-04 +a.sz *\n" } */
+/* { dg-output "\\+00 +b.sz *\n" } */
+/* { dg-output "\\-12 +a.data\\\[0\\\] *\n" } */
+/* { dg-output "\\-34 +a.data\\\[1\\\] *\n" } */
+/* { dg-output "\\-56 +a.data\\\[2\\\] *\n" } */
+/* { dg-output "\\-78 +a.data\\\[3\\\] *\n" } */
diff --git a/testsuite/poke.cmd/sdiff-6.pk b/testsuite/poke.cmd/sdiff-6.pk
new file mode 100644
index 00000000..e876912d
--- /dev/null
+++ b/testsuite/poke.cmd/sdiff-6.pk
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x00 0x00 0x12 0x34 0x56 0x78 0x9a 0xbc} foo } */
+/* { dg-data {c*} {0x00 0x04 0x12 0x34 0x56 0x78 0x9a 0xbc} bar } */
+
+type Foo = struct { byte sz; byte eq; byte[sz] data; };
+
+/* { dg-command {.file foo} } */
+/* { dg-command {.file bar} } */
+/* { dg-command { sdiff :a (Foo @ 0 : 1#B) :b (Foo @ 1 : 1#B) } } */
+/* { dg-output "@@ 0x01\\+1,0x01\\+1 @@\n" } */
+/* { dg-output "-00 +a.sz *\n" } */
+/* { dg-output "\\+04 +b.sz *\n" } */
+/* { dg-output "@@ ,0x03\\+4 @@\n" } */
+/* { dg-output "\\+34 +b.data\\\[0\\\] *\n" } */
+/* { dg-output "\\+56 +b.data\\\[1\\\] *\n" } */
+/* { dg-output "\\+78 +b.data\\\[2\\\] *\n" } */
+/* { dg-output "\\+9a +b.data\\\[3\\\] *\n" } */
diff --git a/testsuite/poke.cmd/sdiff-7.pk b/testsuite/poke.cmd/sdiff-7.pk
new file mode 100644
index 00000000..068f1649
--- /dev/null
+++ b/testsuite/poke.cmd/sdiff-7.pk
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x00 0x04 0x12 0x11 0x22 0x33 0x44 0xbc} foo } */
+/* { dg-data {c*} {0x00 0x04 0x12 0x34 0x56 0x33 0x9a 0xbc} bar } */
+
+type Foo = struct { byte sz; byte eq; byte[sz] data; };
+
+/* { dg-command {.file foo} } */
+/* { dg-command {.file bar} } */
+/* { dg-command { sdiff :a (Foo @ 0 : 1#B) :b (Foo @ 1 : 1#B) } } */
+/* { dg-output "@@ 0x03\\+2,0x03\\+2 @@\n" } */
+/* { dg-output "-11 +a.data\\\[0\\\] *\n" } */
+/* { dg-output "\\+34 +b.data\\\[0\\\] *\n" } */
+/* { dg-output "-22 +a.data\\\[1\\\] *\n" } */
+/* { dg-output "\\+56 +b.data\\\[1\\\] *\n" } */
+/* { dg-output "@@ 0x06\\+1,0x06\\+1 @@\n" } */
+/* { dg-output "-44 +a.data\\\[3\\\] *\n" } */
+/* { dg-output "\\+9a +b.data\\\[3\\\] *\n" } */
diff --git a/testsuite/poke.cmd/sdiff-8.pk b/testsuite/poke.cmd/sdiff-8.pk
new file mode 100644
index 00000000..6b4e96ff
--- /dev/null
+++ b/testsuite/poke.cmd/sdiff-8.pk
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x00 0x27 0x28 0x00 0x22 0x33 0x44 0xbc} foo } */
+/* { dg-data {c*} {0x01 0x29 0x30 0x31 0x00 0x33 0x9a 0xbc} bar } */
+
+type Foo = struct { byte sz; string str; };
+
+/* { dg-command {.file foo} } */
+/* { dg-command {.file bar} } */
+/* { dg-command { sdiff :a (Foo @ 0 : 0#B) :b (Foo @ 1 : 0#B) } } */
+/* { dg-output "@@ 0x00\\+4,0x00\\+5 @@\n" } */
+/* { dg-output "-00 +a.sz *\n" } */
+/* { dg-output "\\+01 +b.sz *\n" } */
+/* { dg-output "-27 28 00 +a.str +\"'\\(\" *\n" } */
+/* { dg-output "\\+29 30 31 00 +b.str +\"\\)01\" *\n" } */
diff --git a/testsuite/poke.repl/repl.exp b/testsuite/poke.repl/repl.exp
index ea523921..d4d70361 100644
--- a/testsuite/poke.repl/repl.exp
+++ b/testsuite/poke.repl/repl.exp
@@ -80,7 +80,7 @@ poke_exit
set test "tab-completion-info-1"
poke_start
-poke_send ".info type Pk_D\t" ".info type Pk_Dump_Offset"
+poke_send ".info type Pk_Du\t" ".info type Pk_Dump_Offset"
poke_exit
set test "sigint-returns-to-prompt-1"
--
2.11.0
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [COMMITTED] poke: new command `sdiff' for structured binary diffs,
Jose E. Marchesi <=