1
0
mirror of git://git.sv.gnu.org/coreutils.git synced 2026-04-20 02:36:16 +02:00

Include "dirname.h".

(outbase): Now a global var.
(outfile_end): Remove.
(suffix_length): New var.
(shortopts, longopts, main): Add -a or --suffix-length.
(next_file_name): Implement -a.  Do not extend the suffix length.
Check for file names that are too long.
(main): Move outfile initialization to next_file_name.

(shortopts): Remove -v (a typo).
This commit is contained in:
Jim Meyering
2002-02-12 15:44:16 +00:00
parent edcef60550
commit 65cbf7d1fd

View File

@@ -29,6 +29,7 @@
#include "system.h"
#include "closeout.h"
#include "dirname.h"
#include "error.h"
#include "full-write.h"
#include "safe-read.h"
@@ -43,14 +44,17 @@
char *program_name;
/* Base name of output files. */
static char *outfile;
static char const *outbase;
/* Name of output files. */
static char *outfile;
/* Pointer to the end of the prefix in OUTFILE.
Suffixes are inserted here. */
static char *outfile_mid;
/* Pointer to the end of OUTFILE. */
static char *outfile_end;
/* Length of OUTFILE's suffix. */
static size_t suffix_length = 2;
/* Name of input file. May be "-". */
static char *infile;
@@ -65,7 +69,7 @@ static int output_desc;
output file is opened. */
static int verbose;
static char const shortopts[] = "vb:l:C:"
static char const shortopts[] = "a:b:l:C:"
#if POSIX2_VERSION < 200112
"0123456789"
#endif
@@ -76,6 +80,7 @@ static struct option const longopts[] =
{"bytes", required_argument, NULL, 'b'},
{"lines", required_argument, NULL, 'l'},
{"line-bytes", required_argument, NULL, 'C'},
{"suffix-length", required_argument, NULL, 'a'},
{"verbose", no_argument, NULL, 2},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
@@ -103,6 +108,7 @@ PREFIX is `x'. With no INPUT, or when INPUT is -, read standard input.\n\
Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (_("\
-a, --suffix-length=N use suffixes of length N (default 2)\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\
-l, --lines=NUMBER put NUMBER lines per output file\n\
@@ -126,35 +132,49 @@ SIZE may have a multiplier suffix: b for 512, k for 1K, m for 1 Meg.\n\
exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
/* Compute the next sequential output file name suffix and store it
into the string `outfile' at the position pointed to by `outfile_mid'. */
/* Compute the next sequential output file name and store it into the
string `outfile'. */
static void
next_file_name (void)
{
static unsigned n_digits = 2;
char *p;
/* Change any suffix of `z's to `a's. */
for (p = outfile_end - 1; *p == 'z'; p--)
if (! outfile)
{
*p = 'a';
/* Allocate and initialize the first file name. */
size_t outbase_length = strlen (outbase);
size_t outfile_length = outbase_length + suffix_length;
if (outfile_length + 1 < outbase_length)
xalloc_die ();
outfile = xmalloc (outfile_length + 1);
outfile_mid = outfile + outbase_length;
memcpy (outfile, outbase, outbase_length);
memset (outfile_mid, 'a', suffix_length);
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
its directory, `split' must fail without creating any files.
This must be checked for explicitly on operating systems that
silently truncate file names. */
{
char *dir = dir_name (outfile);
long name_max = pathconf (dir, _PC_NAME_MAX);
if (0 <= name_max && name_max < base_len (base_name (outfile)))
error (EXIT_FAILURE, ENAMETOOLONG, "%s", outfile);
free (dir);
}
#endif
}
/* Increment the rightmost non-`z' character that was present before the
above z/a substitutions. There is guaranteed to be such a character. */
++(*p);
/* If the result of that increment operation yielded a `z' and there
are only `z's to the left of it, then append two more `a' characters
to the end and add 1 (-1 + 2) to the number of digits (we're taking
out this `z' and adding two `a's). */
if (*p == 'z' && p == outfile_mid)
else
{
++n_digits;
++outfile_mid;
*outfile_end++ = 'a';
*outfile_end++ = 'a';
/* Increment the suffix in place, if possible. */
char *p;
for (p = outfile_mid + suffix_length; outfile_mid < p; *--p = 'a')
if (p[-1]++ != 'z')
return;
error (EXIT_FAILURE, 0, _("Output file suffixes exhausted"));
}
}
@@ -357,7 +377,6 @@ main (int argc, char **argv)
int in_blk_size; /* optimal block size of input file device */
char *buf; /* file i/o buffer */
int accum = 0;
char *outbase;
int c;
int digits_optind = 0;
@@ -388,6 +407,16 @@ main (int argc, char **argv)
case 0:
break;
case 'a':
if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK
|| tmp_long < 0 || tmp_long > SIZE_MAX)
{
error (0, 0, _("%s: invalid suffix length"), optarg);
usage (EXIT_FAILURE);
}
suffix_length = tmp_long;
break;
case 'b':
if (split_type != type_undef)
{
@@ -522,17 +551,6 @@ main (int argc, char **argv)
/* No output file is open now. */
output_desc = -1;
/* Copy the output file prefix so we can add suffixes to it.
26**29 is certainly enough output files! */
outfile = xmalloc (strlen (outbase) + 30);
strcpy (outfile, outbase);
outfile_mid = outfile + strlen (outfile);
outfile_end = outfile_mid + 2;
memset (outfile_mid, 0, 30);
outfile_mid[0] = 'a';
outfile_mid[1] = 'a' - 1; /* first call to next_file_name makes it an 'a' */
/* Get the optimal block size of input device and make a buffer. */
if (fstat (input_desc, &stat_buf) < 0)