projects
/
gnulib.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Update after module 'select' was created.
[gnulib.git]
/
lib
/
getdate.y
diff --git
a/lib/getdate.y
b/lib/getdate.y
index
9171147
..
877b264
100644
(file)
--- a/
lib/getdate.y
+++ b/
lib/getdate.y
@@
-1,8
+1,8
@@
%{
/* Parse a string into an internal time stamp.
%{
/* Parse a string into an internal time stamp.
- Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007
Free Software
- Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007
, 2008
+ F
ree Software F
oundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@
-60,7
+60,7
@@
# undef static
#endif
# undef static
#endif
-#include <ctype.h>
+#include <c
-c
type.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
@@
-205,7
+205,7
@@
typedef struct
union YYSTYPE;
static int yylex (union YYSTYPE *, parser_control *);
static int yyerror (parser_control const *, char const *);
union YYSTYPE;
static int yylex (union YYSTYPE *, parser_control *);
static int yyerror (parser_control const *, char const *);
-static long int time_zone_hhmm (textint, long int);
+static long int time_zone_hhmm (
parser_control *,
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,
/* 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,
@@
-293,7
+293,7
@@
set_hhmmss (parser_control *pc, long int hour, long int minutes,
%token tAGO tDST
%token tYEAR_UNIT tMONTH_UNIT tHOUR_UNIT tMINUTE_UNIT tSEC_UNIT
%token tAGO tDST
%token tYEAR_UNIT tMONTH_UNIT tHOUR_UNIT tMINUTE_UNIT tSEC_UNIT
-%token <intval> tDAY_UNIT
+%token <intval> tDAY_UNIT
tDAY_SHIFT
%token <intval> tDAY tDAYZONE tLOCAL_ZONE tMERIDIAN
%token <intval> tMONTH tORDINAL tZONE
%token <intval> tDAY tDAYZONE tLOCAL_ZONE tMERIDIAN
%token <intval> tMONTH tORDINAL tZONE
@@
-304,7
+304,7
@@
set_hhmmss (parser_control *pc, long int hour, long int minutes,
%type <intval> o_colon_minutes o_merid
%type <timespec> seconds signed_seconds unsigned_seconds
%type <intval> o_colon_minutes o_merid
%type <timespec> seconds signed_seconds unsigned_seconds
-%type <rel> relunit relunit_snumber
+%type <rel> relunit relunit_snumber
dayshift
%%
%%
@@
-358,7
+358,7
@@
time:
set_hhmmss (pc, $1.value, $3.value, 0, 0);
pc->meridian = MER24;
pc->zones_seen++;
set_hhmmss (pc, $1.value, $3.value, 0, 0);
pc->meridian = MER24;
pc->zones_seen++;
- pc->time_zone = time_zone_hhmm ($4, $5);
+ pc->time_zone = time_zone_hhmm (
pc,
$4, $5);
}
| tUNUMBER ':' tUNUMBER ':' unsigned_seconds o_merid
{
}
| tUNUMBER ':' tUNUMBER ':' unsigned_seconds o_merid
{
@@
-370,7
+370,7
@@
time:
set_hhmmss (pc, $1.value, $3.value, $5.tv_sec, $5.tv_nsec);
pc->meridian = MER24;
pc->zones_seen++;
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 ($6, $7);
+ pc->time_zone = time_zone_hhmm (
pc,
$6, $7);
}
;
}
;
@@
-394,7
+394,7
@@
zone:
{ pc->time_zone = $1;
apply_relative_time (pc, $2, 1); }
| tZONE tSNUMBER o_colon_minutes
{ pc->time_zone = $1;
apply_relative_time (pc, $2, 1); }
| tZONE tSNUMBER o_colon_minutes
- { pc->time_zone = $1 + time_zone_hhmm ($2, $3); }
+ { pc->time_zone = $1 + time_zone_hhmm (
pc,
$2, $3); }
| tDAYZONE
{ pc->time_zone = $1 + 60; }
| tZONE tDST
| tDAYZONE
{ pc->time_zone = $1 + 60; }
| tZONE tDST
@@
-502,6
+502,8
@@
rel:
{ apply_relative_time (pc, $1, -1); }
| relunit
{ apply_relative_time (pc, $1, 1); }
{ apply_relative_time (pc, $1, -1); }
| relunit
{ apply_relative_time (pc, $1, 1); }
+ | dayshift
+ { apply_relative_time (pc, $1, 1); }
;
relunit:
;
relunit:
@@
-563,6
+565,11
@@
relunit_snumber:
{ $$ = RELATIVE_TIME_0; $$.seconds = $1.value; }
;
{ $$ = RELATIVE_TIME_0; $$.seconds = $1.value; }
;
+dayshift:
+ tDAY_SHIFT
+ { $$ = RELATIVE_TIME_0; $$.day = $1; }
+ ;
+
seconds: signed_seconds | unsigned_seconds;
signed_seconds:
seconds: signed_seconds | unsigned_seconds;
signed_seconds:
@@
-669,10
+676,10
@@
static table const time_units_table[] =
/* Assorted relative-time words. */
static table const relative_time_table[] =
{
/* Assorted relative-time words. */
static table const relative_time_table[] =
{
- { "TOMORROW", tDAY_
UNIT,
1 },
- { "YESTERDAY",tDAY_
UNIT,
-1 },
- { "TODAY", tDAY_
UNIT,
0 },
- { "NOW", tDAY_
UNIT,
0 },
+ { "TOMORROW", tDAY_
SHIFT,
1 },
+ { "YESTERDAY",tDAY_
SHIFT,
-1 },
+ { "TODAY", tDAY_
SHIFT,
0 },
+ { "NOW", tDAY_
SHIFT,
0 },
{ "LAST", tORDINAL, -1 },
{ "THIS", tORDINAL, 0 },
{ "NEXT", tORDINAL, 1 },
{ "LAST", tORDINAL, -1 },
{ "THIS", tORDINAL, 0 },
{ "NEXT", tORDINAL, 1 },
@@
-795,15
+802,33
@@
static table const military_table[] =
/* Convert a time zone expressed as HH:MM into an integer count of
minutes. If MM is negative, then S is of the form HHMM and needs
/* Convert a time zone expressed as HH:MM into an integer count of
minutes. If MM is negative, then S is of the form HHMM and needs
- to be picked apart; otherwise, S is of the form HH. */
+ to be picked apart; otherwise, S is of the form HH. As specified in
+ http://www.opengroup.org/susv3xbd/xbd_chap08.html#tag_08_03, allow
+ only valid TZ range, and consider first two digits as hours, if no
+ minutes specified. */
static long int
static long int
-time_zone_hhmm (textint s, long int mm)
+time_zone_hhmm (
parser_control *pc,
textint s, long int mm)
{
{
+ long int n_minutes;
+
+ /* If the length of S is 1 or 2 and no minutes are specified,
+ interpret it as a number of hours. */
+ if (s.digits <= 2 && mm < 0)
+ s.value *= 100;
+
if (mm < 0)
if (mm < 0)
-
return
(s.value / 100) * 60 + s.value % 100;
+
n_minutes =
(s.value / 100) * 60 + s.value % 100;
else
else
- return s.value * 60 + (s.negative ? -mm : mm);
+ n_minutes = s.value * 60 + (s.negative ? -mm : mm);
+
+ /* If the absolute number of minutes is larger than 24 hours,
+ arrange to reject it by incrementing pc->zones_seen. Thus,
+ we allow only values in the range UTC-24:00 to UTC+24:00. */
+ if (24 * 60 < abs (n_minutes))
+ pc->zones_seen++;
+
+ return n_minutes;
}
static int
}
static int
@@
-900,7
+925,7
@@
lookup_word (parser_control const *pc, char *word)
for (p = word; *p; p++)
{
unsigned char ch = *p;
for (p = word; *p; p++)
{
unsigned char ch = *p;
- *p = toupper (ch);
+ *p =
c_
toupper (ch);
}
for (tp = meridian_table; tp->name; tp++)
}
for (tp = meridian_table; tp->name; tp++)
@@
-965,7
+990,7
@@
yylex (YYSTYPE *lvalp, parser_control *pc)
for (;;)
{
for (;;)
{
- while (c = *pc->input, isspace (c))
+ while (c = *pc->input,
c_
isspace (c))
pc->input++;
if (ISDIGIT (c) || c == '-' || c == '+')
pc->input++;
if (ISDIGIT (c) || c == '-' || c == '+')
@@
-976,7
+1001,7
@@
yylex (YYSTYPE *lvalp, parser_control *pc)
if (c == '-' || c == '+')
{
sign = c == '-' ? -1 : 1;
if (c == '-' || c == '+')
{
sign = c == '-' ? -1 : 1;
- while (c = *++pc->input, isspace (c))
+ while (c = *++pc->input,
c_
isspace (c))
continue;
if (! ISDIGIT (c))
/* skip the '-' sign */
continue;
if (! ISDIGIT (c))
/* skip the '-' sign */
@@
-1080,7
+1105,7
@@
yylex (YYSTYPE *lvalp, parser_control *pc)
}
}
}
}
- if (isalpha (c))
+ if (
c_
isalpha (c))
{
char buff[20];
char *p = buff;
{
char buff[20];
char *p = buff;
@@
-1092,7
+1117,7
@@
yylex (YYSTYPE *lvalp, parser_control *pc)
*p++ = c;
c = *++pc->input;
}
*p++ = c;
c = *++pc->input;
}
- while (isalpha (c) || c == '.');
+ while (
c_
isalpha (c) || c == '.');
*p = '\0';
tp = lookup_word (pc, buff);
*p = '\0';
tp = lookup_word (pc, buff);
@@
-1205,7
+1230,7
@@
get_date (struct timespec *result, char const *p, struct timespec const *now)
if (! tmp)
return false;
if (! tmp)
return false;
- while (c = *p, isspace (c))
+ while (c = *p,
c_
isspace (c))
p++;
if (strncmp (p, "TZ=\"", 4) == 0)
p++;
if (strncmp (p, "TZ=\"", 4) == 0)
@@
-1417,25
+1442,6
@@
get_date (struct timespec *result, char const *p, struct timespec const *now)
goto fail;
}
goto fail;
}
- if (pc.zones_seen)
- {
- long int delta = pc.time_zone * 60;
- time_t t1;
-#ifdef HAVE_TM_GMTOFF
- delta -= tm.tm_gmtoff;
-#else
- time_t t = Start;
- struct tm const *gmt = gmtime (&t);
- if (! gmt)
- goto fail;
- delta -= tm_diff (&tm, gmt);
-#endif
- t1 = Start - delta;
- if ((Start < t1) != (delta < 0))
- goto fail; /* time_t overflow */
- Start = t1;
- }
-
/* Add relative date. */
if (pc.rel.year | pc.rel.month | pc.rel.day)
{
/* Add relative date. */
if (pc.rel.year | pc.rel.month | pc.rel.day)
{
@@
-1458,6
+1464,27
@@
get_date (struct timespec *result, char const *p, struct timespec const *now)
goto fail;
}
goto fail;
}
+ /* The only "output" of this if-block is an updated Start value,
+ so this block must follow others that clobber Start. */
+ if (pc.zones_seen)
+ {
+ long int delta = pc.time_zone * 60;
+ time_t t1;
+#ifdef HAVE_TM_GMTOFF
+ delta -= tm.tm_gmtoff;
+#else
+ time_t t = Start;
+ struct tm const *gmt = gmtime (&t);
+ if (! gmt)
+ goto fail;
+ delta -= tm_diff (&tm, gmt);
+#endif
+ t1 = Start - delta;
+ if ((Start < t1) != (delta < 0))
+ goto fail; /* time_t overflow */
+ Start = t1;
+ }
+
/* Add relative hours, minutes, and seconds. On hosts that support
leap seconds, ignore the possibility of leap seconds; e.g.,
"+ 10 minutes" adds 600 seconds, even if one of them is a
/* Add relative hours, minutes, and seconds. On hosts that support
leap seconds, ignore the possibility of leap seconds; e.g.,
"+ 10 minutes" adds 600 seconds, even if one of them is a