summaryrefslogtreecommitdiff
path: root/usr.bin/split
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2006-08-09 22:42:09 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2006-08-09 22:42:09 +0000
commit73b5f955d2ae026d1ad44e3affa2610007804a32 (patch)
treeb5d08bcabefb878e2e00ec9da313292a8fd4325e /usr.bin/split
parent8b1676952c1d9b140da331a528d6b49caff9e58a (diff)
Add -a option as per single unix. Rewrote the code to generate
file names to be less blecherous, though it is still not pretty. OK beck@, with man page help from jmc@
Diffstat (limited to 'usr.bin/split')
-rw-r--r--usr.bin/split/split.156
-rw-r--r--usr.bin/split/split.c68
2 files changed, 87 insertions, 37 deletions
diff --git a/usr.bin/split/split.1 b/usr.bin/split/split.1
index 82c7f73ee19..2bc0d3d7f0d 100644
--- a/usr.bin/split/split.1
+++ b/usr.bin/split/split.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: split.1,v 1.11 2006/08/09 12:04:21 jmc Exp $
+.\" $OpenBSD: split.1,v 1.12 2006/08/09 22:42:08 millert Exp $
.\" $NetBSD: split.1,v 1.5 1994/12/21 08:20:35 jtc Exp $
.\"
.\" Copyright (c) 1990, 1991, 1993, 1994
@@ -30,7 +30,7 @@
.\"
.\" @(#)split.1 8.3 (Berkeley) 4/16/94
.\"
-.Dd April 16, 1994
+.Dd August 9, 2006
.Dt SPLIT 1
.Os
.Sh NAME
@@ -38,6 +38,8 @@
.Nd split a file into pieces
.Sh SYNOPSIS
.Nm split
+.Op Fl a Ar suffix_length
+.br
.Oo
.Fl b
.Sm off
@@ -59,6 +61,12 @@ itself is not altered.
.Pp
The options are as follows:
.Bl -tag -width Ds
+.It Fl a Ar suffix_length
+Use
+.Ar suffix_length
+letters to form the suffix of the file name
+(see below).
+The default suffix length is 2.
.It Xo
.Fl b
.Sm off
@@ -88,6 +96,11 @@ The file is split whenever an input line matches
.Ar pattern ,
which is interpreted as an extended regular expression.
The matching line will be the first line of the next output file.
+This option is incompatible with the
+.Fl b
+and
+.Fl l
+options.
.El
.Pp
If
@@ -96,26 +109,43 @@ is specified,
it is used as a prefix
for the names of the files into which the file is split.
In this case, each file into which the file is split is named by the
-prefix followed by a lexically ordered suffix in the range of
-.Dq aa-zz .
+prefix followed by a lexically ordered suffix using
+.Ar suffix_length
+characters in the range
+.Dq a-z .
+.Pp
If the
.Ar name
argument is not specified, the file is split into lexically ordered
-files named in the range of
-.Dq xaa-zzz .
+files named with the prefixes
+.Dq x ,
+.Dq y ,
+and
+.Dq z .
.Sh SEE ALSO
.Xr re_format 7
+.Sh STANDARDS
+The
+.Nm
+utility is compliant with the
+.St -p1003.1-2004
+specification.
+.Pp
+The use of
+.Dq y
+and
+.Dq z
+prefixes (in addition to the standard
+.Dq x )
+in the absence of a
+.Ar name
+parameter is an
+.Ox
+extension.
.Sh HISTORY
A
.Nm
command appeared in
.At v3 .
.Sh BUGS
-For historical reasons, if you specify
-.Ar name ,
-.Nm
-can only create 676 separate
-files.
-The default naming convention allows 2028 separate files.
-.Pp
The maximum line length for matching patterns is 65536.
diff --git a/usr.bin/split/split.c b/usr.bin/split/split.c
index 1513afbf820..0917eb9a6a7 100644
--- a/usr.bin/split/split.c
+++ b/usr.bin/split/split.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: split.c,v 1.11 2006/08/09 12:04:21 jmc Exp $ */
+/* $OpenBSD: split.c,v 1.12 2006/08/09 22:42:08 millert Exp $ */
/* $NetBSD: split.c,v 1.5 1995/08/31 22:22:05 jtc Exp $ */
/*
@@ -40,7 +40,7 @@ static char copyright[] =
#if 0
static char sccsid[] = "@(#)split.c 8.3 (Berkeley) 4/25/94";
#else
-static char rcsid[] = "$OpenBSD: split.c,v 1.11 2006/08/09 12:04:21 jmc Exp $";
+static char rcsid[] = "$OpenBSD: split.c,v 1.12 2006/08/09 22:42:08 millert Exp $";
#endif
#endif /* not lint */
@@ -67,6 +67,7 @@ char bfr[MAXBSIZE]; /* I/O buffer. */
char fname[MAXPATHLEN]; /* File name prefix. */
regex_t rgx;
int pflag;
+int sufflen = 2; /* File name suffix length. */
void newfile(void);
void split1(void);
@@ -78,8 +79,9 @@ main(int argc, char *argv[])
{
int ch;
char *ep, *p;
+ const char *errstr;
- while ((ch = getopt(argc, argv, "0123456789b:l:p:-")) != -1)
+ while ((ch = getopt(argc, argv, "0123456789a:b:l:p:-")) != -1)
switch (ch) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
@@ -104,6 +106,11 @@ main(int argc, char *argv[])
usage();
ifd = 0;
break;
+ case 'a': /* suffix length. */
+ sufflen = strtonum(optarg, 1, NAME_MAX, &errstr);
+ if (errstr)
+ errx(EX_USAGE, "%s: %s", optarg, errstr);
+ break;
case 'b': /* Byte count. */
if ((bytecnt = strtol(optarg, &ep, 10)) <= 0 ||
(*ep != '\0' && *ep != 'k' && *ep != 'm'))
@@ -143,6 +150,8 @@ main(int argc, char *argv[])
if (*argv != NULL)
usage();
+ if (strlen(fname) + sufflen >= sizeof(fname))
+ errx(EX_USAGE, "suffix is too long");
if (pflag && (numlines != 0 || bytecnt != 0))
usage();
@@ -271,35 +280,46 @@ writeit:
void
newfile(void)
{
- static long fnum;
+ static char *suffix, *sufftail;
static int defname;
- static char *fpnt;
if (ofd == -1) {
if (fname[0] == '\0') {
fname[0] = 'x';
- fpnt = fname + 1;
+ suffix = fname + 1;
defname = 1;
} else {
- fpnt = fname + strlen(fname);
+ suffix = fname + strlen(fname);
defname = 0;
}
+ memset(suffix, 'a', sufflen);
+ suffix[sufflen] = '\0';
+ sufftail = suffix + sufflen - 1;
+ --sufftail[0]; /* incremented later */
ofd = fileno(stdout);
}
- /*
- * Hack to increase max files; original code wandered through
- * magic characters. Maximum files is 3 * 26 * 26 == 2028
- */
-#define MAXFILES 676
- if (fnum == MAXFILES) {
- if (!defname || fname[0] == 'z')
- errx(EX_DATAERR, "too many files");
- ++fname[0];
- fnum = 0;
- }
- fpnt[0] = fnum / 26 + 'a';
- fpnt[1] = fnum % 26 + 'a';
- ++fnum;
+
+ if (sufftail[0] == 'z') {
+ int i;
+
+ /* Increment the non-tail portion of the suffix. */
+ for (i = sufflen - 2; i >= 0; i--) {
+ if (suffix[i] != 'z') {
+ suffix[i]++;
+ break;
+ }
+ }
+ if (i < 0) {
+ /* Hack to support y and z prefix if no name spec'd. */
+ if (!defname || fname[0] == 'z')
+ errx(EX_DATAERR, "too many files");
+ ++fname[0];
+ memset(suffix, 'a', sufflen);
+ } else
+ sufftail[0] = 'a'; /* reset tail */
+ } else
+ ++sufftail[0];
+
if (!freopen(fname, "w", stdout))
err(EX_IOERR, "%s", fname);
file_open = 1;
@@ -310,8 +330,8 @@ usage(void)
{
extern char *__progname;
- (void)fprintf(stderr,
-"usage: %s [-b byte_count[k|m] | -l line_count | -p pattern] [file [name]]\n",
-__progname);
+ (void)fprintf(stderr, "usage: %s [-a suffix_length] "
+ "[-b byte_count[k|m] | -l line_count | -p pattern] [file [name]]\n",
+ __progname);
exit(EX_USAGE);
}