Ondřej Vašík <[EMAIL PROTECTED]> wrote: ... > I improved previous patch, created hybrid section - as is more clean > to have such things out of common sections (maybe same thing from "zone" > section should be moved here - of course with pc->zones_seen++) and used > the same code as is in "number" section + relative signed offset code. > > This should solve your objection. Is the patch now acceptable?
Hi Ondřej, Almost. There was too much duplication, no ChangeLog entry, and no test case. I've taken care of those. FYI, here is a patch adding two tests to coreutils: diff --git a/tests/misc/date b/tests/misc/date index 7408ea2..838c54a 100755 --- a/tests/misc/date +++ b/tests/misc/date @@ -134,6 +134,11 @@ my @Tests = ['next-mo', "-d '$d1 next month' '+%Y-%m-%d %T'", {OUT=>"$dm $t0"}], ['next-y', "-d '$d1 next year' '+%Y-%m-%d %T'", {OUT=>"$dy $t0"}], + # This has always worked, ... + ['rel-1', "-d '20050101 1 day' +%F", {OUT=>"2005-01-02"}], + # ...but up to coreutils-6.9, this was rejected due to the "+". + ['rel-1p', "-d '20050101 +1 day' +%F", {OUT=>"2005-01-02"}], + ['utc-0', "-u -d '08/01/97 6:00' '+%D,%H:%M'", {OUT=>"08/01/97,06:00"}, {ENV => 'TZ=UTC+4'}], And here's the part that affects gnulib. I'll wait for Paul to give feedback, since he's listed as the owner of the getdate module. Once the gnulib change goes in, I'll add the coreutils tests. +2007-11-22 Ondřej Vašík <[EMAIL PROTECTED]> + and Jim Meyering <[EMAIL PROTECTED]> + + Adjust getdate' grammar to accept a slightly more regular language. + E.g., accept "YYYYMMDD +N days" as well as "YYYYMMDD N days". + Before, the former was rejected. + * lib/getdate.y (digits_to_date_time): New function, factored + out of ... + (number): ...here. Just call digits_to_date_time. + (hybrid): New non-terminal to handle an <unsigned number, + signed relative offset> sequence consistently. + 2007-11-18 Jim Meyering <[EMAIL PROTECTED]> Pull my changes from coreutils: diff --git a/lib/getdate.y b/lib/getdate.y index 591c7f0..e292f5e 100644 --- a/lib/getdate.y +++ b/lib/getdate.y @@ -208,6 +208,45 @@ static int yylex (union YYSTYPE *, parser_control *); static int yyerror (parser_control const *, char const *); static long int time_zone_hhmm (textint, long int); +/* Extract into *PC any date and time info from a string of digits + of the form e.g., YYYYMMDD, YYMMDD, HHMM, HH (and sometimes YYY, + YYYY, ...). */ +static void +digits_to_date_time (parser_control *pc, textint text_int) +{ + if (pc->dates_seen && ! pc->year.digits + && ! pc->rels_seen && (pc->times_seen || 2 < text_int.digits)) + pc->year = text_int; + else + { + if (4 < text_int.digits) + { + pc->dates_seen++; + pc->day = text_int.value % 100; + pc->month = (text_int.value / 100) % 100; + pc->year.value = text_int.value / 10000; + pc->year.digits = text_int.digits - 4; + } + else + { + pc->times_seen++; + if (text_int.digits <= 2) + { + pc->hour = text_int.value; + pc->minutes = 0; + } + else + { + pc->hour = text_int.value / 100; + pc->minutes = text_int.value % 100; + } + pc->seconds.tv_sec = 0; + pc->seconds.tv_nsec = 0; + pc->meridian = MER24; + } + } +} + %} /* We want a reentrant parser, even if the TZ manipulation and the calls to @@ -277,6 +316,7 @@ item: | rel { pc->rels_seen = true; } | number + | hybrid ; time: @@ -552,38 +592,23 @@ unsigned_seconds: number: tUNUMBER + { digits_to_date_time (pc, $1); } + ; + +hybrid: + tUNUMBER relunit_snumber { - if (pc->dates_seen && ! pc->year.digits - && ! pc->rels_seen && (pc->times_seen || 2 < $1.digits)) - pc->year = $1; - else - { - if (4 < $1.digits) - { - pc->dates_seen++; - pc->day = $1.value % 100; - pc->month = ($1.value / 100) % 100; - pc->year.value = $1.value / 10000; - pc->year.digits = $1.digits - 4; - } - else - { - pc->times_seen++; - if ($1.digits <= 2) - { - pc->hour = $1.value; - pc->minutes = 0; - } - else - { - pc->hour = $1.value / 100; - pc->minutes = $1.value % 100; - } - pc->seconds.tv_sec = 0; - pc->seconds.tv_nsec = 0; - pc->meridian = MER24; - } - } + /* Hybrid all-digit and relative offset, so that we accept e.g., + "YYYYMMDD +N days" as well as "YYYYMMDD N days". */ + digits_to_date_time (pc, $1); + pc->rel.ns += $2.ns; + pc->rel.seconds += $2.seconds; + pc->rel.minutes += $2.minutes; + pc->rel.hour += $2.hour; + pc->rel.day += $2.day; + pc->rel.month += $2.month; + pc->rel.year += $2.year; + pc->rels_seen = true; } ; -- 1.5.3.6.736.gb7f30