[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Discussion] Side-by-side dump format
From: |
Jose E. Marchesi |
Subject: |
Re: [Discussion] Side-by-side dump format |
Date: |
Tue, 22 Aug 2023 12:52:47 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) |
New version of the prototype with styling of the ASCII part and also
line splits that can be configured either passing a :max_line_width
argument to `dump' or by setting pk_dump_max_line_width. Default value
is 90 columns.
diff --git a/etc/poke-dark.css b/etc/poke-dark.css
index e1fff1dc..6880e53a 100644
--- a/etc/poke-dark.css
+++ b/etc/poke-dark.css
@@ -26,6 +26,10 @@
.dump-address { color : green; }
.dump-ascii { color : brown; }
.dump-unknown { color : yellow; }
+.dump-val1 { color : green; }
+.dump-val2 { color : red; }
+.dump-val3 { color : yellow; }
+.dump-val4 { color : brown; }
.diff-thunk-header { font-weight: bold; }
.diff-minus { color : red; }
diff --git a/pickles/ios.pk b/pickles/ios.pk
index be7fad3e..fc5615c6 100644
--- a/pickles/ios.pk
+++ b/pickles/ios.pk
@@ -18,6 +18,22 @@
/* This pickle contains utilities related to poke IO spaces. */
+var ios_dumpval_styles
+ = ["dump-val1", "dump-val2", "dump-val3", "dump-val4"];
+
+type IOS_Dumpval_Info =
+ struct
+ {
+ string name;
+ int<32> index; /* 0 means non-mapped. */
+ int<32> style;
+ offset<uint<64>,b> offset;
+ offset<uint<64>,b> size;
+ };
+
+var ios_dumpval = any[]();
+var ios_dumpval_info = IOS_Dumpval_Info[]();
+
/* Print a byte dump of an area in a given IO space.
IOS is the IO space from which dump bytes.
@@ -28,6 +44,13 @@
SIZE is an offset specifying the amount of bytes to dump. The
offset is rounded up to the next byte.
+ VAL may be either a signed 32-bit integer or a mapped value. If a
+ mapped value, the byte dump corresponds to the contents of the
+ value and field/element information is also printed with color
+ codes. If VAL is a positive integer, then it is used to index the
+ ios_dumpval array to get the mapped value whose bytes are printed.
+ If VAL is a negative integer, then it is ignored. Defaults to -1.
+
GROUP_BY determines how the bytes are grouped together in the
output. Defaults to two bytes.
@@ -47,19 +70,39 @@
NONPRINTABLE_CHAR is the character code to use to denote
non-printable characters. Defaults to '.'.
+ MAX_LINE_WIDTH is the maximum number of columns to use in the
+ terminal. Additional lines are used whenever necessary. If this
+ argument has a negative value then no limit applies. Defaults to
+ -1.
+
This function may raise E_io, E_perm, and E_eof on several error
conditions. */
fun ios_dump_bytes = (int<32> ios,
offset<uint<64>,b> from,
offset<uint<64>,b> size,
+ any val = -1,
offset<uint<64>,b> group_by = 2#B,
int<32> cluster_by = 8,
int<32> ruler_p = 0,
int<32> ascii_p = 0,
string unknown_byte = "??",
- uint<8> nonprintable_char = '.') void:
+ uint<8> nonprintable_char = '.',
+ int<32> max_line_width = -1) void:
{
+ var print_val_p = 0;
+
+ fun get_val_style = (offset<uint<64>,b> offset) string:
+ {
+ for (var idx = 0; idx < ios_dumpval'length; ++idx)
+ {
+ var info = ios_dumpval_info[idx];
+ if (offset >= info.offset && offset < info.offset + info.size)
+ return ios_dumpval_styles[info.style % ios_dumpval_styles'length];
+ }
+ return "";
+ }
+
fun print_ruler = (offset<uint<64>,b> offset) void:
{
var o = 0#B;
@@ -106,28 +149,94 @@ fun ios_dump_bytes = (int<32> ios,
offset<uint<64>,b> top,
offset<uint<64>,b> step,
offset<uint<64>,b> group_by,
- int<32> cluster_by) void:
+ int<32> cluster_by) int<32>:
{
+ var len = 0;
+ var style = "";
+ var unknown_byte_style = "";
print(" ");
+ len += 2;
var o = 0#B;
while (o < step && offset + o < top)
{
+ style = print_val_p ? get_val_style (offset + o) : "dump-ascii";
+ unknown_byte_style = print_val_p ? style : "dump-unknown";
+
try
{
var v = uint<8> @ ios : (offset + o);
+ if (style != "")
+ term_begin_class (style);
if (v < ' ' || v > '~')
- printf "%<dump-ascii:%c%>", nonprintable_char;
+ printf "%c", nonprintable_char;
else
- printf "%<dump-ascii:%c%>", v;
+ printf "%c", v;
+ if (style != "")
+ term_end_class (style);
+ len += 1;
}
catch if E_io
{
- printf "%<dump-unknown:%c%>", nonprintable_char;
+ if (style != "")
+ term_begin_class (style);
+ printf "%c", nonprintable_char;
+ if (style != "")
+ term_end_class (style);
+ len += 1;
}
o++;
if (o < 16#B && (o % (cluster_by * group_by)) == 0#B)
- printf (" ");
+ {
+ printf (" ");
+ len += 1;
+ }
+ }
+
+ return len;
+ }
+
+ fun print_values = (offset<uint<64>,b> offset,
+ offset<uint<64>,b> step,
+ offset<uint<64>,b> top,
+ int<32> col) void:
+ {
+ var o = 0#B;
+ var c = col;
+ while (o < step && offset + o < top)
+ {
+ for (var idx = 0; idx < ios_dumpval'length; ++idx)
+ {
+ var info = ios_dumpval_info[idx];
+ if (info.offset == offset + o)
+ {
+ var val = ios_dumpval[idx];
+ var style = ios_dumpval_styles[info.style %
ios_dumpval_styles'length];
+
+ if (max_line_width >= 0
+ && c + info.name'length + 4 > max_line_width)
+ {
+ print "\n" + (" " * col);
+ c = col;
+ }
+
+ print " ";
+ if (info.index >= 0)
+ {
+ hserver_print_hl ('e',
+ format ("%i32d", idx),
+ format ("dump :val %i32d", idx));
+ print ("=");
+ c += 4;
+ }
+ term_begin_class (style);
+ print (info.name);
+ c += info.name'length;
+ term_end_class (style);
+ break;
+ }
+ }
+ o += 1#B;
}
}
@@ -137,12 +246,19 @@ fun ios_dump_bytes = (int<32> ios,
offset<uint<64>,b> group_by,
int<32> cluster_by) void:
{
+ var col = 0;
for (; offset < top; offset += step)
{
if (offset > 0xffff_ffff#B)
- printf ("%<dump-address:%u64x:%>", offset / #B);
+ {
+ printf ("%<dump-address:%u64x:%>", offset / #B);
+ col += 16 + 1;
+ }
else
- printf ("%<dump-address:%u32x:%>", offset / #B);
+ {
+ printf ("%<dump-address:%u32x:%>", offset / #B);
+ col += 8 + 1;
+ }
var o = 0#B;
try
@@ -153,34 +269,80 @@ fun ios_dump_bytes = (int<32> ios,
{
var b = uint<8> @ ios : (offset + o);
if (o % group_by == 0#B)
- print " ";
+ {
+ print " ";
+ col += 1;
+ }
+
+ var style = print_val_p ? get_val_style (offset + o) : "";
+ if (style != "")
+ term_begin_class (style);
printf ("%u8x", b);
- }
+ col += 2;
+ if (style != "")
+ term_end_class (style);
+ }
catch if E_io
{
if (o % group_by == 0#B)
- print " ";
+ {
+ print " ";
+ col += 1;
+ }
printf ("%<dump-unknown:%s%>", unknown_byte);
+ col += 2;
}
o++;
if (o < 16#B && (o % (cluster_by * group_by)) == 0#B)
- printf (" ");
+ {
+ printf (" ");
+ col += 1;
+ }
}
}
catch if E_eof {}
if (ascii_p)
{
- while (o < step)
- {
- if (o % group_by == 0#B)
- print " ";
- print (" ");
- o++;
- }
- print_ascii (offset, top, step, group_by, cluster_by);
+ for (var t = o; t < step; ++t)
+ {
+ if (t % group_by == 0#B)
+ {
+ print " ";
+ col += 1;
+ }
+ print (" ");
+ col += 2;
+ }
+ col += print_ascii (offset, top, step, group_by, cluster_by);
+ if (print_val_p)
+ {
+ for (var t = o; t < step; ++t)
+ {
+ print " ";
+ col += 1;
+ }
+ }
}
+ if (print_val_p)
+ {
+ if (!ascii_p)
+ {
+ for (var t = o; t < step; ++t)
+ {
+ if (o % group_by == 0#B)
+ {
+ print " ";
+ col += 1;
+ }
+ print (" ");
+ col += 2;
+ }
+ }
+ print_values (offset, step, top, col);
+ }
print "\n";
+ col = 0;
}
}
@@ -188,6 +350,61 @@ fun ios_dump_bytes = (int<32> ios,
if (! (ioflags (ios) & IOS_F_READ))
raise E_perm;
+ /* If `val' is specified, it can be:
+ negative int<32> -> for "no value".
+ positive int<32> -> for a mapped value stored in ios_dumpval.
+ other -> mapped value from which to derive `from'
+ and `size'.
+ */
+ if (val isa int<32>)
+ {
+ if (val as int<32> > 0 && val as int<32> > ios_dumpval'length)
+ raise Exception { code = EC_inval,
+ name = "invalid argument",
+ msg = "invalid VAL index" };
+
+ if (val as int<32> >= 0)
+ {
+ val = ios_dumpval[val as int<32>];
+
+ if (!val'mapped)
+ raise Exception { code = EC_inval,
+ name = "invalid argument",
+ msg = "indexed VAL is not mapped" };
+ }
+ }
+
+ if (val'mapped)
+ {
+ from = val'offset - (val'offset % 16#B);
+ size = val'size + (val'offset % 16#B);
+ print_val_p = 1;
+
+ /* Reset ios_dumpval and ios_dumpval_info. */
+ ios_dumpval = any[]();
+ ios_dumpval_info = IOS_Dumpval_Info[]();
+
+ /* Populate the array with the fields of VAL. */
+ for (var idx = 0UL, style = 0; idx < val'length; ++idx)
+ {
+ /* If the field is optional, check it is actually present. If it
+ is not, do not add it to the array. */
+ if (val'elem (idx) ?! E_inval)
+ continue;
+
+ /* Add the element and its info to the arrays. */
+ var elem = val'elem (idx);
+ apush (ios_dumpval, val'elem (idx));
+ apush (ios_dumpval_info,
+ IOS_Dumpval_Info {
+ name = val'ename (idx) == "" ? "<anon>" : val'ename (idx),
+ index = elem'mapped ? idx as int<32> : -1,
+ offset = val'eoffset (idx),
+ size = val'esize (idx),
+ style = style++ });
+ }
+ }
+
/* The `dump' command is byte-oriented.
The base offset is truncated to bytes.
The offset is rounded up to the next byte. */
diff --git a/poke/pk-dump.pk b/poke/pk-dump.pk
index 62eb8035..5739f68c 100644
--- a/poke/pk-dump.pk
+++ b/poke/pk-dump.pk
@@ -28,6 +28,7 @@ var pk_dump_ruler = 1;
var pk_dump_ascii = 1;
var pk_dump_nonprintable_char = '.';
var pk_dump_unknown_byte = "??";
+var pk_dump_max_line_width = 90;
pk_help_add_topic
:entry Poke_HelpEntry {
@@ -37,8 +38,8 @@ pk_help_add_topic
description= format ("
Synopsis:
- dump [:from OFFSET] [:size OFFSET] [:ios INT] [:ruler BOOL] \\
- [:ascii BOOL] [:group_by INT] [:cluster_by INT]
+ dump [:from OFFSET] [:size OFFSET] [:val VAL] [:ios INT] [:ruler BOOL] \\
+ [:ascii BOOL] [:group_by INT] [:cluster_by INT] [:max_line_width INT]
Arguments:
@@ -51,6 +52,13 @@ Arguments:
How much data to dump. Defaults to `pk_dump_size', currently
%v.
+ :val (any)
+ A mapped value whose constituent bytes are to be dumped. If
+ a non-negative 32-bit integer, then it is used as an index
+ referring to a past result. If a negative 32-bit integer
+ then this argument is ignored. Note that if :var is used
+ then any specified :from and :size are ignored.
+
:ios (int)
IO space from which dump bytes. This defaults to the currently
selected IO space.
@@ -73,12 +81,18 @@ Arguments:
have been displayed. Defaults to `pk_dump_cluster_by',
currently %i32d.
+ :max_line_width (int)
+ Maximum size of lines to use in the byte dump. If negative
+ then there is no limit. Defaults to `pk_dump_max_line_width',
+ currently %i32d.
+
If there is not a current IO space available `dump' raises an E_no_ios
exception.
See `.doc dump' for more information.",
pk_dump_size, pk_dump_ruler, pk_dump_ascii,
- pk_dump_group_by, pk_dump_cluster_by)
+ pk_dump_group_by, pk_dump_cluster_by,
+ pk_dump_max_line_width)
};
/* `pk_dump_offsets' keeps the last base offset used by `dump', per IO
@@ -117,13 +131,16 @@ fun pk_dump_set_offset = (int<32> ios, offset<int<64>,b>
offset) void:
fun dump = (int<32> ios = get_ios,
offset<int<64>,b> from = pk_dump_get_offset (ios),
offset<int<64>,b> size = pk_dump_size,
+ any val = -1,
offset<int<64>,b> group_by = pk_dump_group_by,
int<32> cluster_by = pk_dump_cluster_by,
int<32> ruler = pk_dump_ruler,
- int<32> ascii = pk_dump_ascii) void:
+ int<32> ascii = pk_dump_ascii,
+ int<32> max_line_width = pk_dump_max_line_width) void:
{
- ios_dump_bytes :ios ios :from from :size size :group_by group_by
+ ios_dump_bytes :ios ios :from from :size size :group_by group_by :val val
:cluster_by cluster_by :ruler_p ruler :ascii_p ascii
- :unknown_byte pk_dump_unknown_byte;
+ :unknown_byte pk_dump_unknown_byte
+ :max_line_width pk_dump_max_line_width;
pk_dump_set_offset (ios, from);
}
- [Discussion] Side-by-side dump format, Jade Lovelace, 2023/08/20
- Re: [Discussion] Side-by-side dump format, Jose E. Marchesi, 2023/08/21
- Re: [Discussion] Side-by-side dump format, Jose E. Marchesi, 2023/08/21
- Re: [Discussion] Side-by-side dump format, Jose E. Marchesi, 2023/08/21
- Re: [Discussion] Side-by-side dump format, Jose E. Marchesi, 2023/08/21
- Re: [Discussion] Side-by-side dump format, Jose E. Marchesi, 2023/08/21
- Re: [Discussion] Side-by-side dump format, Jose E. Marchesi, 2023/08/21
- Re: [Discussion] Side-by-side dump format, Jade Lovelace, 2023/08/22
- Re: [Discussion] Side-by-side dump format, Jose E. Marchesi, 2023/08/22
- Re: [Discussion] Side-by-side dump format,
Jose E. Marchesi <=
- Re: [Discussion] Side-by-side dump format, Jade Lovelace, 2023/08/22
- Re: [Discussion] Side-by-side dump format, Jose E. Marchesi, 2023/08/23