Date: Thu, 7 Mar 2002 18:12:20 +1100 (EST) From: "Tim J. Robbins" <tim@robbins.dropbear.id.au> To: FreeBSD-gnats-submit@freebsd.org Subject: bin/35621: Patch to add P1003.1-2001 -t option to unexpand(1) Message-ID: <200203070712.g277CKs46132@descent.robbins.dropbear.id.au>
next in thread | raw e-mail | index | archive | help
>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 <stdio.h> #include <stdlib.h> #include <string.h> +#include <sysexits.h> +#include <unistd.h> -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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200203070712.g277CKs46132>