"<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;
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);
skip++;
}
break;
+ case 'm':
+ mode = (mode) ? 0 : 1;
+ break;
}
}
set_color (white);
- freelines (lines);
+ freelines (hexa);
+ freelines (std);
return NULL;
}
/* 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 */
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;
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);
}
}
}
+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: */
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: */