poke-devel
[Top][All Lists]
Advanced

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

[PATCH] cmd: set: Introduce tree-print set sub-command


From: Carlo Caione
Subject: [PATCH] cmd: set: Introduce tree-print set sub-command
Date: Wed, 12 Feb 2020 13:23:35 +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 command to display the output data in a tree-fied
form (deep or shallow).

For example:

| (poke) .set tree-print shallow
| ...
| St_Key_Hdr {
|    dw_magic=0x0U,
|    n_total_size=0x0U,
|    by_version=0x0UB,
|    by_key_type=0x0UB,
|    by_head_size=0x0UB,
|    sz_pad=0x0UB,
|    rsv=0x0U,
|    item_hdr=St_Item_Hdr
|  }

| (poke) .set tree-print deep
| ...
| St_Key_Hdr {
|    dw_magic=0x0U,
|    n_total_size=0x0U,
|    by_version=0x0UB,
|    by_key_type=0x0UB,
|    by_head_size=0x0UB,
|    sz_pad=0x0UB,
|    rsv=0x0U,
|    item_hdr=St_Item_Hdr {
|      sz_pad_1=[0x0UB,0x0UB,0x0UB,0x0UB],
|      sz_pad_2=[0x0UB,0x0UB,0x0UB,0x0UB],
|      n_raw_offset=0x0UH#B,
|      n_raw_size=0x0UH,
|      sz_pad_3=[0x0UB,0x0UB,0x0UB,0x0UB]
|    }
|  }

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

  * testsuite/poke.cmd/set-tree-print.pk: new test
  * src/pk-set.c (pk_cmd_set_tree_print): net tree-print set sub-command
  * src/pk-term.c (pk_printf_indent) : new function to print indentation
  * src/pk-term.h: likewise
  * src/pvm-val.c: support indentation
  * src/pvm.c: new flag for tree-printing
  * src/pvm.h: likewise
  * src/pvm.jitter: likewise
---
 src/pk-set.c                         | 55 ++++++++++++++++++++++++++++
 src/pk-term.c                        |  6 +++
 src/pk-term.h                        | 10 +++++
 src/pvm-val.c                        | 19 +++++++++-
 src/pvm.c                            | 14 +++++++
 src/pvm.h                            |  3 ++
 src/pvm.jitter                       |  2 +
 testsuite/poke.cmd/set-tree-print.pk | 24 ++++++++++++
 8 files changed, 132 insertions(+), 1 deletion(-)
 create mode 100644 testsuite/poke.cmd/set-tree-print.pk

diff --git a/src/pk-set.c b/src/pk-set.c
index 5a063620..ed4ff626 100644
--- a/src/pk-set.c
+++ b/src/pk-set.c
@@ -230,6 +230,56 @@ pk_cmd_set_pretty_print (int argc, struct pk_cmd_arg 
argv[], uint64_t uflags)
   return 1;
 }
 
