]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
numfmt: add the -z,--zero-terminated option
authorAssaf Gordon <assafgordon@gmail.com>
Fri, 8 Jan 2016 18:55:12 +0000 (13:55 -0500)
committerPádraig Brady <P@draigBrady.com>
Wed, 13 Jan 2016 11:11:36 +0000 (11:11 +0000)
* doc/coreutils.texi (numfmt invocation): Reference the description.
* src/numfmt.c: Parameterize '\n' references.
* tests/misc/numfmt.pl: Add tests for character and field processing.
* NEWS: Mention the new feature.

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

diff --git a/NEWS b/NEWS
index 9f48415de5cefbd8bed809b61a898bf3e370db5a..1c214d5204c9b37514f5d4a8f4a0df9d631a9c5d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -33,7 +33,7 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 ** New features
 
-  comm, cut, head, paste, tail now have the -z,--zero-terminated option, and
+  comm,cut,head,numfmt,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 01d76ec2c740dbdcd5c1cfd17c666a845599b5b5..f7bdc4274c35f6084bd4c4825a5fc41742982013 100644 (file)
@@ -17171,6 +17171,9 @@ the output numbers represent other units (e.g. to represent @samp{4,000,000}
 bytes in blocks of 1KB, use @samp{--to=si --to-unit=1000}).
 Suffixes are handled as with @samp{--from=auto}.
 
+@optZeroTerminated
+@newlineFieldSeparator
+
 @end table
 
 @subsection Possible @var{unit}s:
index 5d38cbdcf72afae25fd931db8bbcb1236bf26a0d..223f2a26bbe0513865d4b415507aaff9d92fce1f 100644 (file)
@@ -147,6 +147,7 @@ static struct option const longopts[] =
   {"header", optional_argument, NULL, HEADER_OPTION},
   {"format", required_argument, NULL, FORMAT_OPTION},
   {"invalid", required_argument, NULL, INVALID_OPTION},
+  {"zero-terminated", no_argument, NULL, 'z'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {NULL, 0, NULL, 0}
@@ -189,8 +190,13 @@ static int conv_exit_code = EXIT_CONVERSION_WARNINGS;
 /* auto-pad each line based on skipped whitespace.  */
 static int auto_padding = 0;
 static mbs_align_t padding_alignment = MBS_ALIGN_RIGHT;
+
+/* field delimiter */
 static int delimiter = DELIMITER_DEFAULT;
 
+/* line delimiter.  */
+static unsigned char line_delim = '\n';
+
 /* if non-zero, the first 'header' lines from STDIN are skipped.  */
 static uintmax_t header = 0;
 
@@ -205,6 +211,7 @@ static int decimal_point_length;
 /* debugging for developers.  Enables devmsg().  */
 static bool dev_debug = false;
 
+
 static inline int
 default_scale_base (enum scale_type scale)
 {
@@ -934,7 +941,9 @@ Reformat NUMBER(s), or the numbers from standard input if none are specified.\n\
       fputs (_("\
       --to-unit=N      the output unit size (instead of the default 1)\n\
 "), stdout);
-
+      fputs (_("\
+  -z, --zero-terminated    line delimiter is NUL, not newline\n\
+"), stdout);
       fputs (HELP_OPTION_DESCRIPTION, stdout);
       fputs (VERSION_OPTION_DESCRIPTION, stdout);
 
@@ -1329,10 +1338,10 @@ next_field (char **line)
   else
     {
       /* keep any space prefix in the returned field */
-      while (*field_end && isblank (to_uchar (*field_end)))
+      while (*field_end && field_sep (*field_end))
         ++field_end;
 
-      while (*field_end && !isblank (to_uchar (*field_end)))
+      while (*field_end && ! field_sep (*field_end))
         ++field_end;
     }
 
@@ -1420,7 +1429,7 @@ process_line (char *line, bool newline)
   }
 
   if (newline)
-    putchar ('\n');
+    putchar (line_delim);
 
   return valid_number;
 }
@@ -1451,7 +1460,7 @@ main (int argc, char **argv)
 
   while (true)
     {
-      int c = getopt_long (argc, argv, "d:", longopts, NULL);
+      int c = getopt_long (argc, argv, "d:z", longopts, NULL);
 
       if (c == -1)
         break;
@@ -1512,6 +1521,10 @@ main (int argc, char **argv)
           delimiter = optarg[0];
           break;
 
+        case 'z':
+          line_delim = '\0';
+          break;
+
         case SUFFIX_OPTION:
           suffix = optarg;
           break;
@@ -1599,12 +1612,14 @@ main (int argc, char **argv)
       size_t line_allocated = 0;
       ssize_t len;
 
-      while (header-- && getline (&line, &line_allocated, stdin) > 0)
+      while (header-- && getdelim (&line, &line_allocated,
+                                   line_delim, stdin) > 0)
         fputs (line, stdout);
 
-      while ((len = getline (&line, &line_allocated, stdin)) > 0)
+      while ((len = getdelim (&line, &line_allocated,
+                              line_delim, stdin)) > 0)
         {
-          bool newline = line[len - 1] == '\n';
+          bool newline = line[len - 1] == line_delim;
           if (newline)
             line[len - 1] = '\0';
           valid_numbers &= process_line (line, newline);
index 451bb34abe47882f523e3cbfb419e4811230464c..3f2d6cc6615cd28dade287cd8c3a766531044a3c 100755 (executable)
@@ -804,6 +804,32 @@ my @Tests =
              {EXIT => 2}],
     );
 
+# test null-terminated lines
+my @NullDelim_Tests =
+  (
+     # Input from STDIN
+     ['z1', '-z --to=iec',
+             {IN_PIPE => "1025\x002048\x00"}, {OUT=>"1.1K\x002.0K\x00"}],
+
+     # Input from the commandline - terminated by NULL vs NL
+     ['z3', '   --to=iec 1024',  {OUT=>"1.0K\n"}],
+     ['z2', '-z --to=iec 1024',  {OUT=>"1.0K\x00"}],
+
+     # Input from STDIN, with fields
+     ['z4', '-z --field=3 --to=si',
+             {IN_PIPE => "A B 1001 C\x00" .
+                         "D E 2002 F\x00"},
+             {OUT => "A B 1.1K C\x00" .
+                     "D E 2.1K F\x00"}],
+
+     # Input from STDIN, with fields and embedded NL
+     ['z5', '-z --field=3 --to=si',
+             {IN_PIPE => "A\nB 1001 C\x00" .
+                         "D E\n2002 F\x00"},
+             {OUT => "A B 1.1K C\x00" .
+                     "D E 2.1K F\x00"}],
+  );
+
 my @Limit_Tests =
   (
      # Large Values
@@ -1080,6 +1106,9 @@ foreach $t (@Tests)
       }
   }
 
+# Add test for null-terminated lines (after adjusting the OUT string, above).
+push @Tests, @NullDelim_Tests;
+
 my $save_temps = $ENV{SAVE_TEMPS};
 my $verbose = $ENV{VERBOSE};