am 4d016c6a: Merge "Upgrade to tzcode2013f plus Android modifications (from tzcode2013d plus Android modifications)."

* commit '4d016c6a83bb8c8b8ec88400031b42c41f18edbb':
  Upgrade to tzcode2013f plus Android modifications (from tzcode2013d plus Android modifications).
This commit is contained in:
Elliott Hughes 2013-09-27 15:41:25 -07:00 committed by Android Git Automerger
commit ef8eb55708
5 changed files with 82 additions and 83 deletions

View File

@ -5,7 +5,7 @@
/*LINTLIBRARY*/ /*LINTLIBRARY*/
#include "private.h" /* for time_t, TYPE_INTEGRAL, and TYPE_SIGNED */ #include "private.h" /* for time_t and TYPE_SIGNED */
double ATTRIBUTE_CONST double ATTRIBUTE_CONST
difftime(const time_t time1, const time_t time0) difftime(const time_t time1, const time_t time0)
@ -16,15 +16,8 @@ difftime(const time_t time1, const time_t time0)
*/ */
if (sizeof (double) > sizeof (time_t)) if (sizeof (double) > sizeof (time_t))
return (double) time1 - (double) time0; return (double) time1 - (double) time0;
if (!TYPE_INTEGRAL(time_t)) {
/*
** time_t is floating.
*/
return time1 - time0;
}
if (!TYPE_SIGNED(time_t)) { if (!TYPE_SIGNED(time_t)) {
/* /*
** time_t is integral and unsigned.
** The difference of two unsigned values can't overflow ** The difference of two unsigned values can't overflow
** if the minuend is greater than or equal to the subtrahend. ** if the minuend is greater than or equal to the subtrahend.
*/ */
@ -33,7 +26,6 @@ difftime(const time_t time1, const time_t time0)
else return -(double) (time0 - time1); else return -(double) (time0 - time1);
} }
/* /*
** time_t is integral and signed.
** Handle cases where both time1 and time0 have the same sign ** Handle cases where both time1 and time0 have the same sign
** (meaning that their difference cannot overflow). ** (meaning that their difference cannot overflow).
*/ */

View File

