comm: accept new option: --output-delimiter=STR
authorBo Borgerson <gigabo@gmail.com>
Wed, 23 Apr 2008 03:47:42 +0000 (23:47 -0400)
committerJim Meyering <meyering@redhat.com>
Thu, 12 Jun 2008 19:03:05 +0000 (21:03 +0200)
* src/comm.c (delimiter): New global.
(writeline): Use delimiter string instead of single TAB character.
(main): Initialize delimiter.
* tests/misc/comm: Add tests for comm output delimiter specification.
* doc/coreutils.texi: Document new option.
* NEWS: Advertise new option.
* TODO: Remove associated item.

NEWS
TODO
doc/coreutils.texi
src/comm.c
tests/misc/comm

diff --git a/NEWS b/NEWS
index ba39d2f..ce14695 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,9 @@ GNU coreutils NEWS                                    -*- outline -*-
   comm now verifies that the inputs are in sorted order.  This check can
   be turned off with the --nocheck-order option.
 
+  comm accepts new option, --output-delimiter=STR, that allows specification
+  of an output delimiter other than the default single TAB.
+
   md5sum now accepts the new option, --quiet, to suppress the printing of
   'OK' messages.  sha1sum, sha224sum, sha384sum, and sha512sum accept it, too.
 
diff --git a/TODO b/TODO
index a48a8e6..81add20 100644 (file)
--- a/TODO
+++ b/TODO
@@ -20,11 +20,6 @@ cp --recursive: use fts and *at functions to perform directory traversals
   become very long, and requires space and time that is quadratic in the
   depth of the hierarchy.  [Bo Borgerson is working on this]
 
-comm: add an option, --output-delimiter=STR
-  Files to change: src/comm.c, ChangeLog, NEWS, doc/coreutils.texi,
-  Add a new file, tests/misc/comm (use another file in that directory as
-  a template), to exercise the new option.  Suggestion from Dan Jacobson.
-
 printf:
   Now that gnulib supports *printf("%a"), import one of the
   *printf-posix modules so that printf(1) will support %a even on
index 3bedd73..d05577d 100644 (file)
@@ -4473,8 +4473,15 @@ Fail with an error message if either input file is wrongly ordered.
 @item --nocheck-order
 Do not check that both input files are in sorted order.
 
-@end table
+Other options are:
+
+@item --output-delimiter=@var{str}
+Print @var{str} between adjacent output columns,
+rather than the default of a single TAB character.
 
+The delimiter @var{str} may not be empty.
+
+@end table
 
 @node tsort invocation
 @section @command{tsort}: Topological sort
index 01c0b8c..9742fb3 100644 (file)
@@ -65,10 +65,18 @@ static enum
     CHECK_ORDER_DISABLED
   } check_input_order;
 
+/* Output columns will be delimited with this string, which may be set
+   on the command-line with --output-delimiter=STR.  The default is a
+   single TAB character. */
+static char const *delimiter;
+
+/* For long options that have no equivalent short option, use a
+   non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
 enum
 {
   CHECK_ORDER_OPTION = CHAR_MAX + 1,
-  NOCHECK_ORDER_OPTION
+  NOCHECK_ORDER_OPTION,
+  OUTPUT_DELIMITER_OPTION
 };
 
 
@@ -76,6 +84,7 @@ static struct option const long_options[] =
 {
   {"check-order", no_argument, NULL, CHECK_ORDER_OPTION},
   {"nocheck-order", no_argument, NULL, NOCHECK_ORDER_OPTION},
+  {"output-delimiter", required_argument, NULL, OUTPUT_DELIMITER_OPTION},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {NULL, 0, NULL, 0}
@@ -116,6 +125,9 @@ and column three contains lines common to both files.\n\
                       if all input lines are pairable\n\
   --nocheck-order   do not check that the input is correctly sorted\n\
 "), stdout);
+      fputs (_("\
+  --output-delimiter=STR  separate columns with STR\n\
+"), stdout);
       fputs (HELP_OPTION_DESCRIPTION, stdout);
       fputs (VERSION_OPTION_DESCRIPTION, stdout);
       emit_bug_reporting_address ();
@@ -141,20 +153,20 @@ writeline (const struct linebuffer *line, FILE *stream, int class)
     case 2:
       if (!only_file_2)
        return;
-      /* Print a TAB if we are printing lines from file 1.  */
+      /* Print a delimiter if we are printing lines from file 1.  */
       if (only_file_1)
-       putc ('\t', stream);
+       fputs (delimiter, stream);
       break;
 
     case 3:
       if (!both)
        return;
-      /* Print a TAB if we are printing lines from file 1.  */
+      /* Print a delimiter if we are printing lines from file 1.  */
       if (only_file_1)
-       putc ('\t', stream);
-      /* Print a TAB if we are printing lines from file 2.  */
+       fputs (delimiter, stream);
+      /* Print a delimiter if we are printing lines from file 2.  */
       if (only_file_2)
-       putc ('\t', stream);
+       fputs (delimiter, stream);
       break;
     }
 
@@ -379,6 +391,17 @@ main (int argc, char **argv)
        check_input_order = CHECK_ORDER_ENABLED;
        break;
 
+      case OUTPUT_DELIMITER_OPTION:
+       if (delimiter && !STREQ (delimiter, optarg))
+         error (EXIT_FAILURE, 0, _("multiple delimiters specified"));
+       delimiter = optarg;
+       if (!*delimiter)
+         {
+           error (EXIT_FAILURE, 0, _("empty %s not allowed"),
+                  quote ("--output-delimiter"));
+         }
+       break;
+
       case_GETOPT_HELP_CHAR;
 
       case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -402,6 +425,10 @@ main (int argc, char **argv)
       usage (EXIT_FAILURE);
     }
 
+  /* The default delimiter is a TAB. */
+  if (!delimiter)
+    delimiter = "\t";
+
   compare_files (argv + optind);
 
   if (issued_disorder_warning[0] || issued_disorder_warning[1])
index 39557d2..81a8529 100755 (executable)
@@ -115,6 +115,27 @@ my @Tests =
     {EXIT=>1},
     {OUT => "\t\t2\n"},
     {ERR => "$prog: file 1 is not in sorted order\n"}],
+
+   # alternate delimiter: ','
+   ['delim-comma', '--output-delimiter=,', @inputs,
+    {OUT=>"1\n,2\n,,3\n"} ],
+
+   # two-character alternate delimiter: '++'
+   ['delim-2char', '--output-delimiter=++', @inputs,
+    {OUT=>"1\n++2\n++++3\n"} ],
+
+   # invalid empty delimiter
+   ['delim-empty', '--output-delimiter=', @inputs, {EXIT=>1},
+    {ERR => "$prog: empty `--output-delimiter' not allowed\n"}],
+
+   # invalid dual delimiter
+   ['delim-dual', '--output-delimiter=,', '--output-delimiter=+',
+    @inputs, {EXIT=>1}, {ERR => "$prog: multiple delimiters specified\n"}],
+
+   # valid dual delimiter specification
+   ['delim-dual2', '--output-delimiter=,', '--output-delimiter=,', @inputs,
+    {OUT=>"1\n,2\n,,3\n"} ],
+
  );
 
 my $save_temps = $ENV{DEBUG};