From 50ca48a287d277e15a4c6b71c1ee09e7cf607364 Mon Sep 17 00:00:00 2001 From: Laurent MAZET Date: Thu, 23 Jan 2025 14:53:11 +0100 Subject: [PATCH] add hexa mode --- display.c | 30 ++++++++++++++----- fm.c | 4 +-- function.c | 84 ++++++++++++++++++++++++++++++++++++++++++++---------- function.h | 6 +++- 4 files changed, 99 insertions(+), 25 deletions(-) diff --git a/display.c b/display.c index c7433f3..d0f4e1b 100644 --- a/display.c +++ b/display.c @@ -537,18 +537,27 @@ char *filewindow (char *name, window_t *win) " Help message\n" " Move up\n" " Move down\n" - " Quit view mode\n" + " Change mode\n" + " 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 db80499..09ed7b3 100644 --- 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 */ diff --git a/function.c b/function.c index adfb09a..e4d2390 100644 --- a/function.c +++ b/function.c @@ -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: */ diff --git a/function.h b/function.h index 0aaac12..20d20d6 100644 --- a/function.h +++ b/function.h @@ -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: */ -- 2.30.2