From ec8d9685e7ab2d40a7d7567e41d3ee81247d12bc Mon Sep 17 00:00:00 2001 From: Sascha Wildner Date: Thu, 9 Aug 2012 02:56:25 +0200 Subject: [PATCH] cut(1): Add back -w (split on whitespace functionality). Reported-by: Tim Darby Dragonfly-bug: --- usr.bin/cut/cut.1 | 11 +++++++---- usr.bin/cut/cut.c | 40 +++++++++++++++++++++++++++++++--------- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/usr.bin/cut/cut.1 b/usr.bin/cut/cut.1 index 42e10a3a19..fbbdbd8698 100644 --- a/usr.bin/cut/cut.1 +++ b/usr.bin/cut/cut.1 @@ -29,9 +29,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)cut.1 8.1 (Berkeley) 6/6/93 -.\" $FreeBSD$ +.\" $FreeBSD: src/usr.bin/cut/cut.1,v 1.36 2012/06/11 03:10:15 kevlo Exp $ .\" -.Dd December 21, 2006 +.Dd August 8, 2012 .Dt CUT 1 .Os .Sh NAME @@ -47,14 +47,14 @@ .Op Ar .Nm .Fl f Ar list -.Op Fl d Ar delim +.Op Fl w | Fl d Ar delim .Op Fl s .Op Ar .Sh DESCRIPTION The .Nm utility cuts out selected portions of each line (as specified by -.Ar list ) +.Ar list ) from each .Ar file and writes them to the standard output. @@ -119,6 +119,9 @@ that form the character are selected. .It Fl s Suppress lines with no field delimiter characters. Unless specified, lines with no delimiters are passed through unmodified. +.It Fl w +Use whitespace (spaces and tabs) as the delimiter. +Consecutive spaces and tabs count as one single field separator. .El .Sh ENVIRONMENT The diff --git a/usr.bin/cut/cut.c b/usr.bin/cut/cut.c index 1da999d983..ea298408f0 100644 --- a/usr.bin/cut/cut.c +++ b/usr.bin/cut/cut.c @@ -31,7 +31,7 @@ * * @(#) Copyright (c) 1989, 1993 The Regents of the University of California. All rights reserved. * @(#)cut.c 8.3 (Berkeley) 5/4/95 - * $FreeBSD: src/usr.bin/cut/cut.c,v 1.9.2.3 2001/07/30 09:59:16 dd Exp $ + * $FreeBSD: src/usr.bin/cut/cut.c,v 1.33 2012/06/11 03:02:40 kevlo Exp $ */ #include @@ -53,6 +53,7 @@ static int dflag; static int fflag; static int nflag; static int sflag; +static int wflag; static size_t autostart, autostop, maxval; static char * positions; @@ -62,6 +63,7 @@ static int b_n_cut(FILE *, const char *); static int c_cut(FILE *, const char *); static int f_cut(FILE *, const char *); static void get_list(char *); +static int is_delim(int); static void needpos(size_t); static void usage(void); @@ -79,7 +81,7 @@ main(int argc, char *argv[]) dchar = '\t'; /* default delimiter is \t */ strcpy(dcharmb, "\t"); - while ((ch = getopt(argc, argv, "b:c:d:f:sn")) != -1) + while ((ch = getopt(argc, argv, "b:c:d:f:snw")) != -1) switch(ch) { case 'b': get_list(optarg); @@ -106,6 +108,9 @@ main(int argc, char *argv[]) case 'n': nflag = 1; break; + case 'w': + wflag = 1; + break; case '?': default: usage(); @@ -114,9 +119,9 @@ main(int argc, char *argv[]) argv += optind; if (fflag) { - if (bflag || cflag || nflag) + if (bflag || cflag || nflag || (wflag && dflag)) usage(); - } else if (!(bflag || cflag) || dflag || sflag) + } else if (!(bflag || cflag) || dflag || sflag || wflag) usage(); else if (!bflag && nflag) usage(); @@ -353,19 +358,31 @@ out: return (0); } +static int +is_delim(int ch) +{ + if (wflag) { + if (ch == ' ' || ch == '\t') + return 1; + } else { + if (ch == dchar) + return 1; + } + return 0; +} + static int f_cut(FILE *fp, const char *fname) { wchar_t ch; int field, i, isdelim; char *pos, *p; - wchar_t sep; int output; char *lbuf, *mlbuf; size_t clen, lbuflen, reallen; mlbuf = NULL; - for (sep = dchar; (lbuf = fgetln(fp, &lbuflen)) != NULL;) { + while ((lbuf = fgetln(fp, &lbuflen)) != NULL) { reallen = lbuflen; /* Assert EOL has a newline. */ if (*(lbuf + lbuflen - 1) != '\n') { @@ -389,7 +406,7 @@ f_cut(FILE *fp, const char *fname) if (clen == 0) clen = 1; /* this should work if newline is delimiter */ - if (ch == sep) + if (is_delim(ch)) isdelim = 1; if (ch == '\n') { if (!isdelim && !sflag) @@ -416,8 +433,13 @@ f_cut(FILE *fp, const char *fname) if (clen == 0) clen = 1; p += clen; - if (ch == '\n' || ch == sep) + if (ch == '\n' || is_delim(ch)) { + /* compress whitespace */ + if (wflag && ch != '\n') + while (is_delim(*p)) + p++; break; + } if (*pos) for (i = 0; i < (int)clen; i++) putchar(p[i - clen]); @@ -447,6 +469,6 @@ usage(void) (void)fprintf(stderr, "%s\n%s\n%s\n", "usage: cut -b list [-n] [file ...]", " cut -c list [file ...]", - " cut -f list [-s] [-d delim] [file ...]"); + " cut -f list [-s] [-w | -d delim] [file ...]"); exit(1); } -- 2.41.0