X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fparse-datetime.y;h=4dce7fa644c6513f8f48619a852776260a0f4b70;hb=5191b3546cfb6c163228c23f214e325ddf60d46f;hp=d99c9558e8383452d9c471f354202008ecf41a36;hpb=8bfd590069540f3fa8500bb496502ad675fdc148;p=gnulib.git diff --git a/lib/parse-datetime.y b/lib/parse-datetime.y index d99c9558e..4dce7fa64 100644 --- a/lib/parse-datetime.y +++ b/lib/parse-datetime.y @@ -1,7 +1,7 @@ %{ /* Parse a string into an internal time stamp. - Copyright (C) 1999-2000, 2002-2011 Free Software Foundation, Inc. + Copyright (C) 1999-2000, 2002-2013 Free Software Foundation, 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 @@ -82,7 +82,7 @@ - It's typically faster. POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to isdigit unless it's important to use the locale's definition - of `digit' even when the host does not conform to POSIX. */ + of "digit" even when the host does not conform to POSIX. */ #define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9) /* Shift A right by B bits portably, by dividing A by 2**B and @@ -113,6 +113,11 @@ typedef long int long_time_t; typedef time_t long_time_t; #endif +/* Convert a possibly-signed character to an unsigned character. This is + a bit safer than casting to unsigned char, since it catches some type + errors that the cast doesn't. */ +static unsigned char to_uchar (char ch) { return ch; } + /* Lots of this code assumes time_t and time_t-like values fit into long_time_t. */ verify (TYPE_MINIMUM (long_time_t) <= TYPE_MINIMUM (time_t) @@ -204,7 +209,7 @@ typedef struct size_t times_seen; size_t zones_seen; - /* Table of local time zone abbrevations, terminated by a null entry. */ + /* Table of local time zone abbreviations, terminated by a null entry. */ table local_time_zone_table[3]; } parser_control; @@ -754,7 +759,7 @@ static table const universal_time_zone_table[] = zone abbreviations are ambiguous; e.g. Australians interpret "EST" as Eastern time in Australia, not as US Eastern Standard Time. You cannot rely on parse_datetime to handle arbitrary time zone - abbreviations; use numeric abbreviations like `-0500' instead. */ + abbreviations; use numeric abbreviations like "-0500" instead. */ static table const time_zone_table[] = { { "WET", tZONE, HOUR ( 0) }, /* Western European */ @@ -905,7 +910,7 @@ to_year (textint textyear) return year; } -static table const * +static table const * _GL_ATTRIBUTE_PURE lookup_zone (parser_control const *pc, char const *name) { table const *tp; @@ -1171,7 +1176,8 @@ yylex (YYSTYPE *lvalp, parser_control *pc) } if (c != '(') - return *pc->input++; + return to_uchar (*pc->input++); + count = 0; do { @@ -1394,7 +1400,7 @@ parse_datetime (struct timespec *result, char const *p, && ! strcmp (pc.local_time_zone_table[0].name, pc.local_time_zone_table[1].name)) { - /* This locale uses the same abbrevation for standard and + /* This locale uses the same abbreviation for standard and daylight times. So if we see that abbreviation, we don't know whether it's daylight time. */ pc.local_time_zone_table[0].value = -1; @@ -1466,7 +1472,7 @@ parse_datetime (struct timespec *result, char const *p, + sizeof pc.time_zone * CHAR_BIT / 3]; if (!tz_was_altered) tz0 = get_tz (tz0buf); - sprintf (tz1buf, "XXX%s%ld:%02d", "-" + (time_zone < 0), + sprintf (tz1buf, "XXX%s%ld:%02d", &"-"[time_zone < 0], abs_time_zone_hour, abs_time_zone_min); if (setenv ("TZ", tz1buf, 1) != 0) goto fail;