Module Name: src
Committed By: sborrill
Date: Sat Mar 6 21:19:11 UTC 2010
Modified Files:
src/usr.bin/wc [netbsd-5]: wc.1 wc.c
Log Message:
Pull up the following revisions(s) (requested by tron in ticket #1313):
usr.bin/wc/wc.c: revision 1.32-1.34
usr.bin/wc/wc.1: revision 1.14-1.15
Add support for "-L" option (longest line) as present in the GNU and
FreeBSD versions of "wc".
To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.13.40.1 src/usr.bin/wc/wc.1
cvs rdiff -u -r1.31 -r1.31.4.1 src/usr.bin/wc/wc.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/wc/wc.1
diff -u src/usr.bin/wc/wc.1:1.13 src/usr.bin/wc/wc.1:1.13.40.1
--- src/usr.bin/wc/wc.1:1.13 Thu Aug 7 11:17:15 2003
+++ src/usr.bin/wc/wc.1 Sat Mar 6 21:19:11 2010
@@ -1,4 +1,4 @@
-.\" $NetBSD: wc.1,v 1.13 2003/08/07 11:17:15 agc Exp $
+.\" $NetBSD: wc.1,v 1.13.40.1 2010/03/06 21:19:11 sborrill Exp $
.\"
.\" Copyright (c) 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -32,7 +32,7 @@
.\"
.\" from: @(#)wc.1 8.2 (Berkeley) 4/19/94
.\"
-.Dd April 19, 1994
+.Dd February 18, 2010
.Dt WC 1
.Os
.Sh NAME
@@ -41,7 +41,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl c | Fl m
-.Op Fl lw
+.Op Fl Llw
.Op Ar file ...
.Sh DESCRIPTION
The
@@ -66,6 +66,9 @@
.It Fl c
The number of bytes in each input file
is written to the standard output.
+.It Fl L
+The number of characters in the longest line of each input file
+is written to the standard output.
.It Fl l
The number of lines in each input file
is written to the standard output.
@@ -81,9 +84,8 @@
.Nm
only
reports the
-information requested by that option. The
-default action is equivalent to all the
-flags
+information requested by that option.
+The default action is equivalent to all the flags
.Fl clw
having been specified.
.Pp
@@ -102,17 +104,20 @@
.Bd -literal -offset indent
lines words bytes file_name
.Ed
-.Pp
-The
-.Nm
-utility exits 0 on success, and \*[Gt]0 if an error occurs.
+.Sh EXIT STATUS
+.Ex -std wc
.Sh SEE ALSO
.Xr iswspace 3
.Sh COMPATIBILITY
Historically, the
.Nm
utility was documented to define a word as a ``maximal string of
-characters delimited by \*[Lt]space\*[Gt], \*[Lt]tab\*[Gt] or \*[Lt]newline\*[Gt] characters''.
+characters delimited by
+.Aq space ,
+.Aq tab
+or
+.Aq newline
+characters''.
The implementation, however, didn't handle non-printing characters
correctly so that `` ^D^E '' counted as 6 spaces, while ``foo^D^Ebar''
counted as 8 characters.
@@ -125,6 +130,15 @@
.Xr iswspace 3
function, as required by
.St -p1003.2 .
+.Pp
+The
+.Fl L
+option is a non-standard extension, compatible with the
+.Fl L
+option of the GNU and
+.Fx
+.Nm
+utilities.
.Sh STANDARDS
The
.Nm
Index: src/usr.bin/wc/wc.c
diff -u src/usr.bin/wc/wc.c:1.31 src/usr.bin/wc/wc.c:1.31.4.1
--- src/usr.bin/wc/wc.c:1.31 Mon Jul 21 14:19:28 2008
+++ src/usr.bin/wc/wc.c Sat Mar 6 21:19:11 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: wc.c,v 1.31 2008/07/21 14:19:28 lukem Exp $ */
+/* $NetBSD: wc.c,v 1.31.4.1 2010/03/06 21:19:11 sborrill Exp $ */
/*
* Copyright (c) 1980, 1987, 1991, 1993
@@ -39,11 +39,11 @@
#if 0
static char sccsid[] = "@(#)wc.c 8.2 (Berkeley) 5/2/95";
#else
-__RCSID("$NetBSD: wc.c,v 1.31 2008/07/21 14:19:28 lukem Exp $");
+__RCSID("$NetBSD: wc.c,v 1.31.4.1 2010/03/06 21:19:11 sborrill Exp $");
#endif
#endif /* not lint */
-/* wc line, word and char count */
+/* wc line, word, char count and optionally longest line. */
#include <sys/param.h>
#include <sys/file.h>
@@ -54,6 +54,7 @@
#include <err.h>
#include <errno.h>
#include <locale.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -71,12 +72,13 @@
# define WCCAST unsigned long long
#endif
-static wc_count_t tlinect, twordct, tcharct;
-static int doline, doword, dobyte, dochar;
+static wc_count_t tlinect, twordct, tcharct, tlongest;
+static bool doline, doword, dobyte, dochar, dolongest;
static int rval = 0;
-static void cnt(char *);
-static void print_counts(wc_count_t, wc_count_t, wc_count_t, char *);
+static void cnt(const char *);
+static void print_counts(wc_count_t, wc_count_t, wc_count_t, wc_count_t,
+ const char *);
static void usage(void);
static size_t do_mb(wchar_t *, const char *, size_t, mbstate_t *,
size_t *, const char *);
@@ -89,21 +91,24 @@
setlocale(LC_ALL, "");
- while ((ch = getopt(argc, argv, "lwcm")) != -1)
+ while ((ch = getopt(argc, argv, "lwcmL")) != -1)
switch (ch) {
case 'l':
- doline = 1;
+ doline = true;
break;
case 'w':
- doword = 1;
+ doword = true;
break;
case 'm':
- dochar = 1;
+ dochar = true;
dobyte = 0;
break;
case 'c':
dochar = 0;
- dobyte = 1;
+ dobyte = true;
+ break;
+ case 'L':
+ dolongest = true;
break;
case '?':
default:
@@ -113,40 +118,42 @@
argc -= optind;
/* Wc's flags are on by default. */
- if (doline + doword + dobyte + dochar == 0)
- doline = doword = dobyte = 1;
+ if (!(doline || doword || dobyte || dochar || dolongest))
+ doline = doword = dobyte = true;
- if (!*argv) {
+ if (*argv == NULL) {
cnt(NULL);
} else {
- int dototal = (argc > 1);
+ bool dototal = (argc > 1);
do {
cnt(*argv);
} while(*++argv);
- if (dototal)
- print_counts(tlinect, twordct, tcharct, "total");
+ if (dototal) {
+ print_counts(tlinect, twordct, tcharct, tlongest,
+ "total");
+ }
}
exit(rval);
}
static size_t
-do_mb(wchar_t *wc, const char *p, size_t mblen, mbstate_t *st,
- size_t *cnt, const char *file)
+do_mb(wchar_t *wc, const char *p, size_t len, mbstate_t *st,
+ size_t *retcnt, const char *file)
{
size_t r;
size_t c = 0;
do {
- r = mbrtowc(wc, p, mblen, st);
+ r = mbrtowc(wc, p, len, st);
if (r == (size_t)-1) {
warnx("%s: invalid byte sequence", file);
rval = 1;
/* XXX skip 1 byte */
- mblen--;
+ len--;
p++;
memset(st, 0, sizeof(*st));
continue;
@@ -157,31 +164,31 @@
c++;
if (wc)
wc++;
- mblen -= r;
+ len -= r;
p += r;
- } while (mblen > 0);
+ } while (len > 0);
- *cnt = c;
+ *retcnt = c;
return (r);
}
static void
-cnt(char *file)
+cnt(const char *file)
{
u_char buf[MAXBSIZE];
wchar_t wbuf[MAXBSIZE];
struct stat sb;
- wc_count_t charct, linect, wordct;
+ wc_count_t charct, linect, wordct, longest;
mbstate_t st;
u_char *C;
wchar_t *WC;
- char *name; /* filename or <stdin> */
+ const char *name; /* filename or <stdin> */
size_t r = 0;
- int fd, gotsp, len = 0;
+ int fd, len = 0;
- linect = wordct = charct = 0;
- if (file) {
+ linect = wordct = charct = longest = 0;
+ if (file != NULL) {
if ((fd = open(file, O_RDONLY, 0)) < 0) {
warn("%s", file);
rval = 1;
@@ -193,10 +200,10 @@
name = "<stdin>";
}
- if (dochar || doword)
- memset(&st, 0, sizeof(st));
+ if (dochar || doword || dolongest)
+ (void)memset(&st, 0, sizeof(st));
- if (!doword) {
+ if (!(doword || dolongest)) {
/*
* line counting is split out because it's a lot
* faster to get lines than to get words, since
@@ -212,10 +219,12 @@
charct += wlen;
} else if (dobyte)
charct += len;
- if (doline)
- for (C = buf; len--; ++C)
+ if (doline) {
+ for (C = buf; len--; ++C) {
if (*C == '\n')
++linect;
+ }
+ }
}
}
@@ -244,7 +253,11 @@
}
} else {
/* do it the hard way... */
- gotsp = 1;
+ wc_count_t linelen;
+ bool gotsp;
+
+ linelen = 0;
+ gotsp = true;
while ((len = read(fd, buf, MAXBSIZE)) > 0) {
size_t wlen;
@@ -252,13 +265,19 @@
name);
if (dochar) {
charct += wlen;
- } else if (dobyte)
+ } else if (dobyte) {
charct += len;
+ }
for (WC = wbuf; wlen--; ++WC) {
if (iswspace(*WC)) {
- gotsp = 1;
+ gotsp = true;
if (*WC == L'\n') {
++linect;
+ if (linelen > longest)
+ longest = linelen;
+ linelen = 0;
+ } else {
+ linelen++;
}
} else {
/*
@@ -270,9 +289,11 @@
* printing or non-printing.
*/
if (gotsp) {
- gotsp = 0;
+ gotsp = false;
++wordct;
}
+
+ linelen++;
}
}
}
@@ -287,7 +308,7 @@
rval = 1;
}
- print_counts(linect, wordct, charct, file);
+ print_counts(linect, wordct, charct, longest, file);
/*
* don't bother checkint doline, doword, or dobyte --- speeds
@@ -296,6 +317,8 @@
tlinect += linect;
twordct += wordct;
tcharct += charct;
+ if (dolongest && longest > tlongest)
+ tlongest = longest;
if (close(fd)) {
warn("%s", name);
@@ -304,26 +327,29 @@
}
static void
-print_counts(wc_count_t lines, wc_count_t words, wc_count_t chars, char *name)
+print_counts(wc_count_t lines, wc_count_t words, wc_count_t chars,
+ wc_count_t longest, const char *name)
{
if (doline)
- printf(WCFMT, (WCCAST)lines);
+ (void)printf(WCFMT, (WCCAST)lines);
if (doword)
- printf(WCFMT, (WCCAST)words);
+ (void)printf(WCFMT, (WCCAST)words);
if (dobyte || dochar)
- printf(WCFMT, (WCCAST)chars);
+ (void)printf(WCFMT, (WCCAST)chars);
+ if (dolongest)
+ (void)printf(WCFMT, (WCCAST)longest);
- if (name)
- printf(" %s\n", name);
+ if (name != NULL)
+ (void)printf(" %s\n", name);
else
- printf("\n");
+ (void)putchar('\n');
}
static void
usage(void)
{
- (void)fprintf(stderr, "usage: wc [-c | -m] [-lw] [file ...]\n");
+ (void)fprintf(stderr, "usage: wc [-c | -m] [-Llw] [file ...]\n");
exit(1);
}