Subject: Re: bin/21058: Teach unexpand -t
To: David Laight <david@l8s.co.uk>
From: Martin Weber <Ephaeton@gmx.net>
List: netbsd-bugs
Date: 04/07/2003 23:56:24
On Mon, Apr 07, 2003 at 10:38:30PM +0100, David Laight wrote:
> > >Synopsis:       Teach unexpand -t <tabstop>
> 
> Whether this is a good idea or not.

Why could it be a bad idea ?

> (...)
> strtoul() is better than atoi()...

changed

> (...)
> A little verbose :-)

oops! *blush* awkward... great...

> (...)
> Not enough ' ' chars...

Huh ? where, why ? *eye*

> Also there are some optimisations that ought to be done to avoid
> all the (expensive) divisions.

Well, didn't know how I could do the same as the &~07 for values
like e.g. 5. Changed/Fixed patch attached.

----- unexpand.c, take 2 -----
--- /usr/src/usr.bin/unexpand/unexpand.c	1999-02-11 16:29:14.000000000 +0100
+++ unexpand.c	2003-04-07 23:51:28.000000000 +0200
@@ -58,25 +58,32 @@
 char	linebuf[BUFSIZ];
 
 int	main __P((int, char **));
-void tabify __P((int));
+void tabify __P((int, int));
 
 int
 main(argc, argv)
 	int argc;
 	char *argv[];
 {
-	int all, c;
-	char *cp;
+	int all, c, tabsize;
+	char *cp, *ep;
 
-	all = 0;
-	while ((c = getopt(argc, argv, "a")) != -1) {
+	tabsize = all = 0;
+	while ((c = getopt(argc, argv, "at:")) != -1) {
 		switch (c) {
 		case 'a':
 			all++;
 			break;
+		case 't':
+			tabsize=(int) strtoul(optarg, &ep, 10);
+			if (*ep != '\0' || tabsize==0) {
+				fprintf(stderr, "unexpand: Invalid tabstop argument!\n");
+				exit(EXIT_FAILURE);
+			}
+			break;
 		case '?':
 		default:
-			fprintf(stderr, "usage: unexpand [-a] [file ...]\n");
+			fprintf(stderr, "usage: unexpand [-a] [-t tabstop] [file ...]\n");
 			exit(EXIT_FAILURE);
 			/* NOTREACHED */
 		}
@@ -97,7 +104,7 @@
 				continue;
 			if (cp > linebuf)
 				cp[-1] = 0;
-			tabify(all);
+			tabify(all, tabsize);
 			printf("%s", linebuf);
 		}
 	} while (argc > 0);
@@ -106,8 +113,9 @@
 }
 
 void
-tabify(c)
+tabify(c, sz)
 	int c;
+	int sz;
 {
 	char *cp, *dp;
 	int dcol;
@@ -124,17 +132,17 @@
 			break;
 
 		case '\t':
-			dcol += 8;
-			dcol &= ~07;
+			dcol += sz;
+			dcol = (dcol/sz) * sz;
 			break;
 
 		default:
-			while (((ocol + 8) &~ 07) <= dcol) {
+			while ((((ocol + sz)/sz)*sz) <= dcol) {
 				if (ocol + 1 == dcol)
 					break;
 				*dp++ = '\t';
-				ocol += 8;
-				ocol &= ~07;
+				ocol += sz;
+				ocol=(ocol/sz) * sz;
 			}
 			while (ocol < dcol) {
 				*dp++ = ' ';
--
-Martin