add hexa mode
authorLaurent MAZET <laurent.mazet@thalesgroup.com>
Thu, 23 Jan 2025 13:53:11 +0000 (14:53 +0100)
committerLaurent MAZET <laurent.mazet@thalesgroup.com>
Fri, 24 Jan 2025 08:30:12 +0000 (09:30 +0100)
display.c
fm.c
function.c
function.h

index c7433f35912fe189d7d56e3f00d0753520b9c899..d0f4e1b9203bd9ca6fc5e29cd6a2867d59b3b3b8 100644 (file)
--- a/display.c
+++ b/display.c
@@ -537,18 +537,27 @@ char *filewindow (char *name, window_t *win)
         "<h> Help message\n"
         "<i> Move up\n"
         "<k> Move down\n"
-        "<q> Quit view mode\n"
+        "<m> Change mode\n"
+        "<q> Quit view\n"
         ;
 
-    char *buffer = loadfile (name);
+    int length = 0;
+    char *buffer = loadfile (name, &length);
     if (buffer == NULL) {
         return strdupcat ("Can't open file '", name, "'", NULL);
     }
-    char **lines = splitlines (buffer, win->xsize);
+    char **hexa = splithexalines (buffer, length, win->xsize);
+    masknonprintable (buffer, length);
+    char **std = splitlines (buffer, win->xsize);
     free (buffer);
-    int len = 0;
-    while (lines[len] != NULL) {
-        len++;
+
+    int lenhexa = 0;
+    while (hexa[lenhexa] != NULL) {
+        lenhexa++;
+    }
+    int lenstd = 0;
+    while (std[lenstd] != NULL) {
+        lenstd++;
     }
     char *basename = strrchr (name, *SEPARATOR);
     basename = (basename) ? basename + 1 : name;
@@ -556,8 +565,11 @@ char *filewindow (char *name, window_t *win)
     set_color (black);
     int skip  = 0;
     int stop = 0;
+    int mode = 1;
     while (!stop) {
         int i, j;
+        char **lines = (mode) ? std : hexa;
+        int len = (mode) ? lenstd : lenhexa;
 
         _dobound (win->xsize, win->ysize, win->xoffset, win->yoffset);
 
@@ -639,11 +651,15 @@ char *filewindow (char *name, window_t *win)
                 skip++;
             }
             break;
+        case 'm':
+            mode = (mode) ? 0 : 1;
+            break;
         }
     }
     set_color (white);
 
-    freelines (lines);
+    freelines (hexa);
+    freelines (std);
 
     return NULL;
 }
diff --git a/fm.c b/fm.c
index db8049920141931bedf8043587e94415ea0bd74a..09ed7b3d3e52efe345853a88bed5c800fa58c5a0 100644 (file)
--- a/fm.c
+++ b/fm.c
@@ -594,10 +594,10 @@ int main (int argc, char *argv[])
 /* test: ln -s .b .a && { sleep 1; echo -en 'k\es'; sleep 1; echo -en '\ex'; sleep 1; echo; sleep 1; echo ; sleep 1; echo -en '\eq'; sleep 1; echo -n y; } | fm.exe && rm .a */
 
 /* View */
-/* test: echo -ne 'Begin\n  This is a test\nEnd' > .a && { sleep 1; echo -n 'k'; sleep 1; echo; sleep 1; echo -n kkk; sleep 1; echo -n iii; sleep 1; echo -n h; sleep 1; echo; sleep 1;  echo -n q; sleep 1; echo -en '\eq'; sleep 1; echo -n y; } | fm.exe -x 60 -y 20 && rm .a */
+/* test: echo -ne 'Begin\n  This is a test\nEnd' > .a && { sleep 1; echo -n 'k'; sleep 1; echo; sleep 1; echo -n kkk; sleep 1; echo -n iii; sleep 1; echo -n h; sleep 1; echo; sleep 1;  echo -n m; sleep 1; echo -n q; sleep 1; echo -en '\eq'; sleep 1; echo -n y; } | fm.exe -x 60 -y 20 && rm .a */
 /* test: cp fm.c .a && { sleep 1; echo -n 'k'; sleep 1; echo -en '\ev'; sleep 1; for i in $(seq 1 1000); do echo -n k; done; sleep 1; for i in $(seq 1 1000); do echo -n i; done; sleep 1; sleep 1;  echo -n q; sleep 1; echo -en '\eq'; sleep 1; echo -n y; } | fm.exe -x 60 -y 20 && rm .a */
 /* test: cp fm.c .a && { sleep 1; echo -n 'k'; sleep 1; echo -en '\ev'; sleep 1; echo -n KKKK; sleep 1; echo -n IIII; sleep 1; echo -n q; sleep 1; echo -en '\eq'; sleep 1; echo -n y; } | fm.exe -x 60 -y 20 && rm .a */
