]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
tac: support an empty (NUL) --separator
authorPádraig Brady <P@draigBrady.com>
Fri, 8 Jan 2016 14:31:27 +0000 (14:31 +0000)
committerPádraig Brady <P@draigBrady.com>
Wed, 13 Jan 2016 10:59:56 +0000 (10:59 +0000)
* 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
doc/coreutils.texi
src/tac.c
tests/misc/tac.pl

diff --git a/NEWS b/NEWS
index 45f299056988ffba101475c664fbe501a9b2ca81..408872b7e7a15d455b73892b0d210ce93ab4904b 100644 (file)
--- 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
index dcf28c5f965cee3acd6c35627ec1d6068207626a..09020275cb3c755bb9a25fb2d0914b60c3318c44 100644 (file)
@@ -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
 
index 241022448402f5a5d1156a50dd61809e0a0b205d..4681f3ab9b0f2a8f574e683b9dc4d24657e76fb4 100644 (file)
--- 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)
index 6297b165957708edf9081b08ce9fe6d5a26d5b85..fb7671988900127965ce508f9db7c4559f6bd826 100755 (executable)
@@ -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"}],