tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: "-L" for wc(1)
On Wed, Feb 17, 2010 at 04:15:01PM +0000, Matthias Scheler wrote:
> the attached patch adds a "-L" option to wc(1), similar to what FreeBSD
> and Linux support. Any objections against commit it?
I've attached a patch with an improved manual page.
Kind regards
--
Matthias Scheler http://zhadum.org.uk/
Index: wc.1
===================================================================
RCS file: /cvsroot/src/usr.bin/wc/wc.1,v
retrieving revision 1.13
diff -u -r1.13 wc.1
--- wc.1 7 Aug 2003 11:17:15 -0000 1.13
+++ wc.1 17 Feb 2010 18:20:19 -0000
@@ -32,7 +32,7 @@
.\"
.\" from: @(#)wc.1 8.2 (Berkeley) 4/19/94
.\"
-.Dd April 19, 1994
+.Dd February 17, 2010
.Dt WC 1
.Os
.Sh NAME
@@ -41,7 +41,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl c | Fl m
-.Op Fl lw
+.Op Fl lwL
.Op Ar file ...
.Sh DESCRIPTION
The
@@ -75,6 +75,9 @@
.It Fl w
The number of words 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.
.El
.Pp
When an option is specified,
@@ -125,6 +128,12 @@
.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 FreeBSD wc utility.
.Sh STANDARDS
The
.Nm
Index: wc.c
===================================================================
RCS file: /cvsroot/src/usr.bin/wc/wc.c,v
retrieving revision 1.32
diff -u -r1.32 wc.c
--- wc.c 14 Apr 2009 07:58:38 -0000 1.32
+++ wc.c 17 Feb 2010 18:20:19 -0000
@@ -43,7 +43,7 @@
#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(const char *);
-static void print_counts(wc_count_t, wc_count_t, wc_count_t, 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,20 +118,22 @@
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);
@@ -172,7 +179,7 @@
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;
@@ -180,8 +187,8 @@
size_t r = 0;
int fd, gotsp, 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;
@@ -202,7 +209,8 @@
* faster to get lines than to get words, since
* the word count requires some logic.
*/
- if (doline || dochar) {
+ if (doline || dochar || dolongest) {
+ size_t llen = 0;
while ((len = read(fd, buf, MAXBSIZE)) > 0) {
if (dochar) {
size_t wlen;
@@ -212,10 +220,18 @@
charct += wlen;
} else if (dobyte)
charct += len;
- if (doline)
- for (C = buf; len--; ++C)
- if (*C == '\n')
+ if (doline || dolongest) {
+ for (C = buf; len--; ++C) {
+ if (*C == '\n') {
++linect;
+ if (llen > longest)
+ longest = llen;
+ llen = 0;
+ } else {
+ llen++;
+ }
+ }
+ }
}
}
@@ -244,6 +260,8 @@
}
} else {
/* do it the hard way... */
+ size_t llen = 0;
+
gotsp = 1;
while ((len = read(fd, buf, MAXBSIZE)) > 0) {
size_t wlen;
@@ -252,13 +270,19 @@
name);
if (dochar) {
charct += wlen;
- } else if (dobyte)
+ } else if (dobyte) {
charct += len;
+ }
for (WC = wbuf; wlen--; ++WC) {
if (iswspace(*WC)) {
gotsp = 1;
if (*WC == L'\n') {
++linect;
+ if (llen > longest)
+ longest = llen;
+ llen = 0;
+ } else {
+ llen++;
}
} else {
/*
@@ -273,6 +297,8 @@
gotsp = 0;
++wordct;
}
+
+ llen++;
}
}
}
@@ -287,7 +313,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 +322,8 @@
tlinect += linect;
twordct += wordct;
tcharct += charct;
+ if (dolongest && longest > tlongest)
+ tlongest = longest;
if (close(fd)) {
warn("%s", name);
@@ -305,20 +333,22 @@
static void
print_counts(wc_count_t lines, wc_count_t words, wc_count_t chars,
- const char *name)
+ 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
Home |
Main Index |
Thread Index |
Old Index