From 826c98b02486dd9dbbab3d2381d5f778af42dd7a Mon Sep 17 00:00:00 2001 From: Pádraig Brady Date: Fri, 8 Jan 2016 14:31:27 +0000 Subject: tac: support an empty (NUL) --separator * doc/coreutils.texi (tac invocation): Mention the NUL delineation with an empty --separator. * src/tac.c (main): Allow an empty separator when -r not specified. * tests/misc/tac.pl: Add test cases. * NEWS: Mention the new feature. Fixes http://bugs.gnu.org/8103 --- NEWS | 4 ++-- doc/coreutils.texi | 2 ++ src/tac.c | 7 ++++--- tests/misc/tac.pl | 7 +++++++ 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 45f299056..408872b7e 100644 --- a/NEWS +++ b/NEWS @@ -33,8 +33,8 @@ GNU coreutils NEWS -*- outline -*- ** New features - cut, head, tail now have -z, --zero-terminated options to work with - NUL delimited items. + cut, head, tail now have the -z,--zero-terminated option, and + tac --separator accepts an empty argument, to work with NUL delimited items. dd now summarizes sizes in --human-readable format too, not just --si. E.g., "3441325000 bytes (3.4 GB, 3.2 GiB) copied". It omits the summaries diff --git a/doc/coreutils.texi b/doc/coreutils.texi index dcf28c5f9..09020275c 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -1706,6 +1706,8 @@ Treat the separator string as a regular expression. @opindex -s @opindex --separator Use @var{separator} as the record separator, instead of newline. +Note an empty @var{separator} is treated as a zero byte. +I.e., input and output items are delimited with ASCII NUL. @end table diff --git a/src/tac.c b/src/tac.c index 241022448..4681f3ab9 100644 --- a/src/tac.c +++ b/src/tac.c @@ -639,8 +639,6 @@ main (int argc, char **argv) break; case 's': separator = optarg; - if (*separator == 0) - error (EXIT_FAILURE, 0, _("separator cannot be empty")); break; case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); @@ -651,6 +649,9 @@ main (int argc, char **argv) if (sentinel_length == 0) { + if (*separator == 0) + error (EXIT_FAILURE, 0, _("separator cannot be empty")); + compiled_separator.buffer = NULL; compiled_separator.allocated = 0; compiled_separator.fastmap = compiled_separator_fastmap; @@ -661,7 +662,7 @@ main (int argc, char **argv) error (EXIT_FAILURE, 0, "%s", (error_message)); } else - match_length = sentinel_length = strlen (separator); + match_length = sentinel_length = *separator ? strlen (separator) : 1; read_size = INITIAL_READSIZE; while (sentinel_length >= read_size / 2) diff --git a/tests/misc/tac.pl b/tests/misc/tac.pl index 6297b1659..fb7671988 100755 --- a/tests/misc/tac.pl +++ b/tests/misc/tac.pl @@ -45,6 +45,13 @@ my @Tests = ['basic-j', '', {IN=>"1234\n8\n"}, {OUT=>"8\n1234\n"}], ['basic-k', '', {IN=>"123\n8\n"}, {OUT=>"8\n123\n"}], + ['nul-0', '-s ""', {IN=>""}, {OUT=>""}], + ['nul-a', '-s ""', {IN=>"a"}, {OUT=>"a"}], + ['nul-b', '-s ""', {IN=>"\0"}, {OUT=>"\0"}], + ['nul-c', '-s ""', {IN=>"a\0"}, {OUT=>"a\0"}], + ['nul-d', '-s ""', {IN=>"a\0b"}, {OUT=>"ba\0"}], + ['nul-e', '-s ""', {IN=>"a\0b\0"}, {OUT=>"b\0a\0"}], + ['opt-b', '-b', {IN=>"\na\nb\nc"}, {OUT=>"\nc\nb\na"}], ['opt-s', '-s:', {IN=>"a:b:c:"}, {OUT=>"c:b:a:"}], ['opt-sb', qw(-s : -b), {IN=>":a:b:c"}, {OUT=>":c:b:a"}], -- cgit v1.2.3-54-g00ecf