poke-devel
[Top][All Lists]
Advanced

[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);
 }



reply via email to

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