Module Name:    src
Committed By:   tron
Date:           Thu Feb 18 10:43:50 UTC 2010

Modified Files:
        src/usr.bin/wc: wc.1 wc.c

Log Message:
Add support for "-L" option (longest line) as present in the GNU and
FreeBSD version of "wc".

No objections on "tech-userlevel" mailing list.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/usr.bin/wc/wc.1
cvs rdiff -u -r1.32 -r1.33 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.14
--- src/usr.bin/wc/wc.1:1.13	Thu Aug  7 11:17:15 2003
+++ src/usr.bin/wc/wc.1	Thu Feb 18 10:43:50 2010
@@ -1,4 +1,4 @@
-.\"	$NetBSD: wc.1,v 1.13 2003/08/07 11:17:15 agc Exp $
+.\"	$NetBSD: wc.1,v 1.14 2010/02/18 10:43:50 tron 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.
@@ -125,6 +128,13 @@
 .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 wc utility.
 .Sh STANDARDS
 The
 .Nm

Index: src/usr.bin/wc/wc.c
diff -u src/usr.bin/wc/wc.c:1.32 src/usr.bin/wc/wc.c:1.33
--- src/usr.bin/wc/wc.c:1.32	Tue Apr 14 07:58:38 2009
+++ src/usr.bin/wc/wc.c	Thu Feb 18 10:43:50 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: wc.c,v 1.32 2009/04/14 07:58:38 lukem Exp $	*/
+/*	$NetBSD: wc.c,v 1.33 2010/02/18 10:43:50 tron 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.32 2009/04/14 07:58:38 lukem Exp $");
+__RCSID("$NetBSD: wc.c,v 1.33 2010/02/18 10:43:50 tron 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(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);
 }

Reply via email to