From dima@unixfreak.org  Mon Apr 23 20:54:06 2001
Return-Path: <dima@unixfreak.org>
Received: from bazooka.unixfreak.org (bazooka.unixfreak.org [63.198.170.138])
	by hub.freebsd.org (Postfix) with ESMTP id 6794D37B422
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 23 Apr 2001 20:54:06 -0700 (PDT)
	(envelope-from dima@unixfreak.org)
Received: from spike.unixfreak.org (spike [63.198.170.139])
	by bazooka.unixfreak.org (Postfix) with ESMTP id 1C6843E28
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 23 Apr 2001 20:54:06 -0700 (PDT)
Received: (from dima@localhost)
	by spike.unixfreak.org (8.11.3/8.11.1) id f3O3s5914785;
	Mon, 23 Apr 2001 20:54:05 -0700 (PDT)
	(envelope-from dima)
Message-Id: <200104240354.f3O3s5914785@spike.unixfreak.org>
Date: Mon, 23 Apr 2001 20:54:05 -0700 (PDT)
From: dd@freebsd.org
Reply-To: dd@freebsd.org
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [PATCH] make cut(1) work with long lines
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         26810
>Category:       bin
>Synopsis:       [PATCH] make cut(1) work with long lines
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    dd
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Apr 23 21:00:01 PDT 2001
>Closed-Date:    Sun Jul 1 18:10:42 PDT 2001
>Last-Modified:  Sun Jul 01 18:10:51 PDT 2001
>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:
State-Changed-From-To: open->analyzed 
State-Changed-By: dd 
State-Changed-When: Thu Apr 26 16:22:49 PDT 2001 
State-Changed-Why:  
Patch committed to -current.  I'll MFC, or bug someone to MFC, it later. 


Responsible-Changed-From-To: freebsd-bugs->dd 
Responsible-Changed-By: dd 
Responsible-Changed-When: Thu Apr 26 16:22:49 PDT 2001 
Responsible-Changed-Why:  
My patch, my commit. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=26810 
State-Changed-From-To: analyzed->closed 
State-Changed-By: dd 
State-Changed-When: Sun Jul 1 18:10:42 PDT 2001 
State-Changed-Why:  
MFC'd 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=26810 
>Unformatted:
