#include #include #include #include #include #include #include #include "atables.h" const char **table = ata2utf; const char *inverse_on = "\x1b[7m"; const char *inverse_off = "\x1b[0m"; int verbose = 0, color = 1; const char *self; void set_self(const char *argv0) { char *p; self = argv0; p = strrchr(self, '/'); if(p) self = p + 1; } void die(const char *msg) { fprintf(stderr, "%s: %s\n", self, msg); exit(1); } void print_help(void) { printf("Usage: %s [-v] [file ...]\n", self); } FILE *open_input(const char *file) { FILE *input; if(file[0] == '-' && file[1] == 0) { if(verbose) fprintf(stderr, "%s: reading from standard input.\n", self); if(freopen(NULL, "rb", stdin)) { input = stdin; } else { perror("(standard input)"); return NULL; } } else if(!(input = fopen(file, "rb"))) { perror(file); return NULL; } if(verbose) fprintf(stderr, "%s: reading from file '%s'.\n", self, file); return input; } const char *color_off = "\x1b[0m"; char *get_color(unsigned char c) { int color; unsigned char c7 = c & 0x7f; static char outbuf[32]; if(c == 0 || c == 0x9b) { color = 1; /* red */ } else if(c7 < 32 || c7 == 0x60 || c7 == 0x7b || c7 == 0x7d || c7 == 0x7e || c7 == 0x7f) { color = 3; /* yellow/orange */ } else { color = 2; } if(color) { sprintf(outbuf, "\x1b[0;3%dm", color); if(c & 0x80) strcat(outbuf, inverse_on); } else { outbuf[0] = '\0'; } return outbuf; } void dump_line(const unsigned char *buf, int len) { char hex[1024], asc[1024]; static int filepos = 0; int hpos = 0, apos = 0, count = len; memset(hex, 0, sizeof(hex)); memset(asc, 0, sizeof(asc)); printf("%04x: ", filepos); while(len) { if(color) hpos += sprintf(hex + hpos, "%s", get_color(*buf)); hpos += sprintf(hex + hpos, "%02x", *buf); if(color) hpos += sprintf(hex + hpos, "%s", color_off); hex[hpos++] = ' '; if(count - len == 7) hex[hpos++] = ' '; if(*buf & 0x80) apos += sprintf(asc + apos, "%s", inverse_on); if(color) apos += sprintf(asc + apos, "%s", get_color(*buf)); apos += sprintf(asc + apos, "%s", table[*buf & 0x7f]); if(color || *buf & 0x80) apos += sprintf(asc + apos, "%s", color_off); filepos++; buf++; len--; } printf("%s", hex); /* what shall we use to fill the empty spaces? */ if(count < 8) putchar(' '); for(; count < 16; count++) fputs(" ", stdout); printf(" %s\n", asc); } int a8xd(const char *file) { FILE *input; int c, len = 0; unsigned char buf[16]; if( !(input = open_input(file)) ) return 1; while( (c = fgetc(input)) != EOF ) { if(len && (len % 16 == 0)) { dump_line(buf, len); len = 0; } buf[len++] = c; } if(len) dump_line(buf, len); return 0; } int main(int argc, char **argv) { int opt, result = 0; set_self(argv[0]); if(argc > 1 && strcmp(argv[1], "--help") == 0) { print_help(); exit(0); } if(argc > 1 && strcmp(argv[1], "--version") == 0) { printf("%s %s\n", self, VERSION); exit(0); } while( (opt = getopt(argc, argv, "vim")) != -1) { switch(opt) { case 'v': verbose = 1; break; case 'i': table = ics2utf; break; case 'm': color = 0; break; default: print_help(); exit(1); break; } } if(optind >= argc) { result = a8xd("-"); } else { while(optind < argc) { result += a8xd(argv[optind]); optind++; } } exit(result); }