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; }