@ -13,7 +13,6 @@
#include "private.h" #include "private.h"
#include "tzfile.h" #include "tzfile.h"
#include "fcntl.h" #include "fcntl.h"
#include "float.h" /* for FLT_MAX and DBL_MAX */
#ifndef TZ_ABBR_MAX_LEN #ifndef TZ_ABBR_MAX_LEN
#define TZ_ABBR_MAX_LEN 16 #define TZ_ABBR_MAX_LEN 16
@ -91,11 +90,11 @@ static const char gmt[] = "GMT";
#endif /* !defined TZDEFDST */ #endif /* !defined TZDEFDST */
struct ttinfo { /* time type information */ struct ttinfo { /* time type information */
int_fast32_t tt_gmtoff; /* UTC offset in seconds */ int_fast32_t tt_gmtoff; /* UT offset in seconds */
int tt_isdst; /* used to set tm_isdst */ int tt_isdst; /* used to set tm_isdst */
int tt_abbrind; /* abbreviation list index */ int tt_abbrind; /* abbreviation list index */
int tt_ttisstd; /* TRUE if transition is std time */ int tt_ttisstd; /* TRUE if transition is std time */
int tt_ttisgmt; /* TRUE if transition is UTC */ int tt_ttisgmt; /* TRUE if transition is UT */
}; };
struct lsinfo { /* leap second information */ struct lsinfo { /* leap second information */
@ -232,12 +231,12 @@ char * tzname[2] = {
static struct tm tmGlobal; static struct tm tmGlobal;
#ifdef USG_COMPAT #ifdef USG_COMPAT
time_t timezone = 0; long timezone = 0;
int daylight = 0; int daylight = 0;
#endif /* defined USG_COMPAT */ #endif /* defined USG_COMPAT */
#ifdef ALTZONE #ifdef ALTZONE
time_t altzone = 0; long altzone = 0;
#endif /* defined ALTZONE */ #endif /* defined ALTZONE */
static int_fast32_t static int_fast32_t
@ -334,8 +333,7 @@ settzname(void)
static int static int
differ_by_repeat(const time_t t1, const time_t t0) differ_by_repeat(const time_t t1, const time_t t0)
{ {
if (TYPE_INTEGRAL(time_t) && if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
return 0; return 0;
return t1 - t0 == SECSPERREPEAT; return t1 - t0 == SECSPERREPEAT;
} }
@ -514,9 +512,9 @@ tzload(register const char* name, register struct state* const sp,
for (i = 0; i < nread; ++i) for (i = 0; i < nread; ++i)
up->buf[i] = p[i]; up->buf[i] = p[i];
/* /*
** If this is a narrow integer time_t system, we're done. ** If this is a narrow time_t system, we're done.
*/ */
if (stored >= (int) sizeof(time_t) && TYPE_INTEGRAL(time_t)) if (stored >= (int) sizeof(time_t))
break; break;
} }
if (doextend && nread > 2 && if (doextend && nread > 2 &&
@ -824,14 +822,14 @@ getrule(const char * strp, register struct rule * const rulep)
** Time specified. ** Time specified.
*/ */
++strp; ++strp;
strp = getsecs(strp, &rulep->r_time); strp = getoffset(strp, &rulep->r_time);
} else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
return strp; return strp;
} }
/* /*
** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the ** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
** year, a rule, and the offset from UTC at the time that rule takes effect, ** year, a rule, and the offset from UT at the time that rule takes effect,
** calculate the Epoch-relative time that rule takes effect. ** calculate the Epoch-relative time that rule takes effect.
*/ */
@ -914,10 +912,10 @@ transtime(const time_t janfirst, const int year,
} }
/* /*
** "value" is the Epoch-relative time of 00:00:00 UTC on the day in ** "value" is the Epoch-relative time of 00:00:00 UT on the day in
** question. To get the Epoch-relative time of the specified local ** question. To get the Epoch-relative time of the specified local
** time on that day, add the transition time and the current offset ** time on that day, add the transition time and the current offset
** from UTC. ** from UT.
*/ */
return value + rulep->r_time + offset; return value + rulep->r_time + offset;
} }
@ -997,6 +995,7 @@ tzparse(const char * name, register struct state * const sp,
struct rule start; struct rule start;
struct rule end; struct rule end;
register int year; register int year;
register int yearlim;
register time_t janfirst; register time_t janfirst;
time_t starttime; time_t starttime;
time_t endtime; time_t endtime;
@ -1024,35 +1023,43 @@ tzparse(const char * name, register struct state * const sp,
atp = sp->ats; atp = sp->ats;
typep = sp->types; typep = sp->types;
janfirst = 0; janfirst = 0;
sp->timecnt = 0; yearlim = EPOCH_YEAR + YEARSPERREPEAT;
for (year = EPOCH_YEAR; for (year = EPOCH_YEAR; year < yearlim; year++) {
sp->timecnt + 2 <= TZ_MAX_TIMES; int_fast32_t yearsecs;
++year) {
time_t newfirst;
starttime = transtime(janfirst, year, &start, starttime = transtime(janfirst, year, &start,
stdoffset); stdoffset);
endtime = transtime(janfirst, year, &end, endtime = transtime(janfirst, year, &end,
dstoffset); dstoffset);
if (starttime > endtime) { yearsecs = (year_lengths[isleap(year)]
*atp++ = endtime; * SECSPERDAY);
*typep++ = 1; /* DST ends */ if (starttime > endtime
*atp++ = starttime; || (starttime < endtime
*typep++ = 0; /* DST begins */ && (endtime - starttime
} else { < (yearsecs
*atp++ = starttime; + (stdoffset - dstoffset))))) {
*typep++ = 0; /* DST begins */ if (&sp->ats[TZ_MAX_TIMES - 2] < atp)
*atp++ = endtime; break;
*typep++ = 1; /* DST ends */ yearlim = year + YEARSPERREPEAT + 1;
if (starttime > endtime) {
*atp++ = endtime;
*typep++ = 1; /* DST ends */
*atp++ = starttime;
*typep++ = 0; /* DST begins */
} else {
*atp++ = starttime;
*typep++ = 0; /* DST begins */
*atp++ = endtime;
*typep++ = 1; /* DST ends */
}
} }
sp->timecnt += 2; if (time_t_max - janfirst < yearsecs)
newfirst = janfirst;
newfirst += year_lengths[isleap(year)] *
SECSPERDAY;
if (newfirst <= janfirst)
break; break;
janfirst = newfirst; janfirst += yearsecs;
} }
sp->timecnt = atp - sp->ats;
if (!sp->timecnt)
sp->typecnt = 1; /* Perpetual DST. */
} else { } else {
register int_fast32_t theirstdoffset; register int_fast32_t theirstdoffset;
register int_fast32_t theirdstoffset; register int_fast32_t theirdstoffset;
@ -1290,21 +1297,14 @@ localsub(const time_t * const timep, const int_fast32_t offset,
(sp->goahead && t > sp->ats[sp->timecnt - 1])) { (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
time_t newt = t; time_t newt = t;
register time_t seconds; register time_t seconds;
register time_t tcycles; register time_t years;
register int_fast64_t icycles;
if (t < sp->ats[0]) if (t < sp->ats[0])
seconds = sp->ats[0] - t; seconds = sp->ats[0] - t;
else seconds = t - sp->ats[sp->timecnt - 1]; else seconds = t - sp->ats[sp->timecnt - 1];
--seconds; --seconds;
tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR; years = (seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT;
++tcycles; seconds = years * AVGSECSPERYEAR;
icycles = tcycles;
if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
return NULL;
seconds = icycles;
seconds *= YEARSPERREPEAT;
seconds *= AVGSECSPERYEAR;
if (t < sp->ats[0]) if (t < sp->ats[0])
newt += seconds; newt += seconds;
else newt -= seconds; else newt -= seconds;
@ -1317,8 +1317,8 @@ localsub(const time_t * const timep, const int_fast32_t offset,
newy = tmp->tm_year; newy = tmp->tm_year;
if (t < sp->ats[0]) if (t < sp->ats[0])
newy -= icycles * YEARSPERREPEAT; newy -= years;
else newy += icycles * YEARSPERREPEAT; else newy += years;
tmp->tm_year = newy; tmp->tm_year = newy;
if (tmp->tm_year != newy) if (tmp->tm_year != newy)
return NULL; return NULL;
@ -1403,7 +1403,7 @@ gmtsub(const time_t * const timep, const int_fast32_t offset,
#ifdef TM_ZONE #ifdef TM_ZONE
/* /*
** Could get fancy here and deliver something such as ** Could get fancy here and deliver something such as
** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero, ** "UT+xxxx" or "UT-xxxx" if offset is non-zero,
** but this is no time for a treasure hunt. ** but this is no time for a treasure hunt.
*/ */
if (offset != 0) if (offset != 0)
@ -1509,9 +1509,10 @@ timesub(const time_t *const timep, const int_fast32_t offset,
register int leapdays; register int leapdays;
tdelta = tdays / DAYSPERLYEAR; tdelta = tdays / DAYSPERLYEAR;
if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
&& tdelta <= INT_MAX))
return NULL;
idelta = tdelta; idelta = tdelta;
if (tdelta - idelta >= 1 || idelta - tdelta >= 1)
return NULL;
if (idelta == 0) if (idelta == 0)
idelta = (tdays < 0) ? -1 : 1; idelta = (tdays < 0) ? -1 : 1;
newy = y; newy = y;
@ -1525,9 +1526,8 @@ timesub(const time_t *const timep, const int_fast32_t offset,
} }
{ {
register int_fast32_t seconds; register int_fast32_t seconds;
register time_t half_second = 0.5;
seconds = tdays * SECSPERDAY + half_second; seconds = tdays * SECSPERDAY;
tdays = seconds / SECSPERDAY; tdays = seconds / SECSPERDAY;
rem += seconds - tdays * SECSPERDAY; rem += seconds - tdays * SECSPERDAY;
} }
@ -1685,8 +1685,9 @@ tmcomp(register const struct tm * const atmp,
{ {
register int result; register int result;
if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && if (atmp->tm_year != btmp->tm_year)
(result = (atmp->tm_mon - btmp->tm_mon)) == 0 && return atmp->tm_year < btmp->tm_year ? -1 : 1;
if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
(result = (atmp->tm_mday - btmp->tm_mday)) == 0 && (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
(result = (atmp->tm_hour - btmp->tm_hour)) == 0 && (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
(result = (atmp->tm_min - btmp->tm_min)) == 0) (result = (atmp->tm_min - btmp->tm_min)) == 0)
@ -1785,11 +1786,6 @@ time2sub(struct tm * const tmp,
if (!TYPE_SIGNED(time_t)) { if (!TYPE_SIGNED(time_t)) {
lo = 0; lo = 0;
hi = lo - 1; hi = lo - 1;
} else if (!TYPE_INTEGRAL(time_t)) {
if (sizeof(time_t) > sizeof(float))
hi = (time_t) DBL_MAX;
else hi = (time_t) FLT_MAX;
lo = -hi;
} else { } else {
lo = 1; lo = 1;
for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i) for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i)
@ -2019,7 +2015,7 @@ timegm(struct tm * const tmp)
** previous versions of the CMUCS runtime library. ** previous versions of the CMUCS runtime library.
*/ */
int_fast32_t long
gtime(struct tm * const tmp) gtime(struct tm * const tmp)
{ {
const time_t t = mktime(tmp); const time_t t = mktime(tmp);

View File

@ -166,10 +166,21 @@ typedef int int_fast32_t;
#ifndef INTMAX_MAX #ifndef INTMAX_MAX
# if defined LLONG_MAX || defined __LONG_LONG_MAX__ # if defined LLONG_MAX || defined __LONG_LONG_MAX__
typedef long long intmax_t; typedef long long intmax_t;
# define strtoimax strtoll
# define PRIdMAX "lld" # define PRIdMAX "lld"
# ifdef LLONG_MAX
# define INTMAX_MAX LLONG_MAX
# define INTMAX_MIN LLONG_MIN
# else
# define INTMAX_MAX __LONG_LONG_MAX__
# define INTMAX_MIN __LONG_LONG_MIN__
# endif
# else # else
typedef long intmax_t; typedef long intmax_t;
# define strtoimax strtol
# define PRIdMAX "ld" # define PRIdMAX "ld"
# define INTMAX_MAX LONG_MAX
# define INTMAX_MIN LONG_MIN
# endif # endif
#endif #endif
@ -193,9 +204,11 @@ typedef unsigned long uintmax_t;
#if 2 < __GNUC__ + (96 <= __GNUC_MINOR__) #if 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
# define ATTRIBUTE_CONST __attribute__ ((const)) # define ATTRIBUTE_CONST __attribute__ ((const))
# define ATTRIBUTE_PURE __attribute__ ((__pure__)) # define ATTRIBUTE_PURE __attribute__ ((__pure__))
# define ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
#else #else
# define ATTRIBUTE_CONST /* empty */ # define ATTRIBUTE_CONST /* empty */
# define ATTRIBUTE_PURE /* empty */ # define ATTRIBUTE_PURE /* empty */
# define ATTRIBUTE_FORMAT(spec) /* empty */
#endif #endif
#if !defined _Noreturn && __STDC_VERSION__ < 201112 #if !defined _Noreturn && __STDC_VERSION__ < 201112
@ -314,15 +327,6 @@ static time_t const time_t_max =
? - (~ 0 < 0) - ((time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1)) ? - (~ 0 < 0) - ((time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1))
: -1); : -1);
/*
** Since the definition of TYPE_INTEGRAL contains floating point numbers,
** it cannot be used in preprocessor directives.
*/
#ifndef TYPE_INTEGRAL
#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5)
#endif /* !defined TYPE_INTEGRAL */
#ifndef INT_STRLEN_MAXIMUM #ifndef INT_STRLEN_MAXIMUM
/* /*
** 302 / 1000 is log10(2.0) rounded up. ** 302 / 1000 is log10(2.0) rounded up.

View File

@ -592,7 +592,7 @@ label:
continue; continue;
case 'z': case 'z':
{ {
int diff; long diff;
char const * sign; char const * sign;
if (t->tm_isdst < 0) if (t->tm_isdst < 0)
@ -601,7 +601,7 @@ label:
diff = t->TM_GMTOFF; diff = t->TM_GMTOFF;
#else /* !defined TM_GMTOFF */ #else /* !defined TM_GMTOFF */
/* /*
** C99 says that the UTC offset must ** C99 says that the UT offset must
** be computed by looking only at ** be computed by looking only at
** tm_isdst. This requirement is ** tm_isdst. This requirement is
** incorrect, since it means the code ** incorrect, since it means the code

View File

@ -39,7 +39,7 @@
struct tzhead { struct tzhead {
char tzh_magic[4]; /* TZ_MAGIC */ char tzh_magic[4]; /* TZ_MAGIC */
char tzh_version[1]; /* '\0' or '2' as of 2005 */ char tzh_version[1]; /* '\0' or '2' or '3' as of 2013 */
char tzh_reserved[15]; /* reserved--must be zero */ char tzh_reserved[15]; /* reserved--must be zero */
char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */ char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
@ -55,7 +55,7 @@ struct tzhead {
** tzh_timecnt (char [4])s coded transition times a la time(2) ** tzh_timecnt (char [4])s coded transition times a la time(2)
** tzh_timecnt (unsigned char)s types of local time starting at above ** tzh_timecnt (unsigned char)s types of local time starting at above
** tzh_typecnt repetitions of ** tzh_typecnt repetitions of
** one (char [4]) coded UTC offset in seconds ** one (char [4]) coded UT offset in seconds
** one (unsigned char) used to set tm_isdst ** one (unsigned char) used to set tm_isdst
** one (unsigned char) that's an abbreviation list index ** one (unsigned char) that's an abbreviation list index
** tzh_charcnt (char)s '\0'-terminated zone abbreviations ** tzh_charcnt (char)s '\0'-terminated zone abbreviations
@ -68,7 +68,7 @@ struct tzhead {
** if absent, transition times are ** if absent, transition times are
** assumed to be wall clock time ** assumed to be wall clock time
** tzh_ttisgmtcnt (char)s indexed by type; if TRUE, transition ** tzh_ttisgmtcnt (char)s indexed by type; if TRUE, transition
** time is UTC, if FALSE, ** time is UT, if FALSE,
** transition time is local time ** transition time is local time
** if absent, transition times are ** if absent, transition times are
** assumed to be local time ** assumed to be local time
@ -82,6 +82,13 @@ struct tzhead {
** instants after the last transition time stored in the file ** instants after the last transition time stored in the file
** (with nothing between the newlines if there is no POSIX representation for ** (with nothing between the newlines if there is no POSIX representation for
** such instants). ** such instants).
**
** If tz_version is '3' or greater, the above is extended as follows.
** First, the POSIX TZ string's hour offset may range from -167
** through 167 as compared to the POSIX-required 0 through 24.
** Second, its DST start time may be January 1 at 00:00 and its stop
** time December 31 at 24:00 plus the difference between DST and
** standard time, indicating DST all year.
*/ */
/* /*