summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>1997-11-03 05:08:36 +0000
committerJim Meyering <jim@meyering.net>1997-11-03 05:08:36 +0000
commitab5ff1597f5d734b711fbd95389cefcc8203d51c (patch)
tree68698b5fea816d265a3d9290a51cd9c7693e5810
parentd6174d58f939754a7da6117c69e9d3344db35719 (diff)
downloadcoreutils-ab5ff1597f5d734b711fbd95389cefcc8203d51c.tar.xz
(main): New option, --max-line-length (-L).
(wc, write_counts): Implement it. From Bruno Haible.
-rw-r--r--src/wc.c61
1 files changed, 46 insertions, 15 deletions
diff --git a/src/wc.c b/src/wc.c
index aff6b62fe..577c71dc7 100644
--- a/src/wc.c
+++ b/src/wc.c
@@ -34,11 +34,12 @@ int safe_read ();
/* The name this program was run with. */
char *program_name;
-/* Cumulative number of lines, words, and chars in all files so far. */
-static unsigned long total_lines, total_words, total_chars;
+/* Cumulative number of lines, words, and chars in all files so far.
+ max_line_length is the maximum over all files processed so far. */
+static unsigned long total_lines, total_words, total_chars, max_line_length;
/* Which counts to print. */
-static int print_lines, print_words, print_chars;
+static int print_lines, print_words, print_chars, print_linelength;
/* Nonzero if we have ever read the standard input. */
static int have_read_stdin;
@@ -58,6 +59,7 @@ static struct option const longopts[] =
{"chars", no_argument, NULL, 'c'},
{"lines", no_argument, NULL, 'l'},
{"words", no_argument, NULL, 'w'},
+ {"max-line-length", no_argument, NULL, 'L'},
{"help", no_argument, &show_help, 1},
{"version", no_argument, &show_version, 1},
{NULL, 0, NULL, 0}
@@ -81,6 +83,7 @@ more than one FILE is specified. With no FILE, or when FILE is -,\n\
read standard input.\n\
-c, --bytes, --chars print the byte counts\n\
-l, --lines print the newline counts\n\
+ -L, --max-line-length print the length of the longest line\n\
-w, --words print the word counts\n\
--help display this help and exit\n\
--version output version information and exit\n\
@@ -92,7 +95,8 @@ read standard input.\n\
static void
write_counts (long unsigned int lines, long unsigned int words,
- long unsigned int chars, const char *file)
+ long unsigned int chars, long unsigned int linelength,
+ const char *file)
{
if (print_lines)
printf ("%7lu", lines);
@@ -108,6 +112,12 @@ write_counts (long unsigned int lines, long unsigned int words,
putchar (' ');
printf ("%7lu", chars);
}
+ if (print_linelength)
+ {
+ if (print_lines || print_words || print_chars)
+ putchar (' ');
+ printf ("%7lu", linelength);
+ }
if (*file)
printf (" %s", file);
putchar ('\n');
@@ -119,9 +129,9 @@ wc (int fd, const char *file)
char buf[BUFFER_SIZE + 1];
register int bytes_read;
register int in_word = 0;
- register unsigned long lines, words, chars;
+ register unsigned long lines, words, chars, linelength;
- lines = words = chars = 0;
+ lines = words = chars = linelength = 0;
/* When counting only bytes, save some line- and word-counting
overhead. If FD is a `regular' Unix file, using lseek is enough
@@ -133,7 +143,7 @@ wc (int fd, const char *file)
`(dd ibs=99k skip=1 count=0; ./wc -c) < /etc/group'
should make wc report `0' bytes. */
- if (print_chars && !print_words && !print_lines)
+ if (print_chars && !print_words && !print_lines && !print_linelength)
{
off_t current_pos, end_pos;
struct stat stats;
@@ -160,7 +170,7 @@ wc (int fd, const char *file)
}
}
}
- else if (!print_words)
+ else if (!print_words && !print_linelength)
{
/* Use a separate loop when counting only lines or lines and bytes --
but not words. */
@@ -183,6 +193,8 @@ wc (int fd, const char *file)
}
else
{
+ register unsigned long linepos = 0;
+
while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0)
{
register char *p = buf;
@@ -197,9 +209,18 @@ wc (int fd, const char *file)
/* Fall through. */
case '\r':
case '\f':
+ if (linepos > linelength)
+ linelength = linepos;
+ linepos = 0;
+ goto word_separator;
case '\t':
- case '\v':
+ linepos += 8 - (linepos % 8);
+ goto word_separator;
case ' ':
+ linepos++;
+ /* Fall through. */
+ case '\v':
+ word_separator:
if (in_word)
{
in_word = 0;
@@ -207,6 +228,7 @@ wc (int fd, const char *file)
}
break;
default:
+ linepos++;
in_word = 1;
break;
}
@@ -218,14 +240,18 @@ wc (int fd, const char *file)
error (0, errno, "%s", file);
exit_status = 1;
}
+ if (linepos > linelength)
+ linelength = linepos;
if (in_word)
words++;
}
- write_counts (lines, words, chars, file);
+ write_counts (lines, words, chars, linelength, file);
total_lines += lines;
total_words += words;
total_chars += chars;
+ if (linelength > max_line_length)
+ max_line_length = linelength;
}
static void
@@ -266,10 +292,10 @@ main (int argc, char **argv)
textdomain (PACKAGE);
exit_status = 0;
- print_lines = print_words = print_chars = 0;
- total_lines = total_words = total_chars = 0;
+ print_lines = print_words = print_chars = print_linelength = 0;
+ total_lines = total_words = total_chars = max_line_length = 0;
- while ((optc = getopt_long (argc, argv, "clw", longopts, NULL)) != -1)
+ while ((optc = getopt_long (argc, argv, "clLw", longopts, NULL)) != -1)
switch (optc)
{
case 0:
@@ -287,6 +313,10 @@ main (int argc, char **argv)
print_words = 1;
break;
+ case 'L':
+ print_linelength = 1;
+ break;
+
default:
usage (1);
}
@@ -300,7 +330,7 @@ main (int argc, char **argv)
if (show_help)
usage (0);
- if (print_lines + print_words + print_chars == 0)
+ if (print_lines + print_words + print_chars + print_linelength == 0)
print_lines = print_words = print_chars = 1;
nfiles = argc - optind;
@@ -316,7 +346,8 @@ main (int argc, char **argv)
wc_file (argv[optind]);
if (nfiles > 1)
- write_counts (total_lines, total_words, total_chars, _("total"));
+ write_counts (total_lines, total_words, total_chars, max_line_length,
+ _("total"));
}
if (have_read_stdin && close (0))