From 9e90f6f26ab85fac2b1599804e31b78aaac42370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Compostella?= Date: Sun, 29 Jan 2012 15:20:31 +0100 Subject: [PATCH] split: --numeric-suffixes new optional "from" argument (bug#9085) The split command now accepts a new optional "from" argument for the --numeric-suffixes option. If this argument is specified, the numeric suffix counts from this value, otherwise, like before, it counts from 0. * src/split.c (next_file_name): Initialize the suffix index accordingly to the count from value. (main): Check that the suffix length is greater enough for the numerical suffix count from value. * doc/coreutils.texi (split invocation): Mention it. * NEWS (New features): Mention it. * tests/split/numeric: New file. --numeric-suffixes[=FROM] option tests. * tests/Makefile.am (TESTS): Add it. Requested by SciFi. --- NEWS | 5 ++++ doc/coreutils.texi | 5 ++- src/split.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++---- tests/Makefile.am | 1 + tests/split/numeric | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 126 insertions(+), 7 deletions(-) create mode 100755 tests/split/numeric diff --git a/NEWS b/NEWS index 2080790..fae6ecc 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,11 @@ GNU coreutils NEWS -*- outline -*- dd now accepts the count_bytes, skip_bytes iflags and the count_bytes oflag, to more easily allow processing portions of a file. + split now accept an optional "from" value for the + --numeric-suffixes option. If this argument is specified, the + numeric suffix counts from this value, otherwise, like before, it + counts from 0. + ** Bug fixes mv now lets you move a symlink onto a same-inode destination file that diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 8c6a287..03a3191 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -3084,10 +3084,11 @@ and so can be a pipe for example. Use suffixes of length @var{length}. The default @var{length} is 2. @item -d -@itemx --numeric-suffixes +@itemx --numeric-suffixes[=@var{from}] @opindex -d @opindex --numeric-suffixes -Use digits in suffixes rather than lower-case letters. +Use digits in suffixes rather than lower-case letters. The numerical +suffix counts from @var{from} if specified, 0 otherwise. @item -e @itemx --elide-empty-files diff --git a/src/split.c b/src/split.c index 1d0310c..03feb9f 100644 --- a/src/split.c +++ b/src/split.c @@ -80,6 +80,9 @@ static size_t suffix_length; /* Alphabet of characters to use in suffix. */ static char const *suffix_alphabet = "abcdefghijklmnopqrstuvwxyz"; +/* Numerical suffix count from value. */ +static unsigned long suffix_count_from; + /* Name of input file. May be "-". */ static char *infile; @@ -122,7 +125,7 @@ static struct option const longopts[] = {"elide-empty-files", no_argument, NULL, 'e'}, {"unbuffered", no_argument, NULL, 'u'}, {"suffix-length", required_argument, NULL, 'a'}, - {"numeric-suffixes", no_argument, NULL, 'd'}, + {"numeric-suffixes", optional_argument, NULL, 'd'}, {"filter", required_argument, NULL, FILTER_OPTION}, {"verbose", no_argument, NULL, VERBOSE_OPTION}, {"-io-blksize", required_argument, NULL, @@ -195,7 +198,8 @@ Mandatory arguments to long options are mandatory for short options too.\n\ -a, --suffix-length=N use suffixes of length N (default %d)\n\ -b, --bytes=SIZE put SIZE bytes per output file\n\ -C, --line-bytes=SIZE put at most SIZE bytes of lines per output file\n\ - -d, --numeric-suffixes use numeric suffixes instead of alphabetic\n\ + -d, --numeric-suffixes[=FROM] use numeric suffixes instead of alphabetic.\n\ + When specified, start counting from FROM, 0 otherwise\n\ -e, --elide-empty-files do not generate empty output files with '-n'\n\ --filter=COMMAND write to shell COMMAND; file name is $FILE\n\ -l, --lines=NUMBER put NUMBER lines per output file\n\ @@ -231,6 +235,7 @@ next_file_name (void) { /* Index in suffix_alphabet of each character in the suffix. */ static size_t *sufindex; + size_t i = suffix_length; if (! outfile) { @@ -243,9 +248,23 @@ next_file_name (void) outfile = xmalloc (outfile_length + 1); outfile_mid = outfile + outbase_length; memcpy (outfile, outbase, outbase_length); - memset (outfile_mid, suffix_alphabet[0], suffix_length); - outfile[outfile_length] = 0; sufindex = xcalloc (suffix_length, sizeof *sufindex); + /* Initialize the suffix index accordingly to the count from + value. */ + { + unsigned long left = suffix_count_from; + while (i-- != 0) + { + if (left) + { + sufindex[i] = left % 10; + left /= 10; + } + outfile_mid[i] = suffix_alphabet[sufindex[i]]; + } + } + + outfile[outfile_length] = 0; #if ! _POSIX_NO_TRUNC && HAVE_PATHCONF && defined _PC_NAME_MAX /* POSIX requires that if the output file name is too long for @@ -265,7 +284,6 @@ next_file_name (void) { /* Increment the suffix in place, if possible. */ - size_t i = suffix_length; while (i-- != 0) { sufindex[i]++; @@ -1142,6 +1160,19 @@ main (int argc, char **argv) case 'd': suffix_alphabet = "0123456789"; + if (optarg) + { + unsigned long tmp; + if (xstrtoul (optarg, NULL, 10, &tmp, "") != LONGINT_OK) + { + error (0, 0, + _("%s: invalid count from numerical suffix number"), + optarg); + usage (EXIT_FAILURE); + } + else + suffix_count_from = tmp; + } break; case 'e': @@ -1212,6 +1243,26 @@ main (int argc, char **argv) usage (EXIT_FAILURE); } + /* Check that the suffix length is greater enough for the numerical + suffix count from value. */ + if (suffix_count_from) + { + unsigned long start = suffix_count_from; + size_t length = suffix_length; + + while (start) + { + if (length == 0) + { + error (0, 0, _("numerical suffix FROM number too hight\ + for the suffix length")); + usage (EXIT_FAILURE); + } + start /= 10; + length--; + } + } + /* Open the input file. */ if (! STREQ (infile, "-") && fd_reopen (STDIN_FILENO, infile, O_RDONLY, 0) < 0) diff --git a/tests/Makefile.am b/tests/Makefile.am index 7b53681..eed6ed6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -259,6 +259,7 @@ TESTS = \ split/lines \ split/l-chunk \ split/r-chunk \ + split/numeric \ misc/stat-birthtime \ misc/stat-fmt \ misc/stat-hyphen \ diff --git a/tests/split/numeric b/tests/split/numeric new file mode 100755 index 0000000..5550d6f --- /dev/null +++ b/tests/split/numeric @@ -0,0 +1,61 @@ +#!/bin/sh +# Show that split --numeric-suffixes[=from] works. + +# Copyright (C) 2012 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 . + +. "${srcdir=.}/init.sh"; path_prepend_ ../src +print_ver_ split + +# Check default start from 0 +printf '1\n2\n3\n4\n5\n' > in || framework_failure_ +split --numeric-suffixes --lines=2 in > out || fail=1 +cat <<\EOF > exp-1 +1 +2 +EOF +cat <<\EOF > exp-2 +3 +4 +EOF +cat <<\EOF > exp-3 +5 +EOF +compare exp-1 x00 || fail=1 +compare exp-2 x01 || fail=1 +compare exp-3 x02 || fail=1 + +# Check --numeric-suffixes=X +split --numeric-suffixes=1 --lines=2 in > out || fail=1 +cat <<\EOF > exp-1 +1 +2 +EOF +cat <<\EOF > exp-2 +3 +4 +EOF +cat <<\EOF > exp-3 +5 +EOF +compare exp-1 x01 || fail=1 +compare exp-2 x02 || fail=1 +compare exp-3 x03 || fail=1 + +# Check that split failed when suffix length is not greater enough for +# the numerical suffix count from value +fail=1 && split -a 3 --numeric-suffixes=1000 in > out 2> /dev/null || fail=0 + +Exit $fail -- 1.7.2.5