ref: ea234b61b3258a71793584c729427da8264e9a2f
dir: /hx.c/
#ifdef __unix__ #ifdef __linux__ #define _GNU_SOURCE #else #define _DEFAULT_SOURCE #endif #define _FILE_OFFSET_BITS 64 #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define OREAD O_RDONLY #define nil NULL #define exits(s) do { return (s) != nil; } while (0) typedef size_t u64int; #else #include <u.h> #include <libc.h> #endif enum { Bufsz = 4*1024*1024, Linesz = 87, }; static int section = 0, pipeit = 0; static unsigned char *buf; static const char b2h[] = ( "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf" "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf" "e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" ); static int hx(int fd) { u64int addr; long sz, i; char s[65536], c; unsigned char line[16]; int wroff, off, eof, lineoff, r; again: #ifdef __linux__ readahead(fd, 0, Bufsz); #endif lineoff = 0; off = 0; eof = 0; sz = 0; for (addr = 0; eof == 0;) { if ((sz = read(fd, buf, Bufsz)) < 1) { section = 0; break; } if (pipeit > 0) write(pipeit, buf, sz); for (i = 0; i < sz; ) { if (lineoff == 0) { s[off++] = b2h[((addr>>55) & 0x1fe)]; s[off++] = b2h[((addr>>55) & 0x1fe)+1]; s[off++] = b2h[((addr>>47) & 0x1fe)]; s[off++] = b2h[((addr>>47) & 0x1fe)+1]; s[off++] = b2h[((addr>>39) & 0x1fe)]; s[off++] = b2h[((addr>>39) & 0x1fe)+1]; s[off++] = b2h[((addr>>31) & 0x1fe)]; s[off++] = b2h[((addr>>31) & 0x1fe)+1]; s[off++] = b2h[((addr>>23) & 0x1fe)]; s[off++] = b2h[((addr>>23) & 0x1fe)+1]; s[off++] = b2h[((addr>>15) & 0x1fe)]; s[off++] = b2h[((addr>>15) & 0x1fe)+1]; s[off++] = b2h[((addr>>7) & 0x1fe)]; s[off++] = b2h[((addr>>7) & 0x1fe)+1]; s[off++] = b2h[((addr<<1) & 0x1fe)]; s[off++] = b2h[((addr<<1) & 0x1fe)+1]; s[off++] = ' '; s[off++] = ' '; } for (; i < sz && lineoff < 16; i++, addr++) { if (lineoff < 16) line[lineoff++] = buf[i]; s[off++] = b2h[(int)buf[i]*2+0]; s[off++] = b2h[(int)buf[i]*2+1]; s[off++] = ' '; if (lineoff == 8) s[off++] = ' '; } if (lineoff == 16) { ascii: s[off++] = ' '; s[off++] = '|'; for (lineoff = 0; lineoff < 16; lineoff++) { c = line[lineoff]; if (c < 0x20 || c > 0x7e) c = '.'; s[off++] = c; } s[off++] = '|'; s[off++] = '\n'; lineoff = 0; } if (off >= (int)sizeof(s)-Linesz) { writes: for (wroff = 0; wroff < off; wroff += r) { if ((r = write(pipeit+1, s+wroff, off-wroff)) < 0) { sz = -1; break; } } off = 0; } } if (section) break; if (sz == 0) continue; #ifdef __linux__ readahead(fd, addr, Bufsz); #endif sz = 0; goto writes; } if (sz >= 0) { if (eof == 0 && lineoff > 0 && lineoff < 16) { eof = 1; if (lineoff == 8) off--; for (; lineoff < 16; lineoff++) { line[lineoff] = 0; s[off++] = ' '; s[off++] = ' '; s[off++] = ' '; if (lineoff == 8) s[off++] = ' '; } i = sz = 0; goto ascii; } for (wroff = 0; wroff < off; wroff += r) { if ((r = write(pipeit+1, s+wroff, off-wroff)) < 0) { sz = -1; break; } } } if (section) { write(pipeit+1, "\n", 1); goto again; } return sz != 0; } #ifdef __unix__ int #else void #endif main(int argc, char **argv) { int i, fd, res, opts; if ((buf = malloc(Bufsz)) == nil) { perror("buf"); exits("buf"); } res = 0; opts = 0; for (i = 1; i < argc && res == 0; i++) { if (argv[i][0] == '-' && argv[i][2] == 0) { switch (argv[i][1]) { case 's': section = 1; opts++; break; case 'p': pipeit = 1; opts++; break; default: write(2, "unknown option: -", 17); write(2, argv[i]+1, 1); write(2, "\n", 1); exits("usage"); } if (opts == argc-1) { fd = 0; goto dump; } continue; } if ((fd = open(argv[i], OREAD)) < 0) { perror(argv[i]); res = 1; } else { if (argc > 2+opts) { write(pipeit+1, "hx ", 3); write(pipeit+1, argv[i], strlen(argv[i])); write(pipeit+1, "\n", 1); } dump: if ((res = hx(fd)) != 0) perror(argv[1]); close(fd); } } memset(buf, 0, Bufsz); free(buf); exits(res == 0 ? nil : "error"); }