[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
- [PATCH] cmd: set: Introduce tree-print set sub-command,
Carlo Caione <=