changeset 2045:1662730053d0

Implement controllable decimal/hexadecimal formatting for offset display mode.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 30 Nov 2018 08:01:46 +0200
parents 1b441465ef36
children 186cf6a7d634 3829c292df02
files tools/fanalyze.c
diffstat 1 files changed, 83 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/tools/fanalyze.c	Fri Nov 30 07:04:47 2018 +0200
+++ b/tools/fanalyze.c	Fri Nov 30 08:01:46 2018 +0200
@@ -50,19 +50,28 @@
 
 enum
 {
-    DMGV_uint8 = 0,
-    DMGV_uint16_le,
-    DMGV_uint16_be,
-    DMGV_uint32_le,
-    DMGV_uint32_be,
+    DMGV_UINT8 = 0,
+    DMGV_UINT16_LE,
+    DMGV_UINT16_BE,
+    DMGV_UINT32_LE,
+    DMGV_UINT32_BE,
 
     DMGV_last
 };
 
 
+enum
+{
+    DMGS_HEX = 0,
+    DMGS_DEC,
+    DMGS_last
+};
+
+
 typedef struct
 {
     int type;
+    int disp;
     Uint32 value;
 } DMGrepValue;
 
@@ -72,10 +81,10 @@
     char *name;
     Uint32 nmax;
     unsigned int bsize;
-} DMGrepDef;
+} DMGrepType;
 
 
-static const DMGrepDef dmGrepTypes[DMGV_last] =
+static const DMGrepType dmGrepTypes[DMGV_last] =
 {
     { "8bit (byte)"      , (1ULL <<  8) - 1, 1 },
     { "16bit (word) LE"  , (1ULL << 16) - 1, 2 },
@@ -85,6 +94,19 @@
 };
 
 
+typedef struct
+{
+    char *name;
+    char *fmt;
+} DMGrepDisp;
+
+
+static const DMGrepDisp dmGrepDisp[DMGS_last] =
+{
+    { "hex", "x" },
+    { "dec", "d" },
+};
+
 enum
 {
     FA_ANALYZE,
@@ -110,7 +132,7 @@
     {  0, '?', "help",        "Show this help", OPT_NONE },
     {  1, 'v', "verbose",     "Be more verbose", OPT_NONE },
     {  2, 'g', "grep",        "Binary grep <val>[,<le|be>[8|16|32]]", OPT_ARGREQ },
-    {  3, 'o', "offset",      "Show data in offset <offset>,<le|be>[8|16|32]]", OPT_ARGREQ },
+    {  3, 'o', "offset",      "Show data in offset <offset>,<le|be>[8|16|32][d|x]]", OPT_ARGREQ },
 };
 
 static const int optListN = sizeof(optList) / sizeof(optList[0]);
@@ -127,7 +149,7 @@
 {
     const char *sep = strchr(arg, ',');
     char *vspec, *vstr;
-    int vtype = -1, ret = DMERR_OK;
+    int vdisp = DMGS_HEX, vtype = -1, ret = DMERR_OK;
     Uint32 vval;
 
     if (setMode != FA_ANALYZE && setMode != mode)
@@ -169,14 +191,23 @@
         }
 
         // Get value bit size
-        if (strcmp(vtmp, "8") == 0)
-            vtype = DMGV_uint8;
+        if (strncmp(vtmp, "8", 1) == 0)
+        {
+            vtype = DMGV_UINT8;
+            vtmp += 1;
+        }
         else
-        if (strcmp(vtmp, "16") == 0)
-            vtype = vendianess ? DMGV_uint16_le : DMGV_uint16_be;
+        if (strncmp(vtmp, "16", 2) == 0)
+        {
+            vtype = vendianess ? DMGV_UINT16_LE : DMGV_UINT16_BE;
+            vtmp += 2;
+        }
         else
-        if (strcmp(vtmp, "32") == 0)
-            vtype = vendianess ? DMGV_uint32_le : DMGV_uint32_be;
+        if (strncmp(vtmp, "32", 2) == 0)
+        {
+            vtype = vendianess ? DMGV_UINT32_LE : DMGV_UINT32_BE;
+            vtmp += 2;
+        }
         else
         {
             ret = dmError(DMERR_INVALID_ARGS,
@@ -184,6 +215,26 @@
                 vspec);
             goto out;
         }
