1 /* wc - print the number of lines, words, and bytes in files
2 Copyright (C) 85, 91, 1995-2008 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* Written by Paul Rubin, phr@ocf.berkeley.edu
18 and David MacKenzie, djm@gnu.ai.mit.edu. */
24 #include <sys/types.h>
34 #include "readtokens0.h"
35 #include "safe-read.h"
37 #if !defined iswspace && !HAVE_ISWSPACE
38 # define iswspace(wc) \
39 ((wc) == to_uchar (wc) && isspace (to_uchar (wc)))
42 /* The official name of this program (e.g., no `g' prefix). */
43 #define PROGRAM_NAME "wc"
46 proper_name ("Paul Rubin"), \
47 proper_name ("David MacKenzie")
49 /* Size of atomic reads. */
50 #define BUFFER_SIZE (16 * 1024)
52 /* Cumulative number of lines, words, chars and bytes in all files so far.
53 max_line_length is the maximum over all files processed so far. */
54 static uintmax_t total_lines;
55 static uintmax_t total_words;
56 static uintmax_t total_chars;
57 static uintmax_t total_bytes;
58 static uintmax_t max_line_length;
60 /* Which counts to print. */
61 static bool print_lines, print_words, print_chars, print_bytes;
62 static bool print_linelength;
64 /* The print width of each count. */
65 static int number_width;
67 /* True if we have ever read the standard input. */
68 static bool have_read_stdin;
70 /* The result of calling fstat or stat on a file descriptor or file. */
73 /* If positive, fstat or stat has not been called yet. Otherwise,
74 this is the value returned from fstat or stat. */
77 /* If FAILED is zero, this is the file's status. */
81 /* For long options that have no equivalent short option, use a
82 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
85 FILES0_FROM_OPTION = CHAR_MAX + 1
88 static const struct option const longopts[] =
90 {"bytes", no_argument, NULL, 'c'},
91 {"chars", no_argument, NULL, 'm'},
92 {"lines", no_argument, NULL, 'l'},
93 {"words", no_argument, NULL, 'w'},
94 {"files0-from", required_argument, NULL, FILES0_FROM_OPTION},
95 {"max-line-length", no_argument, NULL, 'L'},
96 {GETOPT_HELP_OPTION_DECL},
97 {GETOPT_VERSION_OPTION_DECL},
104 if (status != EXIT_SUCCESS)
105 fprintf (stderr, _("Try `%s --help' for more information.\n"),
110 Usage: %s [OPTION]... [FILE]...\n\
111 or: %s [OPTION]... --files0-from=F\n\
113 program_name, program_name);
115 Print newline, word, and byte counts for each FILE, and a total line if\n\
116 more than one FILE is specified. With no FILE, or when FILE is -,\n\
117 read standard input.\n\
118 -c, --bytes print the byte counts\n\
119 -m, --chars print the character counts\n\
120 -l, --lines print the newline counts\n\
123 --files0-from=F read input from the files specified by\n\
124 NUL-terminated names in file F\n\
125 -L, --max-line-length print the length of the longest line\n\
126 -w, --words print the word counts\n\
128 fputs (HELP_OPTION_DESCRIPTION, stdout);
129 fputs (VERSION_OPTION_DESCRIPTION, stdout);
130 emit_bug_reporting_address ();
135 /* FILE is the name of the file (or NULL for standard input)
136 associated with the specified counters. */
138 write_counts (uintmax_t lines,
142 uintmax_t linelength,
145 static char const format_sp_int[] = " %*s";
146 char const *format_int = format_sp_int + 1;
147 char buf[INT_BUFSIZE_BOUND (uintmax_t)];
151 printf (format_int, number_width, umaxtostr (lines, buf));
152 format_int = format_sp_int;
156 printf (format_int, number_width, umaxtostr (words, buf));
157 format_int = format_sp_int;
161 printf (format_int, number_width, umaxtostr (chars, buf));
162 format_int = format_sp_int;
166 printf (format_int, number_width, umaxtostr (bytes, buf));
167 format_int = format_sp_int;
169 if (print_linelength)
171 printf (format_int, number_width, umaxtostr (linelength, buf));
174 printf (" %s", file);
178 /* Count words. FILE_X is the name of the file (or NULL for standard
179 input) that is open on descriptor FD. *FSTATUS is its status.
180 Return true if successful. */
182 wc (int fd, char const *file_x, struct fstatus *fstatus)
185 char buf[BUFFER_SIZE + 1];
187 uintmax_t lines, words, chars, bytes, linelength;
188 bool count_bytes, count_chars, count_complicated;
189 char const *file = file_x ? file_x : _("standard input");
191 lines = words = chars = bytes = linelength = 0;
193 /* If in the current locale, chars are equivalent to bytes, we prefer
194 counting bytes, because that's easier. */
195 #if HAVE_MBRTOWC && (MB_LEN_MAX > 1)
198 count_bytes = print_bytes;
199 count_chars = print_chars;
204 count_bytes = print_bytes | print_chars;
207 count_complicated = print_words | print_linelength;
209 /* When counting only bytes, save some line- and word-counting
210 overhead. If FD is a `regular' Unix file, using lseek is enough
211 to get its `size' in bytes. Otherwise, read blocks of BUFFER_SIZE
212 bytes at a time until EOF. Note that the `size' (number of bytes)
213 that wc reports is smaller than stats.st_size when the file is not
214 positioned at its beginning. That's why the lseek calls below are
215 necessary. For example the command
216 `(dd ibs=99k skip=1 count=0; ./wc -c) < /etc/group'
217 should make wc report `0' bytes. */
219 if (count_bytes & !count_chars & !print_lines & !count_complicated)
221 off_t current_pos, end_pos;
223 if (0 < fstatus->failed)
224 fstatus->failed = fstat (fd, &fstatus->st);
226 if (! fstatus->failed && S_ISREG (fstatus->st.st_mode)
227 && (current_pos = lseek (fd, (off_t) 0, SEEK_CUR)) != -1
228 && (end_pos = lseek (fd, (off_t) 0, SEEK_END)) != -1)
230 /* Be careful here. The current position may actually be
231 beyond the end of the file. As in the example above. */
232 bytes = end_pos < current_pos ? 0 : end_pos - current_pos;
236 while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0)
238 if (bytes_read == SAFE_READ_ERROR)
240 error (0, errno, "%s", file);
248 else if (!count_chars & !count_complicated)
250 /* Use a separate loop when counting only lines or lines and bytes --
251 but not chars or words. */
252 while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0)
256 if (bytes_read == SAFE_READ_ERROR)
258 error (0, errno, "%s", file);
263 while ((p = memchr (p, '\n', (buf + bytes_read) - p)))
271 #if HAVE_MBRTOWC && (MB_LEN_MAX > 1)
272 # define SUPPORT_OLD_MBRTOWC 1
273 else if (MB_CUR_MAX > 1)
275 bool in_word = false;
276 uintmax_t linepos = 0;
277 mbstate_t state = { 0, };
278 bool in_shift = false;
279 # if SUPPORT_OLD_MBRTOWC
280 /* Back-up the state before each multibyte character conversion and
281 move the last incomplete character of the buffer to the front
282 of the buffer. This is needed because we don't know whether
283 the `mbrtowc' function updates the state when it returns -2, -
284 this is the ISO C 99 and glibc-2.2 behaviour - or not - amended
285 ANSI C, glibc-2.1 and Solaris 5.7 behaviour. We don't have an
286 autoconf test for this, yet. */
287 size_t prev = 0; /* number of bytes carried over from previous round */
289 const size_t prev = 0;
292 while ((bytes_read = safe_read (fd, buf + prev, BUFFER_SIZE - prev)) > 0)
295 # if SUPPORT_OLD_MBRTOWC
296 mbstate_t backup_state;
298 if (bytes_read == SAFE_READ_ERROR)
300 error (0, errno, "%s", file);
313 if (!in_shift && is_basic (*p))
315 /* Handle most ASCII characters quickly, without calling
323 # if SUPPORT_OLD_MBRTOWC
324 backup_state = state;
326 n = mbrtowc (&wide_char, p, bytes_read, &state);
327 if (n == (size_t) -2)
329 # if SUPPORT_OLD_MBRTOWC
330 state = backup_state;
334 if (n == (size_t) -1)
336 /* Remember that we read a byte, but don't complain
337 about the error. Because of the decoding error,
338 this is a considered to be byte but not a
339 character (that is, chars is not incremented). */
344 if (mbsinit (&state))
362 if (linepos > linelength)
363 linelength = linepos;
365 goto mb_word_separator;
367 linepos += 8 - (linepos % 8);
368 goto mb_word_separator;
378 if (iswprint (wide_char))
380 int width = wcwidth (wide_char);
383 if (iswspace (wide_char))
384 goto mb_word_separator;
390 while (bytes_read > 0);
392 # if SUPPORT_OLD_MBRTOWC
395 if (bytes_read == BUFFER_SIZE)
397 /* Encountered a very long redundant shift sequence. */
401 memmove (buf, p, bytes_read);
406 if (linepos > linelength)
407 linelength = linepos;
413 bool in_word = false;
414 uintmax_t linepos = 0;
416 while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0)
419 if (bytes_read == SAFE_READ_ERROR)
421 error (0, errno, "%s", file);
436 if (linepos > linelength)
437 linelength = linepos;
441 linepos += 8 - (linepos % 8);
452 if (isprint (to_uchar (p[-1])))
455 if (isspace (to_uchar (p[-1])))
462 while (--bytes_read);
464 if (linepos > linelength)
465 linelength = linepos;
469 if (count_chars < print_chars)
472 write_counts (lines, words, chars, bytes, linelength, file_x);
473 total_lines += lines;
474 total_words += words;
475 total_chars += chars;
476 total_bytes += bytes;
477 if (linelength > max_line_length)
478 max_line_length = linelength;
484 wc_file (char const *file, struct fstatus *fstatus)
486 if (! file || STREQ (file, "-"))
488 have_read_stdin = true;
489 if (O_BINARY && ! isatty (STDIN_FILENO))
490 freopen (NULL, "rb", stdin);
491 return wc (STDIN_FILENO, file, fstatus);
495 int fd = open (file, O_RDONLY | O_BINARY);
498 error (0, errno, "%s", file);
503 bool ok = wc (fd, file, fstatus);
506 error (0, errno, "%s", file);
514 /* Return the file status for the NFILES files addressed by FILE.
515 Optimize the case where only one number is printed, for just one
516 file; in that case we can use a print width of 1, so we don't need
519 static struct fstatus *
520 get_input_fstatus (int nfiles, char * const *file)
522 struct fstatus *fstatus = xnmalloc (nfiles, sizeof *fstatus);
525 && ((print_lines + print_words + print_chars
526 + print_bytes + print_linelength)
528 fstatus[0].failed = 1;
533 for (i = 0; i < nfiles; i++)
534 fstatus[i].failed = (! file[i] || STREQ (file[i], "-")
535 ? fstat (STDIN_FILENO, &fstatus[i].st)
536 : stat (file[i], &fstatus[i].st));
542 /* Return a print width suitable for the NFILES files whose status is
543 recorded in FSTATUS. Optimize the same special case that
544 get_input_fstatus optimizes. */
547 compute_number_width (int nfiles, struct fstatus const *fstatus)
551 if (0 < nfiles && fstatus[0].failed <= 0)
553 int minimum_width = 1;
554 uintmax_t regular_total = 0;
557 for (i = 0; i < nfiles; i++)
558 if (! fstatus[i].failed)
560 if (S_ISREG (fstatus[i].st.st_mode))
561 regular_total += fstatus[i].st.st_size;
566 for (; 10 <= regular_total; regular_total /= 10)
568 if (width < minimum_width)
569 width = minimum_width;
577 main (int argc, char **argv)
584 char *files_from = NULL;
585 struct fstatus *fstatus;
588 initialize_main (&argc, &argv);
589 set_program_name (argv[0]);
590 setlocale (LC_ALL, "");
591 bindtextdomain (PACKAGE, LOCALEDIR);
592 textdomain (PACKAGE);
594 atexit (close_stdout);
596 print_lines = print_words = print_chars = print_bytes = false;
597 print_linelength = false;
598 total_lines = total_words = total_chars = total_bytes = max_line_length = 0;
600 while ((optc = getopt_long (argc, argv, "clLmw", longopts, NULL)) != -1)
620 print_linelength = true;
623 case FILES0_FROM_OPTION:
627 case_GETOPT_HELP_CHAR;
629 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
632 usage (EXIT_FAILURE);
635 if (! (print_lines | print_words | print_chars | print_bytes
637 print_lines = print_words = print_bytes = true;
643 /* When using --files0-from=F, you may not specify any files
644 on the command-line. */
647 error (0, 0, _("extra operand %s"), quote (argv[optind]));
648 fprintf (stderr, "%s\n",
649 _("file operands cannot be combined with --files0-from"));
650 usage (EXIT_FAILURE);
653 if (STREQ (files_from, "-"))
657 stream = fopen (files_from, "r");
659 error (EXIT_FAILURE, errno, _("cannot open %s for reading"),
663 readtokens0_init (&tok);
665 if (! readtokens0 (stream, &tok) || fclose (stream) != 0)
666 error (EXIT_FAILURE, 0, _("cannot read file names from %s"),
674 static char *stdin_only[2];
675 files = (optind < argc ? argv + optind : stdin_only);
676 nfiles = (optind < argc ? argc - optind : 1);
677 stdin_only[0] = NULL;
680 fstatus = get_input_fstatus (nfiles, files);
681 number_width = compute_number_width (nfiles, fstatus);
684 for (i = 0; i < nfiles; i++)
688 if (files_from && STREQ (files_from, "-") && STREQ (files[i], "-"))
691 /* Give a better diagnostic in an unusual case:
692 printf - | wc --files0-from=- */
693 error (0, 0, _("when reading file names from stdin, "
694 "no file name of %s allowed"),
699 /* Diagnose a zero-length file name. When it's one
700 among many, knowing the record number may help. */
701 if (files[i][0] == '\0')
706 /* Using the standard `filename:line-number:' prefix here is
707 not totally appropriate, since NUL is the separator, not NL,
708 but it might be better than nothing. */
709 unsigned long int file_number = i + 1;
710 error (0, 0, "%s:%lu: %s", quotearg_colon (files_from),
711 file_number, _("invalid zero-length file name"));
714 error (0, 0, "%s", _("invalid zero-length file name"));
719 ok &= wc_file (files[i], &fstatus[i]);
723 write_counts (total_lines, total_words, total_chars, total_bytes,
724 max_line_length, _("total"));
728 if (have_read_stdin && close (STDIN_FILENO) != 0)
729 error (EXIT_FAILURE, errno, "-");
731 exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);