poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] cmd: set: Introduce set sub-commands for tree printing


From: Carlo Caione
Subject: [PATCH] cmd: set: Introduce set sub-commands for tree printing
Date: Thu, 13 Feb 2020 09:57:50 +0100

One typical (noob-ish) use for GNU poke is just to parse the content of
a binary file for visual inspection after having defined the binary
structure in a pk file.

Unfortunately the usual output from something like '$<data> @ 0#B'
isn't really user friendly and it is massively difficult to make sense
of the un-spaced wall of text in output.

This patch wants to be an attempt to prettify a bit the displayed data
introducing a new set of commands to tweak how the output data in a
struct is displayed.

Signed-off-by: Carlo Caione <address@hidden>

  * testsuite/poke.cmd/set-odepth.pk: new test
  * testsuite/poke.cmd/set-oindent.pk: likewise
  * testsuite/poke.cmd/set-odepth.pk: likewise
  * src/pvm.jitter: new flags in the PVM state struct
  * src/pvm.c: helpers to retrieve tree-related flags
  * src/pvm.h: likewise
  * src/pvm-val.c: support new printing modes
  * src/pk-term.c: new function to print indentation
  * src/pk-term.h: likewise
  * src/pk-set.c: new .set sub-commands
  * doc/poke.texi: updated documentation
---
 doc/poke.texi                     |  13 ++++
 src/pk-set.c                      | 101 ++++++++++++++++++++++++++++++
 src/pk-term.c                     |   9 +++
 src/pk-term.h                     |   3 +
 src/pvm-val.c                     |  19 +++++-
 src/pvm.c                         |  42 +++++++++++++
 src/pvm.h                         |  15 +++++
 src/pvm.jitter                    |   6 ++
 testsuite/poke.cmd/set-odepth.pk  |  17 +++++
 testsuite/poke.cmd/set-oindent.pk |  14 +++++
 testsuite/poke.cmd/set-omode.pk   |  18 ++++++
 11 files changed, 256 insertions(+), 1 deletion(-)
 create mode 100644 testsuite/poke.cmd/set-odepth.pk
 create mode 100644 testsuite/poke.cmd/set-oindent.pk
 create mode 100644 testsuite/poke.cmd/set-omode.pk

diff --git a/doc/poke.texi b/doc/poke.texi
index 3057eee4..246add95 100644
--- a/doc/poke.texi
+++ b/doc/poke.texi
@@ -668,6 +668,19 @@ is @code{no}.
 @cindex warnings
 Flag indicating whether handling compilation warnings as errors.
 Default value is @code{no}.
+@item omode
+@cindex mode, of displayed values
+It defines the way the binary struct data is displayed. In @code{flat} mode
+data is not formatted in any special way. In @code{tree} mode the struct data
+is displayed in a hierarchical (tree) mode.
+@item odepth
+@cindex depth, of displayed struct fields
+In @code{tree} and @code{flat} mode the struct fields are recursively displayed
+up to the @code{depth}-th level. The default value @code{0} means no limit.
+@item oindent
+@cindex indent, as number of spaces
+Number defining the number of spaces used for indentation for each level. Only
+values >=1 and <= 10 are valid. Default value is '2'.
 @end table
 
 @node vm command
diff --git a/src/pk-set.c b/src/pk-set.c
index 5a063620..f1df36bd 100644
--- a/src/pk-set.c
+++ b/src/pk-set.c
@@ -230,6 +230,95 @@ pk_cmd_set_pretty_print (int argc, struct pk_cmd_arg 
argv[], uint64_t uflags)
   return 1;
 }
 
