Date: Mon, 23 Apr 2001 20:54:05 -0700 (PDT) From: dd@freebsd.org To: FreeBSD-gnats-submit@freebsd.org Subject: bin/26810: [PATCH] make cut(1) work with long lines Message-ID: <200104240354.f3O3s5914785@spike.unixfreak.org>
next in thread | raw e-mail | index | archive | help
>Number: 26810
>Category: bin
>Synopsis: [PATCH] make cut(1) work with long lines
>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: Mon Apr 23 21:00:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Dima Dorfman
>Release: FreeBSD 5.0-20010407-CURRENT i386
>Organization:
Private
>Environment:
System: FreeBSD spike.unixfreak.org 5.0-20010407-CURRENT FreeBSD 5.0-20010407-CURRENT #59: Sat Apr 21 00:18:59 PDT 2001 dima@spike.unixfreak.org:/c/home/dima/w/f/src/sys/compile/SPIKE i386
>Description:
cut(1) cannot deal with lines longer than 2048 characters, and does
not properly deal with files that do not have a trailing newline.
>How-To-Repeat:
dima@spike% perl -e 'for ($i = 0; $i < 9000; $i++) { print "magic$i " }' > llt
dima@spike% cut -d\ -f2 llt
cut: llt: line too long.
dima@spike% echo -n "file with no trailing newline" > ntn
dima@spike% cut -d\ -f2 ntn
cut: ntn: line too long.
dima@spike%
>Fix:
The following patch fixes both of the cases described above. Note
that specifying a list over 2048 on the command line (e.g., the -f
option) still isn't supported, but at least cut(1) doesn't choke when
you want the second token but feed it a few thousand characters in one
line.
Index: cut.c
===================================================================
RCS file: /st/src/FreeBSD/src/usr.bin/cut/cut.c,v
retrieving revision 1.12
diff -u -r1.12 cut.c
--- cut.c 2001/02/06 20:03:48 1.12
+++ cut.c 2001/04/20 20:49:08
@@ -43,6 +43,7 @@
"$FreeBSD: src/usr.bin/cut/cut.c,v 1.12 2001/02/06 20:03:48 charnier Exp $";
#endif /* not lint */
+#include <assert.h>
#include <ctype.h>
#include <err.h>
#include <limits.h>
@@ -228,19 +229,30 @@
int ch, field, isdelim;
char *pos, *p, sep;
int output;
- char lbuf[_POSIX2_LINE_MAX + 1];
+ char *lbuf, *mlbuf = NULL;
+ size_t lbuflen;
- for (sep = dchar; fgets(lbuf, sizeof(lbuf), fp);) {
+ for (sep = dchar; (lbuf = fgetln(fp, &lbuflen)) != NULL;) {
+ /* Assert EOL has a newline. */
+ if (*(lbuf + lbuflen - 1) != '\n') {
+ /* Can't have > 1 line with no trailing newline. */
+ assert(mlbuf == NULL);
+ mlbuf = malloc(lbuflen + 1);
+ if (mlbuf == NULL)
+ err(1, "malloc");
+ memcpy(mlbuf, lbuf, lbuflen);
+ *(mlbuf + lbuflen) = '\n';
+ lbuf = mlbuf;
+ }
output = 0;
- for (isdelim = 0, p = lbuf;; ++p) {
- if (!(ch = *p))
- errx(1, "%s: line too long.", fname);
+ for (isdelim = 0, p = lbuf; p < lbuf + lbuflen; ++p) {
+ ch = *p;
/* this should work if newline is delimiter */
if (ch == sep)
isdelim = 1;
if (ch == '\n') {
if (!isdelim && !sflag)
- (void)printf("%s", lbuf);
+ (void)fwrite(lbuf, lbuflen, 1, stdout);
break;
}
}
@@ -272,6 +284,8 @@
}
(void)putchar('\n');
}
+ if (mlbuf != NULL)
+ free(mlbuf);
}
static void
>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?200104240354.f3O3s5914785>
