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 06:21:30PM +0000, Matthias Scheler wrote:
> 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.

And another version:
1.) Consistent use of the type "wc_count_t".
2.) Correct usage message.

        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 20:09:44 -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 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.
@@ -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 20:09:44 -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) {
+                       wc_count_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... */
+               wc_count_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,26 +333,28 @@
 
 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
 usage(void)
 {
 
-       (void)fprintf(stderr, "usage: wc [-c | -m] [-lw] [file ...]\n");
+       (void)fprintf(stderr, "usage: wc [-c | -m] [-Llw] [file ...]\n");
        exit(1);
 }


Home | Main Index | Thread Index | Old Index