git: b3cef2d2f538 - stable/14 - split: Further option parsing improvements.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 05 Oct 2023 00:01:39 UTC
The branch stable/14 has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=b3cef2d2f538671551b30c918267bfbe246d225c commit b3cef2d2f538671551b30c918267bfbe246d225c Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2023-09-28 16:29:52 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2023-10-04 23:59:44 +0000 split: Further option parsing improvements. * Whenever possible, use strtonum() to parse numeric arguments. * Improve usefulness and consistency of error messages. * While here, fix some type and style issues. Sponsored by: Klara, Inc. Reviewed by: christos, kevans Differential Revision: https://reviews.freebsd.org/D42010 (cherry picked from commit d7399551b02861b910b15c7b7a78a2835644aa45) split: Improve GNU compatibility. * Like GNU split, turn autoextend back on if given -a0. * Add a test case that verifies that -a<non-zero> turns autoextend off. * Add a test case that verifies that -a0 turns autoextend back on. Sponsored by: Klara, Inc. Reviewed by: christos, kevans Differential Revision: https://reviews.freebsd.org/D42011 (cherry picked from commit d9d69a6f6fc1f8d80df9ce6493e8ab9388781615) --- usr.bin/split/split.c | 89 ++++++++++++++++++++++----------------- usr.bin/split/tests/split_test.sh | 19 +++++++++ 2 files changed, 70 insertions(+), 38 deletions(-) diff --git a/usr.bin/split/split.c b/usr.bin/split/split.c index af1ed69c9482..e246a0d4adfc 100644 --- a/usr.bin/split/split.c +++ b/usr.bin/split/split.c @@ -63,7 +63,7 @@ static const char sccsid[] = "@(#)split.c 8.2 (Berkeley) 4/16/94"; #define DEFLINE 1000 /* Default num lines per file. */ static off_t bytecnt; /* Byte count to split on. */ -static off_t chunks = 0; /* Chunks count to split into. */ +static long chunks; /* Chunks count to split into. */ static bool clobber = true; /* Whether to overwrite existing output files. */ static long numlines; /* Line count to split on. */ static int file_open; /* If a file open. */ @@ -73,7 +73,7 @@ static regex_t rgx; static int pflag; static bool dflag; static long sufflen = 2; /* File name suffix length. */ -static int autosfx = 1; /* Whether to auto-extend the suffix length. */ +static bool autosfx = true; /* Whether to auto-extend the suffix length. */ static void newfile(void); static void split1(void); @@ -84,8 +84,8 @@ static void usage(void) __dead2; int main(int argc, char **argv) { - const char *p; - char *ep; + char errbuf[64]; + const char *p, *errstr; int ch, error; setlocale(LC_ALL, ""); @@ -106,20 +106,27 @@ main(int argc, char **argv) while (numlines >= 0 && *p >= '0' && *p <= '9') numlines = numlines * 10 + *p++ - '0'; if (numlines <= 0 || *p != '\0') - errx(EX_USAGE, "%c%s: illegal line count", ch, - optarg ? optarg : ""); + errx(EX_USAGE, "%c%s: line count is invalid", + ch, optarg ? optarg : ""); break; case 'a': /* Suffix length */ - if ((sufflen = strtol(optarg, &ep, 10)) <= 0 || *ep) - errx(EX_USAGE, - "%s: illegal suffix length", optarg); - autosfx = 0; + sufflen = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr != NULL) { + errx(EX_USAGE, "%s: suffix length is %s", + optarg, errstr); + } + if (sufflen == 0) { + sufflen = 2; + autosfx = true; + } else { + autosfx = false; + } break; case 'b': /* Byte count. */ - errno = 0; - error = expand_number(optarg, &bytecnt); - if (error == -1) - errx(EX_USAGE, "%s: offset too large", optarg); + if (expand_number(optarg, &bytecnt) != 0) { + errx(EX_USAGE, "%s: byte count is invalid", + optarg); + } break; case 'c': /* Continue, don't overwrite output files. */ clobber = false; @@ -130,22 +137,27 @@ main(int argc, char **argv) case 'l': /* Line count. */ if (numlines != 0) usage(); - if ((numlines = strtol(optarg, &ep, 10)) <= 0 || *ep) - errx(EX_USAGE, - "%s: illegal line count", optarg); + numlines = strtonum(optarg, 1, LONG_MAX, &errstr); + if (errstr != NULL) { + errx(EX_USAGE, "%s: line count is %s", + optarg, errstr); + } break; case 'n': /* Chunks. */ - if (!isdigit((unsigned char)optarg[0]) || - (chunks = (size_t)strtoul(optarg, &ep, 10)) == 0 || - *ep != '\0') { - errx(EX_USAGE, "%s: illegal number of chunks", - optarg); + chunks = strtonum(optarg, 1, LONG_MAX, &errstr); + if (errstr != NULL) { + errx(EX_USAGE, "%s: number of chunks is %s", + optarg, errstr); } break; case 'p': /* pattern matching. */ - if (regcomp(&rgx, optarg, REG_EXTENDED|REG_NOSUB) != 0) - errx(EX_USAGE, "%s: illegal regexp", optarg); + error = regcomp(&rgx, optarg, REG_EXTENDED|REG_NOSUB); + if (error != 0) { + regerror(error, &rgx, errbuf, sizeof(errbuf)); + errx(EX_USAGE, "%s: regex is invalid: %s", + optarg, errbuf); + } pflag = 1; break; default: @@ -163,9 +175,10 @@ main(int argc, char **argv) --argc; } if (argc > 0) { /* File name prefix. */ - if (strlcpy(fname, *argv, sizeof(fname)) >= sizeof(fname)) - errx(EX_USAGE, "file name prefix is too long: %s", + if (strlcpy(fname, *argv, sizeof(fname)) >= sizeof(fname)) { + errx(EX_USAGE, "%s: file name prefix is too long", *argv); + } ++argv; --argc; } @@ -182,16 +195,16 @@ main(int argc, char **argv) else if (bytecnt != 0 || chunks != 0) usage(); - if (bytecnt && chunks) + if (bytecnt != 0 && chunks != 0) usage(); if (ifd == -1) /* Stdin by default. */ ifd = 0; - if (bytecnt) { + if (bytecnt != 0) { split1(); exit (0); - } else if (chunks) { + } else if (chunks != 0) { split3(); exit (0); } @@ -225,7 +238,7 @@ split1(void) /* NOTREACHED */ default: if (!file_open) { - if (!chunks || (nfiles < chunks)) { + if (chunks == 0 || nfiles < chunks) { newfile(); nfiles++; } @@ -236,24 +249,24 @@ split1(void) err(EX_IOERR, "write"); len -= dist; for (C = bfr + dist; len >= bytecnt; - len -= bytecnt, C += bytecnt) { - if (!chunks || (nfiles < chunks)) { - newfile(); + len -= bytecnt, C += bytecnt) { + if (chunks == 0 || nfiles < chunks) { + newfile(); nfiles++; } - if (write(ofd, - C, bytecnt) != bytecnt) + if (write(ofd, C, bytecnt) != bytecnt) err(EX_IOERR, "write"); } if (len != 0) { - if (!chunks || (nfiles < chunks)) { - newfile(); + if (chunks == 0 || nfiles < chunks) { + newfile(); nfiles++; } if (write(ofd, C, len) != len) err(EX_IOERR, "write"); - } else + } else { file_open = 0; + } bcnt = len; } else { bcnt += len; diff --git a/usr.bin/split/tests/split_test.sh b/usr.bin/split/tests/split_test.sh index c9b87c01618c..48065719055a 100755 --- a/usr.bin/split/tests/split_test.sh +++ b/usr.bin/split/tests/split_test.sh @@ -209,6 +209,23 @@ autoextend_body() atf_check -o inline:"$((26*25+1))\n" cat xzaaa } +atf_test_case noautoextend +noautoextend_body() +{ + seq $((26*26)) >input + atf_check split -a2 -l1 input + atf_check -o inline:"$((26*26))\n" cat xzz +} + +atf_test_case reautoextend +reautoextend_body() +{ + seq $((26*25+1)) >input + atf_check split -a2 -a0 -l1 input + atf_check -o inline:"$((26*25))\n" cat xyz + atf_check -o inline:"$((26*25+1))\n" cat xzaaa +} + atf_test_case continue continue_body() { @@ -249,6 +266,8 @@ atf_init_test_cases() atf_add_test_case larger_suffix_length atf_add_test_case pattern atf_add_test_case autoextend + atf_add_test_case noautoextend + atf_add_test_case reautoextend atf_add_test_case continue atf_add_test_case undocumented_kludge atf_add_test_case duplicate_linecount