Colorized Character Dumper
I have noticed that when i use the hexdump tool, it is most often together with the -C option just to look at the characters. Hexdump is a bit limited, so I decided to make another tool specialized for character dumping. Instead of just printing a dot for non-printable characters, this tool will use a colorized printable character. Escape characters for instance, are represented in green. The tool also tries to use as much terminal real-estate as possible, so it will look at the current column width to expand itself.
Here is how it looks when dumping a binary file. (Actually itself.):
To keep it simple, I just used the standard ANSI way of drawing colors. An alternative would have been to use (n)curses. Check out the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
static void fputc_color(int c, FILE *fh)
{
/* Based on vim's "unprintable" definition instead of ctype's isprint(). */
if (c < 0x20) /* Escape characters. */
fprintf(fh, "\e[32m%c\e[0m", c + 0x40);
else if (c < 0x7F) /* Standard ASCII characters. */
fputc(c, fh);
else if (c == 0x7F) /* The DEL character. */
fprintf(fh, "\e[32m%c\e[0m", '?');
else if (c < 0xA1) /* Special unprintable characters and the NBSP. */
fprintf(fh, "\e[31m%c\e[0m", c - 0x40);
else /* "High" (Latin-1) characters. */
fprintf(fh, "\e[33m%c\e[0m", c);
}
static void dump_file(FILE *fh, int columns, int in_color)
{
int c, n;
columns -= 12; /* Subtract the extra visualization. */
n = 0;
while ((c = fgetc(fh)) != EOF) {
if (n % columns == 0) {
if (n > 0)
printf("|\n");
printf("%08x |", n);
}
if (in_color) {
fputc_color(c, stdout);
} else {
if (isprint(c))
fputc(c, stdout);
else
fputc('.', stdout);
}
n++;
}
if (n % columns < columns)
printf("|\n");
}
static void display_banner(char *text, int columns)
{
int i;
printf("--- %s ", text);
for (i = (strlen(text) + 5); i < columns; i++)
printf("-");
printf("\n");
}
int main(int argc, char *argv[])
{
int i, columns, in_color;
char *p;
FILE *fh;
p = getenv("COLUMNS");
if (p == NULL)
columns = 80; /* Default, and most likely. */
else
columns = atoi(p);
in_color = 0;
if (isatty(STDOUT_FILENO)) {
p = getenv("TERM");
if (p != NULL) {
if (strncmp(p, "xterm", 5) == 0)
in_color = 1;
}
}
if (argc > 1) {
for (i = 1; i < argc; i++) {
fh = fopen(argv[i], "r");
if (fh == NULL)
continue;
if (argc > 2)
display_banner(argv[i], columns);
dump_file(fh, columns, in_color);
fclose(fh);
}
} else
dump_file(stdin, columns, in_color);
return 0;
}