ls now supports the --time=modification option, to explicitly
select the default mtime timestamp for display and sorting.
+ wc now accepts the --total={auto,never,always,only} option
+ to give explicit control over when the total is output.
+
** Improvements
date --debug now diagnoses if multiple --date or --set options are
David Madore david.madore@ens.fr
David Malone dwmalone@cnri.dit.ie
David Matei matei@cs.toronto.edu
+David Pinto carandraug+dev@gmail.com
Davide Canova kc.canova@gmail.com
Dawson Engler engler@stanford.edu
Dean Gaudet dean-savannah@arctic.org
@cindex total counts
@command{wc} prints one line of counts for each file, and if the file was
-given as an argument, it prints the file name following the counts. If
-more than one @var{file} is given, @command{wc} prints a final line
-containing the cumulative counts, with the file name @file{total}. The
-counts are printed in this order: newlines, words, characters, bytes,
+given as an argument, it prints the file name following the counts. By default
+if more than one @var{file} is given, @command{wc} prints a final line
+containing the cumulative counts, with the file name @file{total}.
+This @samp{total} line can be controlled with the @option{--total} option,
+which is a GNU extension.
+The counts are printed in this order: newlines, words, characters, bytes,
maximum line length.
Each count is printed right-justified in a field with at least one
space between fields so that the numbers and file names normally line
Display widths of wide characters are considered.
Non-printable characters are given 0 width.
+@item --total=@var{when}
+@opindex --total=@var{when}
+Control when and how the final line with cumulative counts is printed.
+@var{when} is one of:
+@itemize @bullet
+@item auto
+@vindex auto @r{total option}
+- This is the default mode of @command{wc} when no @option{--total}
+option is specified. Output a total line if more than one @var{file}
+is specified.
+@item always
+@vindex always @r{total option}
+- Always output a total line, irrespective of the number of files processed.
+@item only
+@vindex only @r{total option}
+- Only output total counts. I.e., don't print individual file counts,
+suppress any leading spaces, and don't print the @samp{total} word itself,
+to simplify subsequent processing.
+@item never
+@vindex none @r{total option}
+- Never output a total line.
+@end itemize
+
@macro filesZeroFromOption{cmd,withTotalOption,subListOutput}
@item --files0-from=@var{file}
@opindex --files0-from=@var{file}
#include <wctype.h>
#include "system.h"
+#include "argmatch.h"
#include "argv-iter.h"
#include "die.h"
#include "error.h"
{
DEBUG_PROGRAM_OPTION = CHAR_MAX + 1,
FILES0_FROM_OPTION,
+ TOTAL_OPTION,
};
static struct option const longopts[] =
{"debug", no_argument, NULL, DEBUG_PROGRAM_OPTION},
{"files0-from", required_argument, NULL, FILES0_FROM_OPTION},
{"max-line-length", no_argument, NULL, 'L'},
+ {"total", required_argument, NULL, TOTAL_OPTION},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
};
+enum total_type
+ {
+ total_auto, /* 0: default or --total=auto */
+ total_always, /* 1: --total=always */
+ total_only, /* 2: --total=only */
+ total_never /* 3: --total=never */
+ };
+static char const *const total_args[] =
+{
+ "auto", "always", "only", "never", NULL
+};
+static enum total_type const total_types[] =
+{
+ total_auto, total_always, total_only, total_never
+};
+ARGMATCH_VERIFY (total_args, total_types);
+static enum total_type total_mode = total_auto;
+
#ifdef USE_AVX2_WC_LINECOUNT
static bool
avx2_supported (void)
If F is - then read names from standard input\n\
-L, --max-line-length print the maximum display width\n\
-w, --words print the word counts\n\
+"), stdout);
+ fputs (_("\
+ --total=WHEN when to print a line with total counts;\n\
+ WHEN can be: auto, always, only, never\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
if (count_chars < print_chars)
chars = bytes;
- write_counts (lines, words, chars, bytes, linelength, file_x);
+ if (total_mode != total_only)
+ write_counts (lines, words, chars, bytes, linelength, file_x);
total_lines += lines;
total_words += words;
total_chars += chars;
files_from = optarg;
break;
+ case TOTAL_OPTION:
+ total_mode = XARGMATCH ("--total", optarg, total_args, total_types);
+ break;
+
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
xalloc_die ();
fstatus = get_input_fstatus (nfiles, files);
- number_width = compute_number_width (nfiles, fstatus);
+ if (total_mode == total_only)
+ number_width = 1; /* No extra padding, since no alignment requirement. */
+ else
+ number_width = compute_number_width (nfiles, fstatus);
ok = true;
for (int i = 0; /* */; i++)
if (read_tokens)
readtokens0_free (&tok);
- if (1 < argv_iter_n_args (ai))
+ if (total_mode != total_never
+ && (total_mode != total_auto || 1 < argv_iter_n_args (ai)))
write_counts (total_lines, total_words, total_chars, total_bytes,
- max_line_length, _("total"));
+ max_line_length,
+ total_mode != total_only ? _("total") : NULL);
argv_iter_free (ai);
tests/misc/wc-nbsp.sh \
tests/misc/wc-parallel.sh \
tests/misc/wc-proc.sh \
+ tests/misc/wc-total.sh \
tests/misc/cat-E.sh \
tests/misc/cat-proc.sh \
tests/misc/cat-buf.sh \
--- /dev/null
+#!/bin/sh
+# Show that wc's --total option works.
+
+# Copyright (C) 2022 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ wc
+
+printf '%s\n' '2' > 2b || framework_failure_
+printf '%s\n' '2 words' > 2w || framework_failure_
+
+returns_ 1 wc --total 2b 2w > out || fail=1
+
+wc --total=never 2b 2w > out || fail=1
+cat <<\EOF > exp || framework_failure_
+ 1 1 2 2b
+ 1 2 8 2w
+EOF
+compare exp out || fail=1
+
+wc --total=only 2b 2w > out || fail=1
+cat <<\EOF > exp || framework_failure_
+2 3 10
+EOF
+compare exp out || fail=1
+
+wc --total=always 2b > out || fail=1
+test "$(wc -l < out)" = 2 || fail=1
+
+Exit $fail