From owner-freebsd-bugs Wed Mar 6 23:20:23 2002 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 26B6437B419 for ; Wed, 6 Mar 2002 23:20:02 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.6/8.11.6) id g277K1d69194; Wed, 6 Mar 2002 23:20:01 -0800 (PST) (envelope-from gnats) Received: from descent.robbins.dropbear.id.au (153.c.007.mel.iprimus.net.au [210.50.82.153]) by hub.freebsd.org (Postfix) with ESMTP id D799837B41D for ; Wed, 6 Mar 2002 23:12:23 -0800 (PST) Received: (from tim@localhost) by descent.robbins.dropbear.id.au (8.11.6/8.11.6) id g277CKs46132; Thu, 7 Mar 2002 18:12:20 +1100 (EST) (envelope-from tim) Message-Id: <200203070712.g277CKs46132@descent.robbins.dropbear.id.au> Date: Thu, 7 Mar 2002 18:12:20 +1100 (EST) From: "Tim J. Robbins" Reply-To: "Tim J. Robbins" To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.113 Subject: bin/35621: Patch to add P1003.1-2001 -t option to unexpand(1) Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org >Number: 35621 >Category: bin >Synopsis: Patch to add P1003.1-2001 -t option to unexpand(1) >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Wed Mar 06 23:20:01 PST 2002 >Closed-Date: >Last-Modified: >Originator: Tim J. Robbins >Release: FreeBSD 4.5-STABLE i386 >Organization: >Environment: System: FreeBSD descent.robbins.dropbear.id.au 4.5-STABLE FreeBSD 4.5-STABLE #5: Sat Feb 16 18:56:18 EST 2002 tim@descent.robbins.dropbear.id.au:/usr/obj/usr/src/sys/DESCENT i386 >Description: This patch adds the -t option to unexpand(1), which is specified by P1003.1-2001. It also removes the artifical line length limits imposed by buffering the file line-by-line. The getstops() function in this patch is taken from expand.c. >How-To-Repeat: $ unexpand -t4 usage: unexpand [-a] file ... >Fix: Index: expand/expand.1 =================================================================== RCS file: /home/ncvs/src/usr.bin/expand/expand.1,v retrieving revision 1.7 diff -u -r1.7 expand.1 --- expand/expand.1 2001/07/10 14:15:57 1.7 +++ expand/expand.1 2002/03/07 07:11:46 @@ -51,6 +51,12 @@ .Op Ar .Nm unexpand .Op Fl a +.Oo +.Fl t +.Sm off +.Ar tab1 , tab2 , ... , tabn +.Sm on +.Oc .Op Ar .Sh DESCRIPTION .Nm Expand @@ -86,6 +92,13 @@ option is given, then tabs are inserted whenever they would compress the resultant file by replacing two or more characters. .El +.Sh STANDARDS +The +.Nm expand +and +.Nm unexpand +utilities are expected to conform to +.St -p1003.1-2001 . .Sh HISTORY The .Nm Index: unexpand/unexpand.c =================================================================== RCS file: /home/ncvs/src/usr.bin/unexpand/unexpand.c,v retrieving revision 1.7 diff -u -r1.7 unexpand.c --- unexpand/unexpand.c 2001/12/11 23:18:25 1.7 +++ unexpand/unexpand.c 2002/03/07 07:05:27 @@ -52,13 +52,16 @@ #include #include #include +#include +#include -char genbuf[BUFSIZ]; -char linebuf[BUFSIZ]; int all; +int nstops; +int tabstops[100]; +static void getstops __P((char *)); static void usage __P((void)); -void tabify __P((char)); +void tabify __P((void)); int main(argc, argv) @@ -66,28 +69,34 @@ char *argv[]; { register char *cp; + int ch; - argc--, argv++; - if (argc > 0 && argv[0][0] == '-') { - if (strcmp(argv[0], "-a") != 0) + nstops = 1; + tabstops[0] = 8; + while ((ch = getopt(argc, argv, "at:")) != -1) { + switch (ch) { + case 'a': + all = 1; + break; + case 't': + getstops(optarg); + all = 1; + break; + default: usage(); - all++; - argc--, argv++; + /*NOTREACHED*/ + } } + argc -= optind; + argv += optind; + do { if (argc > 0) { if (freopen(argv[0], "r", stdin) == NULL) - err(1, "%s", argv[0]); + err(EX_NOINPUT, "%s", argv[0]); argc--, argv++; } - while (fgets(genbuf, BUFSIZ, stdin) != NULL) { - for (cp = linebuf; *cp; cp++) - continue; - if (cp > linebuf) - cp[-1] = 0; - tabify(all); - printf("%s", linebuf); - } + tabify(); } while (argc > 0); exit(0); } @@ -95,52 +104,97 @@ static void usage() { - fprintf(stderr, "usage: unexpand [-a] file ...\n"); - exit(1); + fprintf(stderr, "usage: unexpand [-a] [-t tablist] [file ...]\n"); + exit(EX_USAGE); } void -tabify(c) - char c; +tabify() { - register char *cp, *dp; register int dcol; - int ocol; + int ch, n, ocol; ocol = 0; dcol = 0; - cp = genbuf, dp = linebuf; - for (;;) { - switch (*cp) { - + while ((ch = getchar()) != EOF) { + switch (ch) { + case EOF: + return; + case '\n': + putchar('\n'); + ocol = dcol = 0; + break; case ' ': dcol++; break; - case '\t': dcol += 8; dcol &= ~07; break; - + case '\b': + if (dcol > 0) + dcol--; + /*FALLTHROUGH*/ default: - while (((ocol + 8) &~ 07) <= dcol) { - if (ocol + 1 == dcol) - break; - *dp++ = '\t'; - ocol += 8; - ocol &= ~07; + if (nstops == 1) { + while (((ocol + tabstops[0]) / tabstops[0]) + <= (dcol / tabstops[0])) { + if (dcol - ocol < 2) + break; + putchar('\t'); + ocol = (1 + ocol / tabstops[0]) * + tabstops[0]; + } + } else { + for (n = 0; n < nstops; n++) + if (tabstops[n] > ocol) + break; + while (n < nstops && tabstops[n] <= dcol) { + if (dcol - ocol < 2) + break; + putchar('\t'); + ocol = tabstops[n++]; + } } while (ocol < dcol) { - *dp++ = ' '; + putchar(' '); ocol++; } - if (*cp == 0 || c == 0) { - strcpy(dp, cp); - return; + putchar(ch); + if (!all) { + while ((ch = getchar()) != EOF && ch != '\n') + putchar(ch); + putchar('\n'); + ocol = dcol = 0; + break; } - *dp++ = *cp; ocol++, dcol++; } + } +} + +static void +getstops(cp) + register char *cp; +{ + register int i; + + nstops = 0; + for (;;) { + i = 0; + while (*cp >= '0' && *cp <= '9') + i = i * 10 + *cp++ - '0'; + if (i <= 0) + errx(1, "bad tab stop spec"); + if (nstops > 0 && i <= tabstops[nstops-1]) + errx(1, "bad tab stop spec"); + if (nstops == sizeof(tabstops) / sizeof(*tabstops)) + errx(1, "too many tabstops"); + tabstops[nstops++] = i; + if (*cp == 0) + break; + if (*cp != ',' && *cp != ' ') + errx(1, "bad tab stop spec"); cp++; } } >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message