Neale Pickett
·
2020-12-22
hd.c
1#include <getopt.h>
2#include <stdbool.h>
3#include <stdint.h>
4#include <stdio.h>
5#include <string.h>
6#include "glyphs.h"
7
8int dump(FILE *inf, bool verbose) {
9 uint64_t p = 0;
10 uint8_t buf[32];
11 int offset = 0;
12 int skipping = 0;
13
14 while (!feof(inf)) {
15 uint8_t *bytes = buf + offset;
16 size_t len;
17 int i;
18
19 offset = 16 - offset;
20
21 len = fread(bytes, 1, 16, inf);
22 if (0 == len)
23 break;
24
25 if (!verbose && p && (len == 16) && (0 == memcmp(buf, buf + 16, 16))) {
26 if (!skipping) {
27 printf("⋮\n");
28 skipping = 1;
29 }
30 p += 16;
31 continue;
32 } else {
33 skipping = 0;
34 }
35
36 printf("%08lx ", (long unsigned int)p);
37 for (i = 0; i < 16; i += 1) {
38 if (i < len) {
39 printf("%02x ", bytes[i]);
40 } else {
41 printf(" ");
42 }
43 if (7 == i) {
44 printf(" ");
45 }
46 }
47 printf(" ");
48 for (i = 0; i < len; i += 1) {
49 printf("%s", fluffyglyphs[bytes[i]]);
50 }
51 if (-1 == printf("\n")) {
52 perror("printf");
53 return 1;
54 }
55 p += len;
56 }
57 printf("%08lx\n", (long unsigned int)p);
58
59 return 0;
60}
61
62int main(int argc, char *argv[]) {
63 FILE *f;
64 bool verbose = false;
65 int c;
66
67 while ((c = getopt(argc, argv, "v")) != -1) {
68 switch (c) {
69 case -1:
70 break;
71 case 'v':
72 verbose = true;
73 break;
74 default:
75 fprintf(stderr, "Usage: %s [-v] [FILENAME]\n", argv[0]);
76 fprintf(stderr, "\n");
77 fprintf(stderr, "-v Verbose: don't elide output if output lines are identical\n");
78 return 1;
79 }
80 }
81
82 if (!argv[optind] || (0 == strcmp("-", argv[optind]))) {
83 f = stdin;
84 } else {
85 f = fopen(argv[optind], "rb");
86 if (!f) {
87 perror("open");
88 return 1;
89 }
90 }
91
92 dump(f, verbose);
93
94 return 0;
95}