summaryrefslogtreecommitdiff
path: root/usr.bin/cut
diff options
context:
space:
mode:
authorAaron Campbell <aaron@cvs.openbsd.org>2000-06-04 23:52:20 +0000
committerAaron Campbell <aaron@cvs.openbsd.org>2000-06-04 23:52:20 +0000
commitbcb5ce7f6b0a8daa3c1e0771f1cb09000b3db0da (patch)
tree8cb7f39bd60cbded8962f37f2db7ce5e41d4f9cf /usr.bin/cut
parent5f8ce151040563fc391ecc617ce828a11cb01ac6 (diff)
Handle the case where the last line of input does not contain a newline; issue
reported by marc@snafu.org. The main thing here is we use fgetln() instead of fgets(), also giving us the advantage of being able to handle lines of unlimited length. Some -Wall and other fixes from millert@ as well.
Diffstat (limited to 'usr.bin/cut')
-rw-r--r--usr.bin/cut/cut.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/usr.bin/cut/cut.c b/usr.bin/cut/cut.c
index 68a2bf68a74..4aa89e0cfe9 100644
--- a/usr.bin/cut/cut.c
+++ b/usr.bin/cut/cut.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cut.c,v 1.6 1998/11/28 03:41:46 aaron Exp $ */
+/* $OpenBSD: cut.c,v 1.7 2000/06/04 23:52:19 aaron Exp $ */
/* $NetBSD: cut.c,v 1.9 1995/09/02 05:59:23 jtc Exp $ */
/*
@@ -47,7 +47,7 @@ static char copyright[] =
#if 0
static char sccsid[] = "@(#)cut.c 8.3 (Berkeley) 5/4/95";
#endif
-static char rcsid[] = "$OpenBSD: cut.c,v 1.6 1998/11/28 03:41:46 aaron Exp $";
+static char rcsid[] = "$OpenBSD: cut.c,v 1.7 2000/06/04 23:52:19 aaron Exp $";
#endif /* not lint */
#include <ctype.h>
@@ -153,7 +153,7 @@ get_list(list)
* overlapping lists. We also handle "-3-5" although there's no
* real reason too.
*/
- for (; p = strsep(&list, ", \t");) {
+ while ((p = strsep(&list, ", \t"))) {
setautostart = start = stop = 0;
if (*p == '-') {
++p;
@@ -182,7 +182,8 @@ get_list(list)
stop, _POSIX2_LINE_MAX);
if (maxval < stop)
maxval = stop;
- for (pos = positions + start; start++ <= stop; *pos++ = 1);
+ for (pos = positions + start; start++ <= stop; *pos++ = 1)
+ ;
}
/* overlapping ranges */
@@ -213,12 +214,14 @@ c_cut(fp, fname)
if (*pos++)
(void)putchar(ch);
}
- if (ch != '\n')
+ if (ch != '\n') {
if (autostop)
while ((ch = getc(fp)) != EOF && ch != '\n')
(void)putchar(ch);
else
- while ((ch = getc(fp)) != EOF && ch != '\n');
+ while ((ch = getc(fp)) != EOF && ch != '\n')
+ ;
+ }
(void)putchar('\n');
}
}
@@ -231,19 +234,27 @@ f_cut(fp, fname)
register int ch, field, isdelim;
register char *pos, *p, sep;
int output;
- char lbuf[_POSIX2_LINE_MAX + 1];
+ size_t len;
+ char *lbuf, *tbuf;
- for (sep = dchar; fgets(lbuf, sizeof(lbuf), fp);) {
+ for (sep = dchar, tbuf = NULL; (lbuf = fgetln(fp, &len));) {
output = 0;
+ if (lbuf[len - 1] != '\n') {
+ /* no newline at the end of the last line so add one */
+ if ((tbuf = (char *)malloc(len + 1)) == NULL)
+ err(1, NULL);
+ memcpy(tbuf, lbuf, len);
+ tbuf[len] = '\n';
+ lbuf = tbuf;
+ }
for (isdelim = 0, p = lbuf;; ++p) {
- if (!(ch = *p))
- errx(1, "%s: line too long.", fname);
+ 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, len, 1, stdout);
break;
}
}
@@ -258,20 +269,25 @@ f_cut(fp, fname)
while ((ch = *p++) != '\n' && ch != sep)
(void)putchar(ch);
} else
- while ((ch = *p++) != '\n' && ch != sep);
+ while ((ch = *p++) != '\n' && ch != sep)
+ ;
if (ch == '\n')
break;
}
- if (ch != '\n')
+ if (ch != '\n') {
if (autostop) {
if (output)
(void)putchar(sep);
for (; (ch = *p) != '\n'; ++p)
(void)putchar(ch);
} else
- for (; (ch = *p) != '\n'; ++p);
+ for (; (ch = *p) != '\n'; ++p)
+ ;
+ }
(void)putchar('\n');
}
+ if (tbuf)
+ free(tbuf);
}
void