poke-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]