All pastes #1966521 Raw Edit

diff of od.c changes

public c v1 · immutable
#1966521 ·published 2010-10-19 03:58 UTC
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; 	}