From 62fa07a515b2f9a409a1b68453a26f7002febf54 Mon Sep 17 00:00:00 2001
From: Assaf Gordon <assafgordon@gmail.com>
Date: Thu, 11 Feb 2016 20:00:09 -0500
Subject: [PATCH] date: add '--debug' option

* src/date.c: (main): add '--debug' option, enable debugging
   in gnulib's parse-datetime.y module.
* tests/misc/date.pl: repeat tests with '--debug' enable, ensure
   no regression.
* NEWS: mention new option.
* doc/coreutils.texi: likewise.
---
 NEWS               |  5 +++++
 doc/coreutils.texi |  8 ++++++--
 src/date.c         | 13 ++++++++++++-
 tests/misc/date.pl | 29 +++++++++++++++++++++++++++++
 4 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 51958ae..c0beddc 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,11 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+** New Features
+
+  date now accepts the --debug option, to annotate the parsed date string,
+  display timezone information, and warn about potential misuse.
+
 
 * Noteworthy changes in release 8.25 (2016-01-20) [stable]
 
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 01791be..d9b1794 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -521,8 +521,8 @@ Include the version number, machine architecture, input files, and
 any other information needed to reproduce the bug: your input, what you
 expected, what you got, and why it is wrong.
 
-If you have a problem with @command{sort}, try running @samp{sort
---debug}, as it can can often help find and fix problems without
+If you have a problem with @command{sort} or @command{date}, try using the
+@option{--debug} option, as it can can often help find and fix problems without
 having to wait for an answer to a bug report.  If the debug output
 does not suffice to fix the problem on your own, please compress and
 attach it to the rest of your bug report.
@@ -15377,6 +15377,10 @@ date -d "$(LC_TIME=C date)"
 @end example
 @xref{Date input formats}.
 
+@item --debug
+annotate the parsed date, display the effective time zone, and warn about
+potential misuse.
+
 @item -f @var{datefile}
 @itemx --file=@var{datefile}
 @opindex -f
diff --git a/src/date.c b/src/date.c
index a42eb3c..805204c 100644
--- a/src/date.c
+++ b/src/date.c
@@ -78,7 +78,8 @@ static char const rfc_2822_format[] = "%a, %d %b %Y %H:%M:%S %z";
    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
 enum
 {
-  RFC_3339_OPTION = CHAR_MAX + 1
+  RFC_3339_OPTION = CHAR_MAX + 1,
+  DEBUG_DATE_PARSING
 };
 
 static char const short_options[] = "d:f:I::r:Rs:u";
@@ -86,6 +87,7 @@ static char const short_options[] = "d:f:I::r:Rs:u";
 static struct option const long_options[] =
 {
   {"date", required_argument, NULL, 'd'},
+  {"debug", no_argument, NULL, DEBUG_DATE_PARSING},
   {"file", required_argument, NULL, 'f'},
   {"iso-8601", optional_argument, NULL, 'I'},
   {"reference", required_argument, NULL, 'r'},
@@ -133,6 +135,12 @@ Display the current time in the given FORMAT, or set the system date.\n\
 
       fputs (_("\
   -d, --date=STRING          display time described by STRING, not 'now'\n\
+"), stdout);
+      fputs (_("\
+      --debug                annotate the parsed date,\n\
+                              and warn about questionable usage to stderr\n\
+"), stdout);
+      fputs (_("\
   -f, --file=DATEFILE        like --date; once for each line of DATEFILE\n\
 "), stdout);
       fputs (_("\
@@ -360,6 +368,9 @@ main (int argc, char **argv)
         case 'd':
           datestr = optarg;
           break;
+        case DEBUG_DATE_PARSING:
+          parse_datetime_debug = true;
+          break;
         case 'f':
           batch_file = optarg;
           break;
diff --git a/tests/misc/date.pl b/tests/misc/date.pl
index 2d19254..2198ad1 100755
--- a/tests/misc/date.pl
+++ b/tests/misc/date.pl
@@ -310,6 +310,35 @@ foreach my $t (@Tests)
       }
   }
 
+# Repeat all tests with --debug option, ensure it does not cause any regression
+my @debug_tests;
+foreach my $t (@Tests)
+  {
+    # Skip tests with EXIT!=0 or ERR_SUBST part
+    # (as '--debug' requires its own ERR_SUBST).
+    my $exit_val;
+    my $have_err_subst;
+    foreach my $e (@$t)
+      {
+        next unless ref $e && ref $e eq 'HASH';
+        $exit_val = $e->{EXIT} if defined $e->{EXIT};
+        $have_err_subst = 1 if defined $e->{ERR_SUBST};
+      }
+    next if $exit_val || $have_err_subst;
+
+    # Duplicate the test, add '--debug' argument
+    my @newt = @$t;
+    $newt[0] = 'dbg_' . $newt[0];
+    $newt[1] = '--debug ' . $newt[1];
+
+    # Discard all debug printouts before comparing output
+    push @newt, {ERR_SUBST => q!s/^date: .*\n//m!};
+
+    push @debug_tests, \@newt;
+  }
+push @Tests, @debug_tests;
+
+
 my $save_temps = $ENV{DEBUG};
 my $verbose = $ENV{VERBOSE};
 
-- 
2.7.0

