rendered paste body--- /home/garrett/od.almost.c Mon Oct 18 11:21:59 2010+++ /home/garrett/od.c Mon Oct 18 20:45:49 2010@@ -63,16 +63,14 @@ */ typedef struct buffer {- char *data[3];- int count[3];- int cons;+ char *data; int prod;- int navail; /* total bytes avail, in both buffers */+ int cons;+ int mask;+ int size;+ int navail; /* total bytes avail */ } buffer_t; -#define NEXTWHICH(i) ((i) == 2 ? 0 : ((i) + 1))-#define PREVWHICH(i) ((i) == 0 ? 2 : ((i) - 1))- typedef struct output { int ncol; void (*func)(struct buffer *, int);@@ -107,11 +105,7 @@ static typ \ get_ ## typ(buffer_t *b, int index) \ { \- typ val = *(typ *)(void *)(b->data[b->cons] + (index)); \- b->count[b->cons] -= sizeof (typ); \- if (b->count[b->cons] == 0) { \- b->cons = NEXTWHICH(b->cons); \- } \+ typ val = *(typ *)(void *)(b->data + index); \ return (val); \ } DECL_GET(u8)@@ -128,7 +122,7 @@ #define DECL_OUT(nm, typ, fmt) \ static void \-do_ ## nm(buffer_t *buf, int index) \+do_ ## nm(buffer_t *buf, int index) \ { \ typ v = get_ ## typ(buf, index); \ (void) printf(fmt, v); \@@ -194,6 +188,7 @@ do_char(buffer_t *buf, int index) { static int nresid = 0;+ static int printable = 0; int cnt; int avail; int nb;@@ -209,7 +204,11 @@ * indication. */ if (nresid) {- (void) fputs(" **", stdout);+ if (printable) {+ (void) fputs(" **", stdout);+ } else {+ (void) printf(" %03o", v);+ } nresid--; return; }@@ -223,28 +222,32 @@ avail = buf->navail; if (avail > MB_CUR_MAX) avail = MB_CUR_MAX;- which = buf->cons;- index++;- for (cnt = 1; cnt < avail; cnt++) {- if (index == blocksize) {- index = 0;- which = NEXTWHICH(which);- }- scratch[cnt] = *(buf->data[which] + index);- index++;+ for (cnt = 1, which = index + 1; cnt < avail; cnt++, which++) {+ scratch[cnt] = buf->data[which & buf->mask]; } /* now see if the value is a real character */ nresid = 0;+ wc = 0; nb = mbtowc(&wc, scratch, avail);- if (nb <= 0) {+ if (nb < 0) { (void) printf(" %03o", v);- } else if (iswprint(wc)) {+ return;+ }+ if (nb == 0) {+ (void) fputs(" \\0", stdout);+ return;+ }+ nresid = nb - 1;+ if (nb && iswprint(wc)) { scratch[nb] = 0; (void) fputs(" ", stdout); (void) fputs(scratch, stdout);- nresid = nb - 1;- } else if (wc == 0) {+ printable = 1;+ return;+ }+ printable = 0;+ if (wc == 0) { (void) fputs(" \\0", stdout); } else if (wc == '\b') { (void) fputs(" \\b", stdout);@@ -258,7 +261,6 @@ (void) fputs(" \\t", stdout); } else { (void) printf(" %03o", v);- nresid = 0; } } @@ -304,13 +306,13 @@ return (NULL); if (input) {- if ((input = freopen64(files[curfile], "r", input)) !=+ if ((input = freopen(files[curfile], "r", input)) != NULL) { curfile++; return (input); } } else {- if ((input = fopen64(files[curfile], "r")) != NULL) {+ if ((input = fopen(files[curfile], "r")) != NULL) { curfile++; return (input); }@@ -325,7 +327,7 @@ { int n; int want;- char *wptr;+ int zero; /* * If we have 2 blocks bytes available, we're done. Note that each@@ -334,15 +336,8 @@ */ while (input && (b->navail < (2 * blocksize))) { - if (b->count[b->prod]) {- b->prod = NEXTWHICH(b->prod);- }- /* we preload the next one in advance */- wptr = b->data[b->prod]; - (void) memset(wptr, 0, blocksize);- if (limit == 0) { (void) fclose(input); input = NULL;@@ -354,9 +349,16 @@ if ((limit >= 0) && (want > limit)) { want = limit; }+ zero = blocksize; while (want && input) {- n = fread(wptr, 1, want, input);+ int c;+ b->prod &= b->mask;+ c = (b->prod + want > (b->mask + 1)) ?+ b->mask - b->prod :+ want;++ n = fread(b->data + b->prod, 1, c, input); if (n < 0) { warn("read: %s", files ? files[curfile-1] : "stdin");@@ -370,10 +372,17 @@ if (limit >= 0) limit -= n; b->navail += n;- b->count[b->prod] += n;- wptr += n;+ b->prod += n; want -= n;+ zero -= n; }++ while (zero) {+ b->data[b->prod & b->mask] = 0;+ b->prod++;+ b->prod &= b->mask;+ zero--;+ } } } @@ -517,11 +526,11 @@ int c; int i; buffer_t buffer;- int didone = 0;+ int first = 1; int doall = 0; int same = 0;- off64_t offset = 0;- off64_t skip = 0;+ off_t offset = 0;+ off_t skip = 0; char *eptr; input = stdin;@@ -680,10 +689,12 @@ } } - for (i = 0; i < 3; i++) {- if ((buffer.data[i] = memalign(blocksize, blocksize)) == NULL) {- err(1, "memalign");- }+ /* this finds the smallest power of two size we can use */+ buffer.size = (1 << (ffs(blocksize * 3) + 1));+ buffer.mask = buffer.size - 1;+ buffer.data = memalign(16, buffer.size);+ if (buffer.data == NULL) {+ err(1, "memalign"); } /*@@ -704,13 +715,13 @@ * We need to seek ahead. fseek would be faster. */ while (skip && input) {- struct stat64 sbuf;+ struct stat sbuf; /* * Only fseek() on regular files. (Others * we have to read(). */- if (fstat64(fileno(input), &sbuf) < 0) {+ if (fstat(fileno(input), &sbuf) < 0) { warn("fstat: %s", files[curfile-1]); input = next_input(); continue;@@ -725,7 +736,7 @@ input = next_input(); continue; }- if (fseeko64(input, skip, SEEK_SET) < 0) {+ if (fseeko(input, skip, SEEK_SET) < 0) { err(1, "fseek:%s", files[curfile-1]); } /* Done seeking. */@@ -756,50 +767,60 @@ buffer.navail = 0; buffer.prod = 0; buffer.cons = 0;- buffer.count[0] = 0;- buffer.count[1] = 0;- buffer.count[2] = 0; for (refill(&buffer); buffer.navail > 0; refill(&buffer)) { output_t *out;- char *data, *prev; int mx;+ int j, k; - data = buffer.data[buffer.cons];- prev = buffer.data[PREVWHICH(buffer.cons)];- /* * If this buffer was the same as last, then just * dump an asterisk. */- if (didone && (buffer.navail >= blocksize) && (!doall) &&- (memcmp(data, prev, blocksize) == 0)) {- if (!same) {- (void) fputs("*\n", stdout);+ if ((!first) && (buffer.navail >= blocksize) && (!doall)) {+ j = buffer.cons;+ k = j - blocksize;+ for (i = 0; i < blocksize; i++) {+ if (buffer.data[j & buffer.mask] !=+ buffer.data[k & buffer.mask]) {+ break;+ }+ j++;+ k++; }- buffer.navail -= blocksize;- same = 1;- offset += blocksize;- continue;+ if (i == blocksize) {+ if (!same) {+ (void) fputs("*\n", stdout);+ same = 1;+ }+ buffer.navail -= blocksize;+ offset += blocksize;+ buffer.cons += blocksize;+ buffer.cons &= buffer.mask;+ continue;+ } } - didone = 1;+ first = 0; same = 0; mx = (buffer.navail > blocksize) ? blocksize : buffer.navail; for (out = head; out != NULL; out = out->next) { - if (out == head) { (void) printf(afmt, offset); } else { (void) fputs(cfmt, stdout); }- for (i = 0; i < mx; i += out->ncol) {- out->func(&buffer, i);+ for (i = 0, j = buffer.cons; i < mx; i += out->ncol) {+ out->func(&buffer, j);+ j += out->ncol;+ j &= buffer.mask; } (void) fputs("\n", stdout); }+ buffer.cons += mx;+ buffer.cons &= buffer.mask; offset += mx; buffer.navail -= mx; }