[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
FYI: wc accepts a new option --files0-from=FILE, ...
From: |
Jim Meyering |
Subject: |
FYI: wc accepts a new option --files0-from=FILE, ... |
Date: |
Sun, 25 Jun 2006 20:28:35 +0200 |
I've just checked in this change:
2006-06-25 Jim Meyering <address@hidden>
* NEWS: wc accepts a new option --files0-from=FILE, where FILE
contains a list of NUL-separated file names.
* src/wc.c: Include "readtokens.h".
(usage): Describe the new option, and adjust the `Usage':
with this option, no FILE may be specified on the command line.
(main): Handle the new option.
* tests/misc/wc-files0: New tests, for the above.
* tests/misc/wc-files0-from: Likewise.
* tests/misc/Makefile.am (TESTS): Add wc-files0.
Index: src/wc.c
===================================================================
RCS file: /fetish/cu/src/wc.c,v
retrieving revision 1.108
retrieving revision 1.109
diff -u -p -u -r1.108 -r1.109
--- src/wc.c 13 Aug 2005 22:47:48 -0000 1.108
+++ src/wc.c 25 Jun 2006 18:26:09 -0000 1.109
@@ -1,5 +1,5 @@
/* wc - print the number of lines, words, and bytes in files
- Copyright (C) 85, 91, 1995-2005 Free Software Foundation, Inc.
+ Copyright (C) 85, 91, 1995-2006 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
@@ -48,6 +48,8 @@
#include "error.h"
#include "inttostr.h"
+#include "quote.h"
+#include "readtokens0.h"
#include "safe-read.h"
#ifndef HAVE_DECL_WCWIDTH
@@ -103,6 +105,12 @@ struct fstatus
struct stat st;
};
+/* For long options that have no equivalent short option, use a
+ non-character as a pseudo short option, starting with CHAR_MAX + 1. */
+enum
+{
+ FILES0_FROM_OPTION = CHAR_MAX + 1
+};
static struct option const longopts[] =
{
@@ -110,6 +118,7 @@ static struct option const longopts[] =
{"chars", no_argument, NULL, 'm'},
{"lines", no_argument, NULL, 'l'},
{"words", no_argument, NULL, 'w'},
+ {"files0-from", required_argument, NULL, FILES0_FROM_OPTION},
{"max-line-length", no_argument, NULL, 'L'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
@@ -126,8 +135,9 @@ usage (int status)
{
printf (_("\
Usage: %s [OPTION]... [FILE]...\n\
+ or: %s [OPTION]... --files0-from=F\n\
"),
- program_name);
+ program_name, program_name);
fputs (_("\
Print newline, word, and byte counts for each FILE, and a total line if\n\
more than one FILE is specified. With no FILE, or when FILE is -,\n\
@@ -137,6 +147,8 @@ read standard input.\n\
-l, --lines print the newline counts\n\
"), stdout);
fputs (_("\
+ --files0-from=F read input from the files specified by\n\
+ NUL-terminated names in file F\n\
-L, --max-line-length print the length of the longest line\n\
-w, --words print the word counts\n\
"), stdout);
@@ -593,7 +605,10 @@ main (int argc, char **argv)
bool ok;
int optc;
int nfiles;
+ char **files;
+ char *files_from = NULL;
struct fstatus *fstatus;
+ struct Tokens tok;
initialize_main (&argc, &argv);
program_name = argv[0];
@@ -630,6 +645,10 @@ main (int argc, char **argv)
print_linelength = true;
break;
+ case FILES0_FROM_OPTION:
+ files_from = optarg;
+ break;
+
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -642,15 +661,64 @@ main (int argc, char **argv)
| print_linelength))
print_lines = print_words = print_bytes = true;
- nfiles = argc - optind;
- nfiles += (nfiles == 0);
+ if (files_from)
+ {
+ FILE *stream;
+
+ /* When using --files0-from=F, you may not specify any files
+ on the command-line. */
+ if (optind < argc)
+ {
+ error (0, 0, _("extra operand %s"), quote (argv[optind]));
+ fprintf (stderr, "%s\n",
+ _("File operands cannot be combined with --files0-from."));
+ usage (EXIT_FAILURE);
+ }
+
+ if (STREQ (files_from, "-"))
+ stream = stdin;
+ else
+ {
+ stream = fopen (files_from, "r");
+ if (stream == NULL)
+ error (EXIT_FAILURE, errno, _("cannot open %s for reading"),
+ quote (files_from));
+ }
- fstatus = get_input_fstatus (nfiles, argv + optind);
+ readtokens0_init (&tok);
+
+ if (! readtokens0 (stream, &tok) || fclose (stream) != 0)
+ error (EXIT_FAILURE, 0, _("cannot read file names from %s"),
+ quote (files_from));
+
+ files = tok.tok;
+ nfiles = tok.n_tok;
+ }
+ else
+ {
+ static char *stdin_only[2];
+ files = (optind < argc ? argv + optind : stdin_only);
+ nfiles = (optind < argc ? argc - optind : 1);
+ stdin_only[0] = NULL;
+ }
+
+ fstatus = get_input_fstatus (nfiles, files);
number_width = compute_number_width (nfiles, fstatus);
ok = true;
for (i = 0; i < nfiles; i++)
- ok &= wc_file (argv[optind + i], &fstatus[i]);
+ {
+ if (files_from && STREQ (files_from, "-") && STREQ (files[i], "-"))
+ {
+ ok = false;
+ error (0, 0,
+ _("when reading file names from stdin, "
+ "no file name of %s allowed"),
+ quote ("-"));
+ continue;
+ }
+ ok &= wc_file (files[i], &fstatus[i]);
+ }
if (1 < nfiles)
write_counts (total_lines, total_words, total_chars, total_bytes,
Index: tests/misc/wc-files0-from
===================================================================
RCS file: tests/misc/wc-files0-from
diff -N tests/misc/wc-files0-from
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/misc/wc-files0-from 25 Jun 2006 18:26:10 -0000 1.1
@@ -0,0 +1,91 @@
+#!/bin/sh
+# -*- perl -*-
+# Exercise wc's --files0-from option.
+# This file bears a striking resemblance to tests/du/files0-from.
+
+: ${PERL=perl}
+: ${srcdir=.}
+
+. $srcdir/../envvar-check
+
+$PERL -e 1 > /dev/null 2>&1 || {
+ echo 1>&2 "$0: configure didn't find a usable version of Perl," \
+ "so can't run this test"
+ exit 77
+}
+
+exec $PERL -w -I$srcdir/.. -MCoreutils -- - <<\EOF
+#/
+require 5.003;
+use strict;
+
+(my $program_name = $0) =~ s|.*/||;
+
+$ENV{PROG} = 'wc';
+my $ME = $ENV{PROG};
+
+# Turn off localization of executable's ouput.
address@hidden(LANGUAGE LANG LC_ALL)} = ('C') x 3;
+
+my @Tests =
+ (
+ # invalid extra command line argument
+ ['f-extra-arg', '--files0-from=- no-such', {IN=>"a"}, {EXIT=>1},
+ {ERR => "$ME: extra operand `no-such'\n"
+ . "File operands cannot be combined with --files0-from.\n"
+ . "Try `$ME --help' for more information.\n"}
+ ],
+
+ # missing input file
+ ['missing', '--files0-from=missing', {EXIT=>1},
+ {ERR => "$ME: cannot open `missing' for reading: "
+ . "No such file or directory\n"}],
+
+ # empty input
+ ['empty', '--files0-from=-'],
+
+ # empty input, from non-regular file
+ ['empty-nonreg', '--files0-from=/dev/null'],
+
+ # one NUL
+ ['nul-1', '--files0-from=-', '<', {IN=>"\0"}, {EXIT=>1},
+ {ERR => "$ME: : No such file or directory\n"}],
+
+ # two NULs
+ ['nul-2', '--files0-from=-', '<', {IN=>"\0\0"}, {EXIT=>1},
+ {OUT=>"0 0 0 total\n"},
+ {ERR => "$ME: : No such file or directory\n"
+ . "$ME: : No such file or directory\n"}],
+
+ # one file name, no NUL
+ ['1', '--files0-from=-', '<',
+ {IN=>{f=>"g"}}, {AUX=>{g=>''}}, {OUT=>"0 0 0 g\n"} ],
+
+ # one file name, with NUL
+ ['1a', '--files0-from=-', '<',
+ {IN=>{f=>"g\0"}}, {AUX=>{g=>''}}, {OUT=>"0 0 0 g\n"} ],
+
+ # two file names, no final NUL
+ ['2', '--files0-from=-', '<',
+ {IN=>{f=>"g\0g"}}, {AUX=>{g=>''}},
+ {OUT=>"0 0 0 g\n0 0 0 g\n0 0 0 total\n"} ],
+
+ # two file names, with final NUL
+ ['2a', '--files0-from=-', '<',
+ {IN=>{f=>"g\0g\0"}}, {AUX=>{g=>''}},
+ {OUT=>"0 0 0 g\n0 0 0 g\n0 0 0 total\n"} ],
+
+ # Ensure that wc processes FILEs following a zero-length name.
+ ['zero-len', '--files0-from=-', '<',
+ {IN=>{f=>"\0g\0"}}, {AUX=>{g=>''}},
+ {OUT=>"0 0 0 g\n0 0 0 total\n"},
+ {ERR => "$ME: : No such file or directory\n"}, {EXIT=>1} ],
+ );
+
+my $save_temps = $ENV{DEBUG};
+my $verbose = $ENV{VERBOSE};
+
+my $prog = $ENV{PROG} || die "$0: \$PROG not specified in environment\n";
+my $fail = run_tests ($program_name, $prog, address@hidden, $save_temps,
$verbose);
+exit $fail;
+EOF
Index: tests/misc/wc-files0
===================================================================
RCS file: tests/misc/wc-files0
diff -N tests/misc/wc-files0
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/misc/wc-files0 25 Jun 2006 18:26:10 -0000 1.1
@@ -0,0 +1,49 @@
+#!/bin/sh
+# Show that wc's new --files0-from option works.
+
+if test "$VERBOSE" = yes; then
+ set -x
+ wc --version
+fi
+
+. $srcdir/../lang-default
+
+pwd=`pwd`
+t0=`echo "$0"|sed 's,.*/,,'`.tmp; tmp=$t0/$$
+trap 'status=$?; cd $pwd; chmod -R u+rwx $t0; rm -rf $t0 && exit $status' 0
+trap '(exit $?); exit $?' 1 2 13 15
+
+framework_failure=0
+mkdir -p $tmp || framework_failure=1
+cd $tmp || framework_failure=1
+
+echo 2 > 2b || framework_failure=1
+echo 2 words > 2w || framework_failure=1
+printf '2b\n2w\n' |tr '\n' '\0' > names || framework_failure=1
+
+if test $framework_failure = 1; then
+ echo "$0: failure in testing framework" 1>&2
+ (exit 1); exit 1
+fi
+
+fail=0
+
+wc --files0-from=names > out || fail=1
+cat <<\EOF > exp || fail=1
+ 1 1 2 2b
+ 1 2 8 2w
+ 2 3 10 total
+EOF
+
+cmp out exp || fail=1
+test $fail = 1 && diff out exp 2> /dev/null
+
+if test "$fail" = ''; then
+ # Repeat the above test, but read the file name list from stdin.
+ rm -f out
+ wc --files0-from=- < names > out || fail=1
+ cmp out exp || fail=1
+ test $fail = 1 && diff out exp 2> /dev/null
+fi
+
+(exit $fail); exit $fail
Index: tests/misc/Makefile.am
===================================================================
RCS file: /fetish/cu/tests/misc/Makefile.am,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -p -u -r1.39 -r1.40
--- tests/misc/Makefile.am 8 Jun 2006 20:13:46 -0000 1.39
+++ tests/misc/Makefile.am 25 Jun 2006 18:26:10 -0000 1.40
@@ -18,6 +18,8 @@ TESTS_ENVIRONMENT = \
# will execute the test script rather than the standard utility.
TESTS = \
+ wc-files0-from \
+ wc-files0 \
cat-proc \
base64 \
basename \
- FYI: wc accepts a new option --files0-from=FILE, ...,
Jim Meyering <=
- Re: FYI: wc accepts a new option --files0-from=FILE, ..., Pádraig Brady, 2006/06/26
- Re: FYI: wc accepts a new option --files0-from=FILE, ..., Jim Meyering, 2006/06/26
- Re: FYI: wc accepts a new option --files0-from=FILE, ..., Bob Proulx, 2006/06/26
- Re: FYI: wc accepts a new option --files0-from=FILE, ..., Jim Meyering, 2006/06/26
- Re: FYI: wc accepts a new option --files0-from=FILE, ..., Pádraig Brady, 2006/06/27
- Re: FYI: wc accepts a new option --files0-from=FILE, ..., Jim Meyering, 2006/06/27