From 4625a73ca2221a43c46da946ae27af3e4967cd69 Mon Sep 17 00:00:00 2001 From: =?utf-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 30 Jun 2008 17:32:28 +0200 Subject: [PATCH] getdate.y: Allow usage of relative signed time offset even before time zone is specified. * lib/getdate.y (time) : Improve grammar to allow relative signed time offset even before time zone. (zone) : likewise (hybrid) : Empty strings handling no longer necessary (handled directly in the changes above). * tests/test-getdate.c (main) : Add tests for this change. * ChangeLog : Mention changes. --- ChangeLog | 6 +++++ lib/getdate.y | 52 +++++++++++++++++++++++++++++++++++++++++-------- tests/test-getdate.c | 28 ++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2d9b9ab..e13525a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-09-23 Ondřej Vašík + * lib/getdate.y: Improve grammar to allow relative signed time offsets even + before timezone specified. + Reported in https://bugs.launchpad.net/ubuntu/+source/coreutils/+bug/51106 + * tests/test-getdate.c: Add test for this grammar improvement + 2009-09-23 Bruno Haible * gnulib-tool (func_import): Add 'link-warning' to testsrelated_modules diff --git a/lib/getdate.y b/lib/getdate.y index f022710..3f905ca 100644 --- a/lib/getdate.y +++ b/lib/getdate.y @@ -288,8 +288,8 @@ set_hhmmss (parser_control *pc, long int hour, long int minutes, %parse-param { parser_control *pc } %lex-param { parser_control *pc } -/* This grammar has 20 shift/reduce conflicts. */ -%expect 20 +/* This grammar has 32 shift/reduce conflicts. */ +%expect 32 %union { @@ -381,7 +381,43 @@ time: pc->zones_seen++; pc->time_zone = time_zone_hhmm (pc, $6, $7); } - ; + | tUNUMBER ':' tUNUMBER relunit_snumber + { + set_hhmmss (pc, $1.value, $3.value, 0, 0); + pc->meridian = MER24; + apply_relative_time (pc, $4, 1); + } + | tUNUMBER ':' tUNUMBER ':' unsigned_seconds relunit_snumber + { + set_hhmmss (pc, $1.value, $3.value, $5.tv_sec, $5.tv_nsec); + pc->meridian = MER24; + apply_relative_time (pc, $6, 1); + } + | tUNUMBER ':' tUNUMBER + { + set_hhmmss (pc, $1.value, $3.value, 0, 0); + pc->meridian = MER24; + } + | tUNUMBER ':' tUNUMBER tSNUMBER + { + set_hhmmss (pc, $1.value, $3.value, 0, 0); + pc->meridian = MER24; + pc->zones_seen++; + pc->time_zone = time_zone_hhmm (pc, $4, -1); + } + | tUNUMBER ':' tUNUMBER ':' unsigned_seconds + { + set_hhmmss (pc, $1.value, $3.value, $5.tv_sec, $5.tv_nsec); + pc->meridian = MER24; + } + | tUNUMBER ':' tUNUMBER ':' unsigned_seconds tSNUMBER + { + set_hhmmss (pc, $1.value, $3.value, $5.tv_sec, $5.tv_nsec); + pc->meridian = MER24; + pc->zones_seen++; + pc->time_zone = time_zone_hhmm (pc, $6, -1); + } + ; local_zone: tLOCAL_ZONE @@ -404,6 +440,8 @@ zone: apply_relative_time (pc, $2, 1); } | tZONE tSNUMBER o_colon_minutes { pc->time_zone = $1 + time_zone_hhmm (pc, $2, $3); } + | tZONE tSNUMBER + { pc->time_zone = $1 + time_zone_hhmm (pc, $2, -1); } | tDAYZONE { pc->time_zone = $1 + 60; } | tZONE tDST @@ -609,16 +647,12 @@ hybrid: ; o_colon_minutes: - /* empty */ - { $$ = -1; } - | ':' tUNUMBER + ':' tUNUMBER { $$ = $2.value; } ; o_merid: - /* empty */ - { $$ = MER24; } - | tMERIDIAN + tMERIDIAN { $$ = $1; } ; diff --git a/tests/test-getdate.c b/tests/test-getdate.c index ea70527..cbc3e29 100644 --- a/tests/test-getdate.c +++ b/tests/test-getdate.c @@ -224,6 +224,34 @@ main (int argc, char **argv) ASSERT (result.tv_sec == result2.tv_sec && result.tv_nsec == result2.tv_nsec); + /* Check relative time-offsets without specified timezone */ + now.tv_sec = 4711; + now.tv_nsec = 1267; + p = "-8 minutes"; + ASSERT (get_date (&result, p, &now)); + LOG (p, now, result); + p = "8 minutes ago"; + ASSERT (get_date (&result2, p, &now)); + LOG (p, now, result2); + ASSERT (result.tv_sec == result2.tv_sec + && result.tv_nsec == result2.tv_nsec); + p = "+8 hours"; + ASSERT (get_date (&result, p, &now)); + LOG (p, now, result); + p = "8 hours"; + ASSERT (get_date (&result2, p, &now)); + LOG (p, now, result2); + ASSERT (result.tv_sec == result2.tv_sec + && result.tv_nsec == result2.tv_nsec); + p = "UTC +8 hours"; + ASSERT (get_date (&result, p, &now)); + LOG (p, now, result); + p = "UTC 8 hours"; + ASSERT (get_date (&result2, p, &now)); + LOG (p, now, result2); + ASSERT (result.tv_sec == result2.tv_sec + && result.tv_nsec == result2.tv_nsec); + /* Check that some "next Monday", "last Wednesday", etc. are correct. */ putenv ("TZ=UTC0"); for (i = 0; day_table[i]; i++) -- 1.5.6.1.156.ge903b