+static int
+pk_cmd_set_odepth (int argc, struct pk_cmd_arg argv[], uint64_t uflags)
+{
+  /* set odepth [DEPTH]  */
+
+  assert(argc == 1);
+
+  int odepth = PK_CMD_ARG_INT (argv[0]);
+
+  if (odepth < 0)
+    {
+      pk_term_class ("error");
+      pk_puts ("error: ");
+      pk_term_end_class ("error");
+      pk_puts (_(" odepth should be >=0.\n"));
+      return 0;
+    }
+
+  pvm_set_odepth (poke_vm, odepth);
+  return 1;
+}
+
+static int
+pk_cmd_set_oindent (int argc, struct pk_cmd_arg argv[], uint64_t uflags)
+{
+  /* set oindent [INDENT]  */
+
+  assert(argc == 1);
+
+  int oindent = PK_CMD_ARG_INT (argv[0]);
+
+  if (oindent < 1 || oindent > 10)
+    {
+      pk_term_class ("error");
+      pk_puts ("error: ");
+      pk_term_end_class ("error");
+      pk_puts (_(" oindent should be >=1 and <= 10.\n"));
+      return 0;
+    }
+
+  pvm_set_oindent (poke_vm, oindent);
+  return 1;
+}
+
+static int
+pk_cmd_set_omode (int argc, struct pk_cmd_arg argv[], uint64_t uflags)
+{
+  /* set omode {normal|tree}  */
+
+  enum pvm_omode omode;
+  const char *arg;
+
+  assert(argc == 1);
+
+  arg = PK_CMD_ARG_STR (argv[0]);
+
+  if (*arg == '\0')
+    {
+      omode = pvm_omode (poke_vm);
+
+      switch (omode)
+        {
+        case PVM_PRINT_FLAT: pk_puts ("flat\n"); break;
+        case PVM_PRINT_TREE: pk_puts ("tree\n"); break;
+        default:
+          assert (0);
+        }
+    }
+  else
+    {
+      if (STREQ (arg, "flat"))
+        omode = PVM_PRINT_FLAT;
+      else if (STREQ (arg, "tree"))
+        omode = PVM_PRINT_TREE;
+      else
+        {
+          pk_term_class ("error");
+          pk_puts (_("error: "));
+          pk_term_end_class ("error");
+          pk_puts (_(" omode should be one of `flat' or `tree'.\n"));
+          return 0;
+        }
+
+      pvm_set_omode (poke_vm, omode);
+    }
+
+  return 1;
+}
+
 static int
 pk_cmd_set_error_on_warning (int argc, struct pk_cmd_arg argv[],
                              uint64_t uflags)