-/* test: cp debug.o .a && { sleep 1; echo -n 'k'; sleep 1; echo -en '\ev'; sleep 1; for i in $(seq 1 100); do echo -n k; done; sleep 1; for i in $(seq 1 100); do echo -n i; done; sleep 1; echo -n q; sleep 1; echo -en '\eq'; sleep 1; echo -n y; } | fm.exe -x 60 -y 20 && rm .a */
+/* test: cp debug.o .a && { sleep 1; echo -n 'k'; sleep 1; echo -en '\ev'; sleep 1; for i in $(seq 1 100); do echo -n k; done; sleep 1; for i in $(seq 1 100); do echo -n i; done; sleep 1; echo -n m; sleep 1; echo -n q; sleep 1; echo -en '\eq'; sleep 1; echo -n y; } | fm.exe -x 60 -y 20 && rm .a */
 /* test: mkdir .a && { sleep 1; echo -n 'k'; sleep 1; echo -en '\ev'; sleep 1; echo; sleep 1; echo -en '\eq'; sleep 1; echo -n y; } | fm.exe -x 60 -y 20 && rmdir .a */
 /* test: ln -s .b .a && { sleep 1; echo -n 'k'; sleep 1; echo -en '\ev'; sleep 1; echo; sleep 1; echo -en '\eq'; sleep 1; echo -n y; } | fm.exe -x 60 -y 20 && rm .a */
 
index adfb09adcfb8a94825554cda0355b4e31a16716a..e4d2390c5b084657b8ecaf81c0048a25c9bae3e0 100644 (file)
@@ -635,39 +635,45 @@ char *processchmod (char *name, int mode)
     return msg;
 }
 
-static char *_readstream (FILE *sd)
+void masknonprintable (char *buffer, int length)
+{
+    unsigned char *pt = (unsigned char *)buffer;
+    while (length-- > 0) {
+        if ((*pt != '\n') && ((*pt < 32) || (*pt >= 127))) {
+            *pt = 128;
+        }
+        pt++;
+    }
+}
+
+static char *_readstream (FILE *sd, int *length)
 {
     char *buffer = NULL;
     size_t size = 0;
     int blocklen = 0;
-    int length = 0;
+    int _length = 0;
     do {
         size += BUFMAX + (size == 0);
         buffer = (char *) realloc (buffer, size);
         memset (buffer + size - BUFMAX - 1, 0, BUFMAX + 1);
         blocklen = fread (buffer + size - BUFMAX - 1, 1, BUFMAX, sd);
-        length += blocklen;
+        _length += blocklen;
     } while (blocklen > 0);
 
     /* check size */
-    VERBOSE (DEBUG, fprintf (stderr, "length: %d\n", length));
-    if (length == 0) {
+    VERBOSE (DEBUG, fprintf (stderr, "length: %d\n", _length));
+    if (_length == 0) {
         free (buffer);
         buffer = NULL;
-    } else {
-        unsigned char *pt = (unsigned char *)buffer;
-        while (length-- > 0) {
-            if ((*pt != '\n') && ((*pt < 32) || (*pt >= 127))) {
-                *pt = 128;
-            }
-            pt++;
-        }
+    }
+    if (length) {
+        *length = _length;
     }
 
     return buffer;
 }
 
-char *loadfile (char *name)
+char *loadfile (char *name, int *length)
 {
     int status = -1;
     char *buffer = NULL;
@@ -675,7 +681,7 @@ char *loadfile (char *name)
     VERBOSE (DEBUG, fprintf (stdout, "open file: %s\n", name));
     FILE *fd = fopen (name, "rb");
     if (fd != NULL) {
-        buffer = _readstream (fd);
+        buffer = _readstream (fd, length);
         status = fclose (fd);
     }
 
@@ -733,4 +739,52 @@ void freelines (char **lines)
     }
 }
 
+int _getnbdigits (int l) {
+    int n = 0;
+    while (l) {
+        n += 2;
+        l /= 256;
+    }
+    return n;
+}
+
+char *_newhexaline (char *buffer, int nb, int addr, int nbdigits, int nbcols) {
+    int i;
+
+    char *line = (char *) calloc (7 + nbdigits + 4 * nbcols, 1);
+    CHECKALLOC (line);
+
+    int l = sprintf (line, "0x%0*x:", nbdigits, addr);
+
+    for (i = 0; i < nb; i++) {
+        l += sprintf (line + l, " %02x", (unsigned char)buffer[i]);
+    }
+    for (i = nb; i < nbcols; i++) {
+        l += sprintf (line + l, "   ");
+    }
+
+    l += sprintf (line + l, "  ");
+
+    for (i = 0; i < nb; i++) {
+        char c = buffer[i];
+        l += sprintf (line + l, "%c", (c > 31) && (c < 127) ? c : '.');
+    }
+
+    return line;
+}
+
+char **splithexalines (char *buffer, int length, int width)
+{
+    int nbdigits = _getnbdigits (length);
+    int nbcols = (width - 7 - nbdigits) / 4;
+    int nblines = (length + nbcols - 1) / nbcols;
+    char **lines = (char **) calloc (nblines + 1, sizeof (char *));
+    int i;
+    for (i = 0; i < nblines; i++) {
+        int nb = min (length - i * nbcols, nbcols);
+        lines[i] = _newhexaline (buffer + i * nbcols, nb, i * nbcols, nbdigits, nbcols);
+    }
+    return lines;
+}
+
 /* vim: set ts=4 sw=4 et: */
index 0aaac12eff3536ed224dd5d768e4a7b1bfe611f9..20d20d63f6403ce54991ed916a33d18fbee22113 100644 (file)
@@ -59,12 +59,16 @@ char *processmove (char *dest, char *src);
 
 char *processchmod (char *name, int mode);
 
-char *loadfile (char *name);
+char *loadfile (char *name, int *length);
+
+void masknonprintable (char *buffer, int length);
 
 char **splitlines (char *buffer, int max);
 
 void freelines (char **lines);
 
+char **splithexalines (char *buffer, int length, int width);
+
 #endif /* __FUNCTION_H__ */
 
 /* vim: set ts=4 sw=4 et: */