summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2016-01-08 14:31:27 +0000
committerPádraig Brady <P@draigBrady.com>2016-01-13 10:59:56 +0000
commit826c98b02486dd9dbbab3d2381d5f778af42dd7a (patch)
tree24177f02817887f4ca8e63844e68770086c663ae
parenta499a0ce583a8d941e50c4da450133e694994d17 (diff)
downloadcoreutils-826c98b02486dd9dbbab3d2381d5f778af42dd7a.tar.xz
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
-rw-r--r--NEWS4
-rw-r--r--doc/coreutils.texi2
-rw-r--r--src/tac.c7
-rwxr-xr-xtests/misc/tac.pl7
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"}],