hexv.c (2203B)
1#include <fcntl.h> 2#include <unistd.h> 3#include <err.h> 4#include <errno.h> 5 6#include <stdlib.h> 7#include <string.h> 8#include <stdio.h> 9#include <stdint.h> 10#include <stdbool.h> 11 12static const char hex[] = "0123456789abcdef"; 13 14static int color = 0; 15static int gradient[256] = { 16 [0] = 241, 17 [1 ... 31] = 242, 18 [32 ... 63] = 244, 19 [64 ... 95] = 246, 20 [96 ... 127] = 247, 21 [128 ... 159] = 248, 22 [160 ... 191] = 250, 23 [192 ... 223] = 252, 24 [224 ... 254] = 254, 25 [255] = 255, 26}; 27 28/* command-line arguments */ 29static bool newline_aware = false; 30 31void 32colorhex(uint8_t c) 33{ 34 if (gradient[c] != color) { 35 color = gradient[c]; 36 printf("\x1b[38;5;%im", color); 37 } 38 putchar(hex[(c >> 4) & 0xf]); 39 putchar(hex[(c >> 0) & 0xf]); 40} 41 42void 43printrow(char *row, size_t pos, size_t len) 44{ 45 size_t i; 46 47 printf("%08lx: ", pos); 48 for (i = 0; i < 16; i++) { 49 if (i < len) { 50 colorhex(row[i]); 51 } else { 52 printf(" "); 53 } 54 if ((i + 1) % 2 == 0) 55 putchar(' '); 56 } 57 if (color != 0) 58 printf("\x1b[0m"); 59 color = 0; 60 61 printf(" "); 62 63 for (i = 0; i < 16; i++) { 64 if (i < len) { 65 if (row[i] >= 0x20 && row[i] <= 126) { 66 putchar(row[i]); 67 } else { 68 putchar('.'); 69 } 70 } else { 71 putchar(' '); 72 } 73 } 74 printf("\n"); 75} 76 77void 78tohex(int fd) 79{ 80 size_t last, pos, i, k; 81 ssize_t nread; 82 char buf[4096]; 83 char row[16]; 84 85 last = pos = 0; 86 while (1) { 87 nread = read(fd, buf, sizeof(buf)); 88 if (nread <= 0) break; 89 90 for (i = 0; i < nread; i++, pos++) { 91 row[pos - last] = buf[i]; 92 if (pos == last + 15 || buf[i] == '\n' && newline_aware) { 93 printrow(row, last, pos - last + 1); 94 last = pos + 1; 95 } 96 } 97 } 98 99 if (pos != last) 100 printrow(row, last, pos - last); 101} 102 103int 104main(int argc, const char **argv) 105{ 106 const char **arg, **farg; 107 int fd; 108 109 if (argc < 1) return 1; 110 111 for (arg = argv + 1; *arg; arg++) { 112 if (!strcmp(*arg, "-n") || !strcmp(*arg, "--newline-aware")) { 113 newline_aware = true; 114 } else { 115 break; 116 } 117 } 118 119 if (*arg) { 120 for (farg = arg; *farg; farg++) { 121 if (farg != arg) printf("\n"); 122 fd = open(*farg, O_RDONLY); 123 if (fd < 0) { 124 fprintf(stderr, "hexv: open '%s': %s", 125 *farg, strerror(errno)); 126 continue; 127 } 128 tohex(fd); 129 close(fd); 130 } 131 } else { 132 tohex(0); 133 } 134} 135