]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
paste: add the -z,--zero-terminated option
authorPádraig Brady <P@draigBrady.com>
Fri, 8 Jan 2016 15:57:06 +0000 (15:57 +0000)
committerPádraig Brady <P@draigBrady.com>
Wed, 13 Jan 2016 10:59:56 +0000 (10:59 +0000)
* doc/coreutils.texi (paste invocation): Reference -z description.
* src/paste.c (main): Parameterize the use of '\n'.
* tests/misc/paste.pl: Add test cases.
* NEWS: Mention the new feature.

NEWS
doc/coreutils.texi
src/paste.c
tests/misc/paste.pl

diff --git a/NEWS b/NEWS
index 27789f761cca5b00ef0db7b885d26e74d243e3f7..9f48415de5cefbd8bed809b61a898bf3e370db5a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -33,7 +33,7 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 ** New features
 
-  comm, cut, head, tail now have the -z,--zero-terminated option, and
+  comm, cut, head, paste, 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.
index 157ce0e12e749e083a141ec287e83f6eaadc67f7..01d76ec2c740dbdcd5c1cfd17c666a845599b5b5 100644 (file)
@@ -6004,6 +6004,8 @@ $ paste -d '%_' num2 let3 num2
 %c_
 @end example
 
+@optZeroTerminated
+
 @end table
 
 @exitstatus
index a5acecd900304e8174281a937a24bdb5fc31d4bb..bf99fe0289b94509adba6ee18a6b1e862234474b 100644 (file)
@@ -67,10 +67,13 @@ static char *delims;
 /* A pointer to the character after the end of 'delims'. */
 static char const *delim_end;
 
+static unsigned char line_delim = '\n';
+
 static struct option const longopts[] =
 {
   {"serial", no_argument, NULL, 's'},
   {"delimiters", required_argument, NULL, 'd'},
+  {"zero-terminated", no_argument, NULL, 'z'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {NULL, 0, NULL, 0}
@@ -250,7 +253,7 @@ paste_parallel (size_t nfiles, char **fnamptr)
               while (chr != EOF)
                 {
                   sometodo = true;
-                  if (chr == '\n')
+                  if (chr == line_delim)
                     break;
                   xputchar (chr);
                   chr = getc (fileptr[i]);
@@ -295,7 +298,7 @@ paste_parallel (size_t nfiles, char **fnamptr)
                             write_error ();
                           delims_saved = 0;
                         }
-                      xputchar ('\n');
+                      xputchar (line_delim);
                     }
                   continue;    /* Next read of files, or exit. */
                 }
@@ -316,7 +319,7 @@ paste_parallel (size_t nfiles, char **fnamptr)
               /* Except for last file, replace last newline with delim. */
               if (i + 1 != nfiles)
                 {
-                  if (chr != '\n' && chr != EOF)
+                  if (chr != line_delim && chr != EOF)
                     xputchar (chr);
                   if (*delimptr != EMPTY_DELIM)
                     xputchar (*delimptr);
@@ -327,7 +330,7 @@ paste_parallel (size_t nfiles, char **fnamptr)
                 {
                   /* If the last line of the last file lacks a newline,
                      print one anyhow.  POSIX requires this.  */
-                  char c = (chr == EOF ? '\n' : chr);
+                  char c = (chr == EOF ? line_delim : chr);
                   xputchar (c);
                 }
             }
@@ -386,7 +389,7 @@ paste_serial (size_t nfiles, char **fnamptr)
           while ((charnew = getc (fileptr)) != EOF)
             {
               /* Process the old character. */
-              if (charold == '\n')
+              if (charold == line_delim)
                 {
                   if (*delimptr != EMPTY_DELIM)
                     xputchar (*delimptr);
@@ -405,8 +408,8 @@ paste_serial (size_t nfiles, char **fnamptr)
           xputchar (charold);
         }
 
-      if (charold != '\n')
-        xputchar ('\n');
+      if (charold != line_delim)
+        xputchar (line_delim);
 
       if (ferror (fileptr))
         {
@@ -446,6 +449,9 @@ each FILE, separated by TABs, to standard output.\n\
       fputs (_("\
   -d, --delimiters=LIST   reuse characters from LIST instead of TABs\n\
   -s, --serial            paste one file at a time instead of in parallel\n\
+"), stdout);
+      fputs (_("\
+  -z, --zero-terminated    line delimiter is NUL, not newline\n\
 "), stdout);
       fputs (HELP_OPTION_DESCRIPTION, stdout);
       fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -473,7 +479,7 @@ main (int argc, char **argv)
   have_read_stdin = false;
   serial_merge = false;
 
-  while ((optc = getopt_long (argc, argv, "d:s", longopts, NULL)) != -1)
+  while ((optc = getopt_long (argc, argv, "d:sz", longopts, NULL)) != -1)
     {
       switch (optc)
         {
@@ -486,6 +492,10 @@ main (int argc, char **argv)
           serial_merge = true;
           break;
 
+        case 'z':
+          line_delim = '\0';
+          break;
+
         case_GETOPT_HELP_CHAR;
 
         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
index b4409e77985c919a0c704d57f6e57ba4ef8a3875..7c9559700fb45afdeb850e80a3a172ac05aeb8f4 100755 (executable)
@@ -34,6 +34,11 @@ my @Tests =
    ['no-nl-3', {IN=>"a"},   {IN=>"b\n"}, {OUT=>"a\tb\n"}],
    ['no-nl-4', {IN=>"a\n"}, {IN=>"b\n"}, {OUT=>"a\tb\n"}],
 
+   ['zno-nl-1', '-z', {IN=>"a"},   {IN=>"b"},   {OUT=>"a\tb\0"}],
+   ['zno-nl-2', '-z', {IN=>"a\0"}, {IN=>"b"},   {OUT=>"a\tb\0"}],
+   ['zno-nl-3', '-z', {IN=>"a"},   {IN=>"b\0"}, {OUT=>"a\tb\0"}],
+   ['zno-nl-4', '-z', {IN=>"a\0"}, {IN=>"b\0"}, {OUT=>"a\tb\0"}],
+
    # Same as above, but with a two lines in each input file and
    # the addition of the -d option to make SPACE be the output delimiter.
    ['no-nla1', '-d" "', {IN=>"1\na"},   {IN=>"2\nb"},   {OUT=>"1 2\na b\n"}],
@@ -41,6 +46,11 @@ my @Tests =
    ['no-nla3', '-d" "', {IN=>"1\na"},   {IN=>"2\nb\n"}, {OUT=>"1 2\na b\n"}],
    ['no-nla4', '-d" "', {IN=>"1\na\n"}, {IN=>"2\nb\n"}, {OUT=>"1 2\na b\n"}],
 
+   ['zno-nla1', '-zd" "', {IN=>"1\0a"},   {IN=>"2\0b"},   {OUT=>"1 2\0a b\0"}],
+   ['zno-nla2', '-zd" "', {IN=>"1\0a\0"}, {IN=>"2\0b"},   {OUT=>"1 2\0a b\0"}],
+   ['zno-nla3', '-zd" "', {IN=>"1\0a"},   {IN=>"2\0b\0"}, {OUT=>"1 2\0a b\0"}],
+   ['zno-nla4', '-zd" "', {IN=>"1\0a\0"}, {IN=>"2\0b\0"}, {OUT=>"1 2\0a b\0"}],
+
    # Specifying a delimiter with a trailing backslash would overrun a
    # malloc'd buffer.
    ['delim-bs1', q!-d'\'!, {IN=>{'a'x50=>''}}, {EXIT => 1},