Subject: bin/21058: Teach unexpand -t
To: None <gnats-bugs@gnats.netbsd.org>
From: Martin Weber <Ephaeton@gmx.net>
List: netbsd-bugs
Date: 04/07/2003 23:20:10
>Number:         21058
>Category:       bin
>Synopsis:       Teach unexpand -t <tabstop>
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Mon Apr 07 14:21:00 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Martin Weber
>Release:        NetBSD 1.6Q
>Organization:
	Entropie Erlangen
	
>Environment:
	
	
System: NetBSD phaeton.entropie.net 1.6Q NetBSD 1.6Q (FAETON) #0: Sat Apr 5 18:17:16 CEST 2003 root@phaeton.entropie.net:/usr/obj/sys/arch/i386/compile/FAETON i386
/usr/src/usr.bin/expand/expand.1:
     $NetBSD: expand.1,v 1.7 2002/09/30 11:08:59 grant Exp $
/usr/src/usr.bin/unexpand/unexpand.c:
     $NetBSD: unexpand.c,v 1.8 1999/02/11 15:29:14 kleink Exp $
Architecture: i386
Machine: i386
>Description:
	expand is taking an argument -t <tabstop> which lets you specify an alternate
	tabstop (i.e. spaces to insert instead of a \t) to use. unexpand is quite stubborn
	about handling tabs, for it always assumes a tabsize of 8. That is annoying if you
	use e.g. -t 2 for "visual compressing" and want to turn it back into tabs with
	unexpand before working on it (like in email communication). So I think an unexpand
	option -t <tabstop> would be nice.
	
>How-To-Repeat:
	printf "\t\tx!\n" | expand -t 4 | unexpand
	>> get "\tx!\n"
	printf "\t\tx!\n" | expand -t 2 | unexpand
	>> get "    x!\n"
	
>Fix:
	apply those two patches (expand.1 and unexpand.c) They are against the revisions
	shown above.

----- expand.1 patch ------
--- /usr/src/usr.bin/expand/expand.1	2002-09-30 13:08:59.000000000 +0200
+++ expand.1	2003-04-07 22:59:26.000000000 +0200
@@ -47,6 +47,7 @@
 .Op Ar
 .Nm unexpand
 .Op Fl a
+.Op Fl t Ar tabstop
 .Op Ar
 .Sh DESCRIPTION
 .Nm
@@ -70,6 +71,7 @@
 .Nm unexpand
 puts tabs back into the data from the standard input or the named
 files and writes the result on the standard output.
+If tabstop is not specified, then use the default 8.
 .Pp
 Option (with
 .Nm unexpand
----- unexpand.c patch ------ 
--- /usr/src/usr.bin/unexpand/unexpand.c	1999-02-11 16:29:14.000000000 +0100
+++ unexpand.c	2003-04-07 22:55:27.000000000 +0200
@@ -58,25 +58,28 @@
 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;
+	int all, c, tabsize;
 	char *cp;
 
-	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=atoi(optarg);
+			break;
 		case '?':
 		default:
-			fprintf(stderr, "usage: unexpand [-a] [file ...]\n");
+			fprintf(stderr, "usage: unexpand [-a] [-t tabsize] [file ...]\n");
 			exit(EXIT_FAILURE);
 			/* NOTREACHED */
 		}
@@ -97,7 +100,7 @@
 				continue;
 			if (cp > linebuf)
 				cp[-1] = 0;
-			tabify(all);
+			tabify(all, tabsize);
 			printf("%s", linebuf);
 		}
 	} while (argc > 0);
@@ -106,8 +109,9 @@
 }
 
 void
-tabify(c)
+tabify(c, sz)
 	int c;
+	int sz;
 {
 	char *cp, *dp;
 	int dcol;
@@ -121,20 +125,23 @@
 
 		case ' ':
 			dcol++;
+			fprintf(stderr, "Space found, dcol: %d\n", dcol);
 			break;
 
 		case '\t':
-			dcol += 8;
-			dcol &= ~07;
+			dcol += sz;
+			fprintf(stderr, "Tab found, dcol pre: %d", dcol);
+			dcol = (dcol/sz) * sz;
+			fprintf(stderr, " post: %d\n", dcol);
 			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++ = ' ';
	
>Release-Note:
>Audit-Trail:
>Unformatted: