From a0b2bc8de7c1363f2fe85dd11d28d2b1e68c9d32 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 24 Jan 2007 09:06:57 +0100 Subject: [PATCH] * NEWS: New option sort -C, proposed by XCU ERN 127, which looks like it will be approved. Also add --check=quiet, --check=silent as long aliases, and --check=diagnose-first as an alias for -c. * doc/coreutils.texi (sort invocation): Document this. Also, mention that sort -c can take at most one file. * src/sort.c: Implement this. Include argmatch.h. (usage): Document the change. (CHECK_OPTION): New constant. (long_options): --check now takes an optional argument, and is now treated differently from 'c'. (check_args, check_types): New constant arrays. (check): New arg CHECKONLY, which suppresses diagnostic if -C. (main): Parse the new options. * tests/sort/Test.pm (02d, 02d, incompat5, incompat6): New tests for -C. --- ChangeLog | 19 +++++++++++++ NEWS | 7 +++++ doc/coreutils.texi | 22 ++++++++++++--- src/sort.c | 79 +++++++++++++++++++++++++++++++++++++----------------- tests/sort/Test.pm | 4 +++ 5 files changed, 102 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index 81b9fe0..e126ac8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2007-01-24 Paul Eggert + + * NEWS: New option sort -C, proposed by XCU ERN 127, which looks + like it will be approved. Also add --check=quiet, --check=silent + as long aliases, and --check=diagnose-first as an alias for -c. + * doc/coreutils.texi (sort invocation): Document this. + Also, mention that sort -c can take at most one file. + * src/sort.c: Implement this. + Include argmatch.h. + (usage): Document the change. + (CHECK_OPTION): New constant. + (long_options): --check now takes an optional argument, and is now + treated differently from 'c'. + (check_args, check_types): New constant arrays. + (check): New arg CHECKONLY, which suppresses diagnostic if -C. + (main): Parse the new options. + * tests/sort/Test.pm (02d, 02d, incompat5, incompat6): + New tests for -C. + 2007-01-24 Jim Meyering Fix a typo. diff --git a/NEWS b/NEWS index 389cca9..ad0fd1d 100644 --- a/NEWS +++ b/NEWS @@ -35,6 +35,13 @@ GNU coreutils NEWS -*- outline -*- When sorting very large inputs, this can result in sort using far less temporary disk space and in improved performance. +** New features + + sort accepts the new option -C, which acts like -c except no diagnostic + is printed. Its --check option now accepts an optional argument, and + --check=quiet and --check=silent are now aliases for -C, while + --check=diagnose-first is an alias for -c or plain --check. + * Noteworthy changes in release 6.7 (2006-12-08) [stable] diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 1abf45d..ff049bc 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -3342,12 +3342,26 @@ mode: @item -c @itemx --check +@itemx --check=diagnose-first @opindex -c @opindex --check @cindex checking for sortedness -Check whether the given files are already sorted: if they are not all -sorted, print an error message and exit with a status of 1. +Check whether the given file is already sorted: if it is not all +sorted, print a diagnostic containing the first out-of-order line and +exit with a status of 1. Otherwise, exit successfully. +At most one input file can be given. + +@item -C +@itemx --check=quiet +@itemx --check=silent +@opindex -c +@opindex --check +@cindex checking for sortedness +Exit successfully if the given file is already sorted, and +exit with status 1 otherwise. +At most one input file can be given. +This is like @option{-c}, except it does not print a diagnostic. @item -m @itemx --merge @@ -3401,7 +3415,7 @@ Exit status: @display 0 if no error occurred -1 if invoked with @option{-c} and the input is not properly sorted +1 if invoked with @option{-c} or @option{-C} and the input is not sorted 2 if an error occurred @end display @@ -3716,7 +3730,7 @@ disks and controllers. @cindex uniquifying output Normally, output only the first of a sequence of lines that compare -equal. For the @option{--check} (@option{-c}) option, +equal. For the @option{--check} (@option{-c} or @option{-C}) option, check that no pair of consecutive lines compares equal. This option also disables the default last-resort comparison. diff --git a/src/sort.c b/src/sort.c index 693b902..f571ecc 100644 --- a/src/sort.c +++ b/src/sort.c @@ -28,6 +28,7 @@ #include #include #include "system.h" +#include "argmatch.h" #include "error.h" #include "findprog.h" #include "hard-locale.h" @@ -336,7 +337,8 @@ Ordering options:\n\ fputs (_("\ Other options:\n\ \n\ - -c, --check check whether input is sorted; do not sort\n\ + -c, --check, --check=diagnose-first check for sorted input; do not sort\n\ + -C, --check=quiet, --check=silent like -c, but do not report first bad line\n\ -k, --key=POS1[,POS2] start a key at POS1, end it at POS2 (origin 1)\n\ -m, --merge merge already sorted files; do not sort\n\ -o, --output=FILE write result to FILE instead of standard output\n\ @@ -385,15 +387,16 @@ native byte values.\n\ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ enum { - RANDOM_SOURCE_OPTION = CHAR_MAX + 1 + CHECK_OPTION = CHAR_MAX + 1, + RANDOM_SOURCE_OPTION }; -static char const short_options[] = "-bcdfgik:mMno:rRsS:t:T:uy:z"; +static char const short_options[] = "-bcCdfgik:mMno:rRsS:t:T:uy:z"; static struct option const long_options[] = { {"ignore-leading-blanks", no_argument, NULL, 'b'}, - {"check", no_argument, NULL, 'c'}, + {"check", optional_argument, NULL, CHECK_OPTION}, {"dictionary-order", no_argument, NULL, 'd'}, {"ignore-case", no_argument, NULL, 'f'}, {"general-numeric-sort", no_argument, NULL, 'g'}, @@ -417,6 +420,16 @@ static struct option const long_options[] = {NULL, 0, NULL, 0}, }; +static char const *const check_args[] = +{ + "quiet", "silent", "diagnose-first", NULL +}; +static char const check_types[] = +{ + 'C', 'C', 'c' +}; +ARGMATCH_VERIFY (check_args, check_types); + /* The set of signals that are caught. */ static sigset_t caught_signals; @@ -1917,13 +1930,13 @@ compare (const struct line *a, const struct line *b) return reverse ? -diff : diff; } -/* Check that the lines read from FILE_NAME come in order. Print a - diagnostic (FILE_NAME, line number, contents of line) to stderr and return - false if they are not in order. Otherwise, print no diagnostic - and return true. */ +/* Check that the lines read from FILE_NAME come in order. Return + true if they are in order. If CHECKONLY == 'c', also print a + diagnostic (FILE_NAME, line number, contents of line) to stderr if + they are not in order. */ static bool -check (char const *file_name) +check (char const *file_name, char checkonly) { FILE *fp = xfopen (file_name, "r"); struct buffer buf; /* Input buffer. */ @@ -1949,15 +1962,19 @@ check (char const *file_name) { found_disorder: { - struct line const *disorder_line = line - 1; - uintmax_t disorder_line_number = - buffer_linelim (&buf) - disorder_line + line_number; - char hr_buf[INT_BUFSIZE_BOUND (uintmax_t)]; - fprintf (stderr, _("%s: %s:%s: disorder: "), - program_name, file_name, - umaxtostr (disorder_line_number, hr_buf)); - write_bytes (disorder_line->text, disorder_line->length, stderr, - _("standard error")); + if (checkonly == 'c') + { + struct line const *disorder_line = line - 1; + uintmax_t disorder_line_number = + buffer_linelim (&buf) - disorder_line + line_number; + char hr_buf[INT_BUFSIZE_BOUND (uintmax_t)]; + fprintf (stderr, _("%s: %s:%s: disorder: "), + program_name, file_name, + umaxtostr (disorder_line_number, hr_buf)); + write_bytes (disorder_line->text, disorder_line->length, + stderr, _("standard error")); + } + ordered = false; break; } @@ -2728,7 +2745,7 @@ main (int argc, char **argv) struct keyfield gkey; char const *s; int c = 0; - bool checkonly = false; + char checkonly = 0; bool mergeonly = false; char *random_source = NULL; bool need_random = false; @@ -2920,8 +2937,16 @@ main (int argc, char **argv) } break; + case CHECK_OPTION: + c = (optarg + ? XARGMATCH ("--check", optarg, check_args, check_types) + : 'c'); + /* Fall through. */ case 'c': - checkonly = true; + case 'C': + if (checkonly && checkonly != c) + incompatible_options ("cC"); + checkonly = c; break; case 'k': @@ -3128,15 +3153,19 @@ main (int argc, char **argv) if (checkonly) { if (nfiles > 1) - error (SORT_FAILURE, 0, _("extra operand %s not allowed with -c"), - quote (files[1])); + error (SORT_FAILURE, 0, _("extra operand %s not allowed with -%c"), + quote (files[1]), checkonly); if (outfile) - incompatible_options ("co"); + { + static char opts[] = {0, 'o', 0}; + opts[0] = checkonly; + incompatible_options (opts); + } - /* POSIX requires that sort return 1 IFF invoked with -c and the + /* POSIX requires that sort return 1 IFF invoked with -c or -C and the input is not properly sorted. */ - exit (check (files[0]) ? EXIT_SUCCESS : SORT_OUT_OF_ORDER); + exit (check (files[0], checkonly) ? EXIT_SUCCESS : SORT_OUT_OF_ORDER); } if (mergeonly) diff --git a/tests/sort/Test.pm b/tests/sort/Test.pm index 6bed61b..dc41d92 100755 --- a/tests/sort/Test.pm +++ b/tests/sort/Test.pm @@ -51,6 +51,8 @@ my @tv = ( ["02a", '-c', "A\nB\nC\n", '', 0], ["02b", '-c', "A\nC\nB\n", '', 1], ["02c", '-c -k1,1', "a\na b\n", '', 0], +["02d", '-C', "A\nB\nC\n", '', 0], +["02e", '-C', "A\nC\nB\n", '', 1], # This should fail because there are duplicate keys ["02m", '-cu', "A\nA\n", '', 1], ["02n", '-cu', "A\nB\n", '', 0], @@ -272,6 +274,8 @@ my @tv = ( ["incompat2", '-fR', '', '', 2], ["incompat3", '-dfgiMnR', '', '', 2], ["incompat4", '-c -o /dev/null', '', '', 2], +["incompat5", '-C -o /dev/null', '', '', 2], +["incompat6", '-cC', '', '', 2], # -t '\0' is accepted, as of coreutils-5.0.91 ['nul-tab', "-k2,2 -t '\\0'", "a\0z\01\nb\0y\02\n", "b\0y\02\na\0z\01\n", 0], -- 2.7.4