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>