+static int
+pk_cmd_set_tree_print (int argc, struct pk_cmd_arg argv[], uint64_t uflags)
+{
+  /* set tree-print {no,deep,shallow}  */
+
+  const char *arg;
+
+  if (argc != 1)
+    assert (0);
+
+  arg = PK_CMD_ARG_STR (argv[0]);
+
+  if (*arg == '\0')
+    {
+      enum pk_tree_mode tree_mode = pvm_tree_print (poke_vm);
+
+      switch (tree_mode)
+        {
+        case PK_TREE_NO:      pk_puts ("no\n"); break;
+        case PK_TREE_DEEP:    pk_puts ("deep\n"); break;
+        case PK_TREE_SHALLOW: pk_puts ("shallow\n"); break;
+        default:
+          assert (0);
+        }
+    }
+  else
+    {
+      enum pk_tree_mode tree_mode;
+
+      if (STREQ (arg, "no"))
+        tree_mode = PK_TREE_NO;
+      else if (STREQ (arg, "deep"))
+        tree_mode = PK_TREE_DEEP;
+      else if (STREQ (arg, "shallow"))
+        tree_mode = PK_TREE_SHALLOW;
+      else
+        {
+          pk_term_class ("error");
+          pk_puts ("error: ");
+          pk_term_end_class ("error");
+          pk_puts (" tree_mode should be one of `no' or `deep' or 
`shallow'.\n");
+          return 0;
+        }
+
+      pvm_set_tree_print (poke_vm, tree_mode);
+    }
+
+  return 1;
+}
+
 static int
 pk_cmd_set_error_on_warning (int argc, struct pk_cmd_arg argv[],
                              uint64_t uflags)
@@ -293,6 +343,10 @@ struct pk_cmd set_pretty_print_cmd =
   {"pretty-print", "s?", "", 0, NULL, pk_cmd_set_pretty_print,
    "set pretty-print (yes|no)"};
 
+struct pk_cmd set_tree_print_cmd =
+  {"tree-print", "s?", "", 0, NULL, pk_cmd_set_tree_print,
+   "set pretty-print (no|deep|shallow)"};
+
 struct pk_cmd set_error_on_warning_cmd =
   {"error-on-warning", "s?", "", 0, NULL, pk_cmd_set_error_on_warning,
    "set error-on-warning (yes|no)"};
@@ -303,6 +357,7 @@ struct pk_cmd *set_cmds[] =
    &set_endian_cmd,
    &set_nenc_cmd,
    &set_pretty_print_cmd,
+   &set_tree_print_cmd,
    &set_error_on_warning_cmd,
    &null_cmd
   };
diff --git a/src/pk-term.c b/src/pk-term.c
index b0a2dee4..a92b6a99 100644
--- a/src/pk-term.c
+++ b/src/pk-term.c
@@ -117,6 +117,12 @@ pk_printf (const char *format, ...)
   free (str);
 }
 
+void
+pk_printf_indent (unsigned int lvl)
+{
+  pk_printf ("\n%*s", (2 * lvl) + 1, "");
+}
+
 void
 pk_term_class (const char *class)
 {
diff --git a/src/pk-term.h b/src/pk-term.h
index 80827a0b..8a20adcc 100644
--- a/src/pk-term.h
+++ b/src/pk-term.h
@@ -23,6 +23,13 @@
 
 #include <textstyle.h>
 
+enum pk_tree_mode
+  {
+    PK_TREE_NO,
+    PK_TREE_DEEP,
+    PK_TREE_SHALLOW
+  };
+
 /* Initialize and finalize the terminal subsystem.  */
 void pk_term_init (int argc, char *argv[]);
 void pk_term_shutdown (void);
@@ -40,6 +47,9 @@ extern void pk_puts (const char *str);
 /* Print a formatted string to the terminal.  */
 extern void pk_printf (const char *format, ...);
 
+/* Print a formatted string as indentation.  */
+extern void pk_printf_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..cb1fb119 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_indent_level;
 
       /* 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,17 @@ pvm_print_val (pvm_val val, int base, int flags)
         }
       else
         pk_puts ("struct");
-      pk_puts (" ");
 
+      if ((pvm_tree_print (poke_vm) == PK_TREE_SHALLOW) && pk_indent_level != 
0)
+        {
+          pk_term_end_class ("struct");
+          return;
+        }
+
+      pk_puts (" ");
       pk_printf ("{");
+
+      pk_indent_level++;
       for (idx = 0; idx < nelem; ++idx)
         {
           pvm_val name = PVM_VAL_SCT_FIELD_NAME(val, idx);
@@ -851,6 +860,10 @@ pvm_print_val (pvm_val val, int base, int flags)
 
           if (idx != 0)
             pk_puts (",");
+
+          if (pvm_tree_print (poke_vm) != PK_TREE_NO)
+           pk_printf_indent (pk_indent_level);
+
           if (name != PVM_NULL)
             {
               pk_term_class ("struct-field-name");
@@ -866,6 +879,10 @@ pvm_print_val (pvm_val val, int base, int flags)
               pvm_print_val (offset, base, flags);
             }
         }
+      pk_indent_level--;
+
+      if (pvm_tree_print (poke_vm) != PK_TREE_NO)
+        pk_printf_indent (pk_indent_level);
       pk_puts ("}");
 
       pk_term_end_class ("struct");
diff --git a/src/pvm.c b/src/pvm.c
index 3eeaa06c..c8193b7c 100644
--- a/src/pvm.c
+++ b/src/pvm.c
@@ -39,6 +39,8 @@
   ((PVM)->pvm_state.pvm_state_runtime.nenc)
 #define PVM_STATE_PRETTY_PRINT(PVM)                     \
   ((PVM)->pvm_state.pvm_state_runtime.pretty_print)
+#define PVM_STATE_TREE_PRINT(PVM)                       \
+  ((PVM)->pvm_state.pvm_state_runtime.tree_print)
 
 struct pvm
 {
@@ -168,6 +170,18 @@ pvm_set_pretty_print (pvm apvm, int flag)
   PVM_STATE_PRETTY_PRINT (apvm) = flag;
 }
 
+int
+pvm_tree_print (pvm apvm)
+{
+  return PVM_STATE_TREE_PRINT (apvm);
+}
+
+void
+pvm_set_tree_print (pvm apvm, int flag)
+{
+  PVM_STATE_TREE_PRINT (apvm) = flag;
+}
+
 void
 pvm_assert (int expression)
 {
diff --git a/src/pvm.h b/src/pvm.h
index 40449efd..ccf9fc6c 100644
--- a/src/pvm.h
+++ b/src/pvm.h
@@ -96,6 +96,9 @@ 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);
 
+int pvm_tree_print (pvm pvm);
+void pvm_set_tree_print (pvm pvm, int flag);
+
 /* 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..1f9d4afd 100644
--- a/src/pvm.jitter
+++ b/src/pvm.jitter
@@ -550,6 +550,7 @@ state-struct-runtime-c
       uint32_t endian;
       uint32_t nenc;
       uint32_t pretty_print;
+      uint32_t tree_print;
   end
 end
 
@@ -562,6 +563,7 @@ 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->tree_print = 0;
   end
 end
 
diff --git a/testsuite/poke.cmd/set-tree-print.pk 
b/testsuite/poke.cmd/set-tree-print.pk
new file mode 100644
index 00000000..f4b28d45
--- /dev/null
+++ b/testsuite/poke.cmd/set-tree-print.pk
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80} } */
+
+/* { dg-command { .set obase 16 } } */
+
+/* { dg-command { .set tree-print no } } */
+/* { dg-command { deftype Foo = struct { byte b; } } } */
+/* { dg-command { deftype Foo2 = struct { Foo foo; } } } */
+/* { dg-command { Foo2 @ 0#B } } */
+/* { dg-output "Foo2 \{foo=Foo \{b=0x10UB\}\}" } */
+
+/* { dg-command { .set tree-print shallow } } */
+/* { dg-command { Foo2 @ 0#B } } */
+/* { dg-output "\nFoo2 \{" } */
+/* { dg-output "\n   foo=Foo" } */
+/* { dg-output "\n \}" } */
+
+/* { dg-command { .set tree-print deep } } */
+/* { dg-command { Foo2 @ 0#B } } */
+/* { dg-output "\nFoo2 \{" } */
+/* { 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]