+
+        switch (tolower(*vtmp))
+        {
+            case 'd':
+                vdisp = DMGS_DEC;
+                break;
+
+            case 'x': case 'h':
+                vdisp = DMGS_HEX;
+                break;
+
+            case 0:
+                break;
+
+            default:
+                ret = dmError(DMERR_INVALID_ARGS,
+                    "Invalid grep view type '%s'.\n",
+                    vspec);
+                goto out;
+        }
     }
 
     // Get value
@@ -202,7 +253,7 @@
         {
             for (int n = DMGV_last; n >= 0; n--)
             {
-                const DMGrepDef *def = &dmGrepTypes[n];
+                const DMGrepType *def = &dmGrepTypes[n];
                 if (vval <= def->nmax)
                     vtype = n;
             }
@@ -230,13 +281,14 @@
     if (mode == FA_OFFSET)
     {
         if (vtype < 0)
-            vtype = DMGV_uint8;
+            vtype = DMGV_UINT8;
     }
 
     if (nsetGrepValues < SET_MAX_VALUES)
     {
         DMGrepValue *node = &setGrepValues[nsetGrepValues++];
         node->type = vtype;
+        node->disp = vdisp;
         node->value = vval;
 
         dmMsg(1, "Grep value %s : %d / 0x%x\n",
@@ -347,23 +399,23 @@
 
     switch (type)
     {
-        case DMGV_uint8:
-            *mval = *((uint8_t *) data);
+        case DMGV_UINT8:
+            *mval = *((Uint8 *) data);
             break;
 
-        case DMGV_uint16_le:
+        case DMGV_UINT16_LE:
             *mval = DM_LE16_TO_NATIVE(*((Uint16 *) data));
             break;
 
-        case DMGV_uint16_be:
+        case DMGV_UINT16_BE:
             *mval = DM_BE16_TO_NATIVE(*((Uint16 *) data));
             break;
 
-        case DMGV_uint32_le:
+        case DMGV_UINT32_LE:
             *mval = DM_LE32_TO_NATIVE(*((Uint32 *) data));
             break;
 
-        case DMGV_uint32_be:
+        case DMGV_UINT32_BE:
             *mval = DM_BE32_TO_NATIVE(*((Uint32 *) data));
             break;
 
@@ -432,7 +484,7 @@
             for (int n = 0; n < nsetGrepValues; n++)
             {
                 DMGrepValue *node = &setGrepValues[n];
-                const DMGrepDef *def = &dmGrepTypes[node->type];
+                const DMGrepType *def = &dmGrepTypes[node->type];
 
                 for (size_t offs = 0; offs + def->bsize < file->size; offs++)
                 {
@@ -470,7 +522,7 @@
         for (int n = 0; n < nsetGrepValues; n++)
         {
             DMGrepValue *node = &setGrepValues[n];
-            const DMGrepDef *def = &dmGrepTypes[node->type];
+            const DMGrepType *def = &dmGrepTypes[node->type];
             printf("%08x : ", node->value);
 
             for (int nfile = 0; nfile < nsrcFiles; nfile++)
@@ -484,7 +536,9 @@
                 {
                     char mfmt[16];
                     nwidth = def->bsize * 2;
-                    snprintf(mfmt, sizeof(mfmt), "%%0%dx", nwidth);
+                    snprintf(mfmt, sizeof(mfmt), "%%0%d%s",
+                        nwidth, dmGrepDisp[node->disp].fmt);
+
                     snprintf(mstr, sizeof(mstr), mfmt, mval);
                 }
                 else
@@ -502,7 +556,9 @@
                 for (int q = 0; q < npad; q++)
                     fputc(' ', stdout);
             }
-            fputs("\n", stdout);
+
+            printf("  [%s]\n",
+                dmGrepDisp[node->disp].name);
         }
     }
     else