@@ -280,6 +369,15 @@ pk_cmd_set_error_on_warning (int argc, struct pk_cmd_arg 
argv[],
 
 extern struct pk_cmd null_cmd; /* pk-cmd.c  */
 
+struct pk_cmd set_oindent_cmd =
+  {"oindent", "i", "", 0, NULL, pk_cmd_set_oindent, "set oindent [INDENT]"};
+
+struct pk_cmd set_odepth_cmd =
+  {"odepth", "i", "", 0, NULL, pk_cmd_set_odepth, "set odepth [DEPTH]"};
+
+struct pk_cmd set_omode_cmd =
+  {"omode", "s?", "", 0, NULL, pk_cmd_set_omode, "set omode (normal|tree)"};
+
 struct pk_cmd set_obase_cmd =
   {"obase", "i", "", 0, NULL, pk_cmd_set_obase, "set obase (2|8|10|16)"};
 
@@ -300,6 +398,9 @@ struct pk_cmd set_error_on_warning_cmd =
 struct pk_cmd *set_cmds[] =
   {
    &set_obase_cmd,
+   &set_omode_cmd,
+   &set_odepth_cmd,
+   &set_oindent_cmd,
    &set_endian_cmd,
    &set_nenc_cmd,
    &set_pretty_print_cmd,
diff --git a/src/pk-term.c b/src/pk-term.c
index b0a2dee4..2f052dab 100644
--- a/src/pk-term.c
+++ b/src/pk-term.c
@@ -117,6 +117,15 @@ pk_printf (const char *format, ...)
   free (str);
 }
 
+void
+pk_term_indent (unsigned int lvl)
+{
+  unsigned int oindent = pvm_oindent (poke_vm);
+
+  if (pvm_omode (poke_vm) == PVM_PRINT_TREE)
+    pk_printf ("\n%*s", (oindent * lvl), "");
+}
+
 void
 pk_term_class (const char *class)
 {
diff --git a/src/pk-term.h b/src/pk-term.h
index 80827a0b..0134b012 100644
--- a/src/pk-term.h
+++ b/src/pk-term.h
@@ -40,6 +40,9 @@ extern void pk_puts (const char *str);
 /* Print a formatted string to the terminal.  */
 extern void pk_printf (const char *format, ...);
 
+/* Print indentation.  */
+extern void pk_term_indent (unsigned int lvl);
+
 /* Class handling.  */
 extern void pk_term_class (const char *class);
 extern void pk_term_end_class (const char *class);
diff --git a/src/pvm-val.c b/src/pvm-val.c
index 69726b10..1d727102 100644
--- a/src/pvm-val.c
+++ b/src/pvm-val.c
@@ -818,6 +818,7 @@ pvm_print_val (pvm_val val, int base, int flags)
       pvm_val struct_type = PVM_VAL_SCT_TYPE (val);
       pvm_val struct_type_name = PVM_VAL_TYP_S_NAME (struct_type);
       pvm_val pretty_printer = pvm_get_struct_method (val, "_print");
+      static unsigned int pk_odepth;
 
       /* If the struct has a pretty printing method (called _print)
          then use it, unless the PVM is configured to not do so.
@@ -840,9 +841,19 @@ pvm_print_val (pvm_val val, int base, int flags)
         }
       else
         pk_puts ("struct");
-      pk_puts (" ");
 
+      if (pk_odepth >= pvm_odepth (poke_vm) &&
+          pvm_odepth (poke_vm) != 0)
+        {
+          pk_puts (" {...}");
+          pk_term_end_class ("struct");
+          return;
+        }
+
+      pk_puts (" ");
       pk_printf ("{");
+
+      pk_odepth++;
       for (idx = 0; idx < nelem; ++idx)
         {
           pvm_val name = PVM_VAL_SCT_FIELD_NAME(val, idx);
@@ -851,6 +862,9 @@ pvm_print_val (pvm_val val, int base, int flags)
 
           if (idx != 0)
             pk_puts (",");
+
+          pk_term_indent (pk_odepth);
+
           if (name != PVM_NULL)
             {
               pk_term_class ("struct-field-name");
@@ -866,6 +880,9 @@ pvm_print_val (pvm_val val, int base, int flags)
               pvm_print_val (offset, base, flags);
             }
         }
+      pk_odepth--;
+
+      pk_term_indent (pk_odepth);
       pk_puts ("}");
 
       pk_term_end_class ("struct");
diff --git a/src/pvm.c b/src/pvm.c
index 3eeaa06c..bb041f15 100644
--- a/src/pvm.c
+++ b/src/pvm.c
@@ -39,6 +39,12 @@
   ((PVM)->pvm_state.pvm_state_runtime.nenc)
 #define PVM_STATE_PRETTY_PRINT(PVM)                     \
   ((PVM)->pvm_state.pvm_state_runtime.pretty_print)
+#define PVM_STATE_OMODE(PVM)                            \
+  ((PVM)->pvm_state.pvm_state_runtime.omode)
+#define PVM_STATE_ODEPTH(PVM)                           \
+  ((PVM)->pvm_state.pvm_state_runtime.odepth)
+#define PVM_STATE_OINDENT(PVM)                          \
+  ((PVM)->pvm_state.pvm_state_runtime.oindent)
 
 struct pvm
 {
@@ -168,6 +174,42 @@ pvm_set_pretty_print (pvm apvm, int flag)
   PVM_STATE_PRETTY_PRINT (apvm) = flag;
 }
 
+enum pvm_omode
+pvm_omode (pvm apvm)
+{
+  return PVM_STATE_OMODE (apvm);
+}
+
+void
+pvm_set_omode (pvm apvm, enum pvm_omode omode)
+{
+  PVM_STATE_OMODE (apvm) = omode;
+}
+
+unsigned int
+pvm_oindent (pvm apvm)
+{
+  return PVM_STATE_OINDENT (apvm);
+}
+
+void
+pvm_set_oindent (pvm apvm, unsigned int oindent)
+{
+  PVM_STATE_OINDENT (apvm) = oindent;
+}
+
+unsigned int
+pvm_odepth (pvm apvm)
+{
+  return PVM_STATE_ODEPTH (apvm);
+}
+
+void
+pvm_set_odepth (pvm apvm, unsigned int odepth)
+{
+  PVM_STATE_ODEPTH (apvm) = odepth;
+}
+
 void
 pvm_assert (int expression)
 {
diff --git a/src/pvm.h b/src/pvm.h
index 40449efd..f0df8ff9 100644
--- a/src/pvm.h
+++ b/src/pvm.h
@@ -27,6 +27,12 @@
 #include "pvm-env.h"
 #include "pvm-alloc.h"
 
+enum pvm_omode
+  {
+    PVM_PRINT_FLAT,
+    PVM_PRINT_TREE,
+  };
+
 /* The following enumeration contains every possible exit code
    resulting from the execution of a routine in the PVM.
 
@@ -96,6 +102,15 @@ void pvm_set_nenc (pvm pvm, enum ios_nenc nenc);
 int pvm_pretty_print (pvm pvm);
 void pvm_set_pretty_print (pvm pvm, int flag);
 
+enum pvm_omode pvm_omode (pvm apvm);
+void pvm_set_omode (pvm apvm, enum pvm_omode omode);
+
+unsigned int pvm_oindent (pvm apvm);
+void pvm_set_oindent (pvm apvm, unsigned int oindent);
+
+unsigned int pvm_odepth (pvm apvm);
+void pvm_set_odepth (pvm apvm, unsigned int odepth);
+
 /* Set the current negative encoding for PVM.  NENC should be one of
  * the IOS_NENC_* values defined in ios.h */
 
diff --git a/src/pvm.jitter b/src/pvm.jitter
index a1258747..72a84181 100644
--- a/src/pvm.jitter
+++ b/src/pvm.jitter
@@ -550,6 +550,9 @@ state-struct-runtime-c
       uint32_t endian;
       uint32_t nenc;
       uint32_t pretty_print;
+      enum pvm_omode omode;
+      uint32_t odepth;
+      uint32_t oindent;
   end
 end
 
@@ -562,6 +565,9 @@ state-initialization-c
       jitter_state_runtime->endian = IOS_ENDIAN_MSB;
       jitter_state_runtime->nenc = IOS_NENC_2;
       jitter_state_runtime->pretty_print = 0;
+      jitter_state_runtime->omode = PVM_PRINT_FLAT;
+      jitter_state_runtime->odepth = 0;
+      jitter_state_runtime->oindent = 2;
   end
 end
 
diff --git a/testsuite/poke.cmd/set-odepth.pk b/testsuite/poke.cmd/set-odepth.pk
new file mode 100644
index 00000000..605c7328
--- /dev/null
+++ b/testsuite/poke.cmd/set-odepth.pk
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80} } */
+
+/* { dg-command { .set obase 16 } } */
+
+/* { dg-command { .set omode flat } } */
+/* { dg-command { .set odepth 1 } } */
+/* { dg-command { deftype Foo = struct { byte b; } } } */
+/* { dg-command { deftype Bar = struct { Foo foo; } } } */
+/* { dg-command { Bar @ 0#B } } */
+/* { dg-output "Bar \{foo=Foo \{...\}\}" } */
+
+/* { dg-command { .set omode tree } } */
+/* { dg-command { Bar @ 0#B } } */
+/* { dg-output "\nBar \{" } */
+/* { dg-output "\n  foo=Foo \{...\}" } */
+/* { dg-output "\n\}" } */
diff --git a/testsuite/poke.cmd/set-oindent.pk 
b/testsuite/poke.cmd/set-oindent.pk
new file mode 100644
index 00000000..92ccca39
--- /dev/null
+++ b/testsuite/poke.cmd/set-oindent.pk
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80} } */
+
+/* { dg-command { .set obase 16 } } */
+
+/* { dg-command { .set omode tree } } */
+/* { dg-command { .set oindent 4 } } */
+/* { dg-command { .set odepth 1 } } */
+/* { dg-command { deftype Foo = struct { byte b; } } } */
+/* { dg-command { deftype Bar = struct { Foo foo; } } } */
+/* { dg-command { Bar @ 0#B } } */
+/* { dg-output "Bar \{" } */
+/* { dg-output "\n    foo=Foo \{...\}" } */
+/* { dg-output "\n\}" } */
diff --git a/testsuite/poke.cmd/set-omode.pk b/testsuite/poke.cmd/set-omode.pk
new file mode 100644
index 00000000..a52ca7c5
--- /dev/null
+++ b/testsuite/poke.cmd/set-omode.pk
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80} } */
+
+/* { dg-command { .set obase 16 } } */
+
+/* { dg-command { .set omode flat } } */
+/* { dg-command { deftype Foo = struct { byte b; } } } */
+/* { dg-command { deftype Bar = struct { Foo foo; } } } */
+/* { dg-command { Bar @ 0#B } } */
+/* { dg-output "Bar \{foo=Foo \{b=0x10UB\}\}" } */
+
+/* { dg-command { .set omode tree } } */
+/* { dg-command { Bar @ 0#B } } */
+/* { dg-output "\nBar \{" } */
+/* { dg-output "\n  foo=Foo \{" } */
+/* { dg-output "\n    b=0x10UB" } */
+/* { dg-output "\n  \}" } */
+/* { dg-output "\n\}" } */
-- 
2.20.1




reply via email to

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