Updated to tzcode2005c.tar.gz
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11228 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
fa12e0eeff
commit
aafd5156d4
@ -5,7 +5,7 @@
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)localtime.c 7.80";
|
||||
static char elsieid[] = "@(#)localtime.c 7.89";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
@ -55,7 +55,7 @@ static char elsieid[] = "@(#)localtime.c 7.80";
|
||||
#define WILDABBR " "
|
||||
#endif /* !defined WILDABBR */
|
||||
|
||||
static char wildabbr[] = "WILDABBR";
|
||||
static char wildabbr[] = WILDABBR;
|
||||
|
||||
static const char gmt[] = "GMT";
|
||||
|
||||
@ -129,11 +129,12 @@ static const char * getsecs P((const char * strp, long * secsp));
|
||||
static const char * getoffset P((const char * strp, long * offsetp));
|
||||
static const char * getrule P((const char * strp, struct rule * rulep));
|
||||
static void gmtload P((struct state * sp));
|
||||
static void gmtsub P((const time_t * timep, long offset,
|
||||
static struct tm * gmtsub P((const time_t * timep, long offset,
|
||||
struct tm * tmp));
|
||||
static void localsub P((const time_t * timep, long offset,
|
||||
static struct tm * localsub P((const time_t * timep, long offset,
|
||||
struct tm * tmp));
|
||||
static int increment_overflow P((int * number, int delta));
|
||||
static int leaps_thru_end_of P((int y));
|
||||
static int long_increment_overflow P((long * number, int delta));
|
||||
static int long_normalize_overflow P((long * tensptr,
|
||||
int * unitsptr, int base));
|
||||
@ -141,18 +142,18 @@ static int normalize_overflow P((int * tensptr, int * unitsptr,
|
||||
int base));
|
||||
static void settzname P((void));
|
||||
static time_t time1 P((struct tm * tmp,
|
||||
void(*funcp) P((const time_t *,
|
||||
struct tm * (*funcp) P((const time_t *,
|
||||
long, struct tm *)),
|
||||
long offset));
|
||||
static time_t time2 P((struct tm *tmp,
|
||||
void(*funcp) P((const time_t *,
|
||||
struct tm * (*funcp) P((const time_t *,
|
||||
long, struct tm*)),
|
||||
long offset, int * okayp));
|
||||
static time_t time2sub P((struct tm *tmp,
|
||||
void(*funcp) P((const time_t *,
|
||||
struct tm * (*funcp) P((const time_t *,
|
||||
long, struct tm*)),
|
||||
long offset, int * okayp, int do_norm_secs));
|
||||
static void timesub P((const time_t * timep, long offset,
|
||||
static struct tm * timesub P((const time_t * timep, long offset,
|
||||
const struct state * sp, struct tm * tmp));
|
||||
static int tmcomp P((const struct tm * atmp,
|
||||
const struct tm * btmp));
|
||||
@ -409,6 +410,33 @@ register struct state * const sp;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
** Out-of-sort ats should mean we're running on a
|
||||
** signed time_t system but using a data file with
|
||||
** unsigned values (or vice versa).
|
||||
*/
|
||||
for (i = 0; i < sp->timecnt - 2; ++i)
|
||||
if (sp->ats[i] > sp->ats[i + 1]) {
|
||||
++i;
|
||||
if (TYPE_SIGNED(time_t)) {
|
||||
/*
|
||||
** Ignore the end (easy).
|
||||
*/
|
||||
sp->timecnt = i;
|
||||
} else {
|
||||
/*
|
||||
** Ignore the beginning (harder).
|
||||
*/
|
||||
register int j;
|
||||
|
||||
for (j = 0; j + i < sp->timecnt; ++j) {
|
||||
sp->ats[j] = sp->ats[j + i];
|
||||
sp->types[j] = sp->types[j + i];
|
||||
}
|
||||
sp->timecnt = j;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1010,7 +1038,7 @@ tzset P((void))
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
static struct tm *
|
||||
localsub(timep, offset, tmp)
|
||||
const time_t * const timep;
|
||||
const long offset;
|
||||
@ -1019,14 +1047,13 @@ struct tm * const tmp;
|
||||
register struct state * sp;
|
||||
register const struct ttinfo * ttisp;
|
||||
register int i;
|
||||
register struct tm * result;
|
||||
const time_t t = *timep;
|
||||
|
||||
sp = lclptr;
|
||||
#ifdef ALL_STATE
|
||||
if (sp == NULL) {
|
||||
gmtsub(timep, offset, tmp);
|
||||
return;
|
||||
}
|
||||
if (sp == NULL)
|
||||
return gmtsub(timep, offset, tmp);
|
||||
#endif /* defined ALL_STATE */
|
||||
if (sp->timecnt == 0 || t < sp->ats[0]) {
|
||||
i = 0;
|
||||
@ -1039,7 +1066,7 @@ struct tm * const tmp;
|
||||
for (i = 1; i < sp->timecnt; ++i)
|
||||
if (t < sp->ats[i])
|
||||
break;
|
||||
i = sp->types[i - 1];
|
||||
i = (int) sp->types[i - 1];
|
||||
}
|
||||
ttisp = &sp->ttis[i];
|
||||
/*
|
||||
@ -1048,12 +1075,13 @@ struct tm * const tmp;
|
||||
** t += ttisp->tt_gmtoff;
|
||||
** timesub(&t, 0L, sp, tmp);
|
||||
*/
|
||||
timesub(&t, ttisp->tt_gmtoff, sp, tmp);
|
||||
result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
|
||||
tmp->tm_isdst = ttisp->tt_isdst;
|
||||
tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
|
||||
#ifdef TM_ZONE
|
||||
tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
|
||||
#endif /* defined TM_ZONE */
|
||||
return result;
|
||||
}
|
||||
|
||||
struct tm *
|
||||
@ -1061,8 +1089,7 @@ localtime(timep)
|
||||
const time_t * const timep;
|
||||
{
|
||||
tzset();
|
||||
localsub(timep, 0L, &tm);
|
||||
return &tm;
|
||||
return localsub(timep, 0L, &tm);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1070,24 +1097,25 @@ const time_t * const timep;
|
||||
*/
|
||||
|
||||
struct tm *
|
||||
localtime_r(timep, tm)
|
||||
localtime_r(timep, tmp)
|
||||
const time_t * const timep;
|
||||
struct tm * tm;
|
||||
struct tm * tmp;
|
||||
{
|
||||
localsub(timep, 0L, tm);
|
||||
return tm;
|
||||
return localsub(timep, 0L, tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
** gmtsub is to gmtime as localsub is to localtime.
|
||||
*/
|
||||
|
||||
static void
|
||||
static struct tm *
|
||||
gmtsub(timep, offset, tmp)
|
||||
const time_t * const timep;
|
||||
const long offset;
|
||||
struct tm * const tmp;
|
||||
{
|
||||
register struct tm * result;
|
||||
|
||||
if (!gmt_is_set) {
|
||||
gmt_is_set = TRUE;
|
||||
#ifdef ALL_STATE
|
||||
@ -1096,7 +1124,7 @@ struct tm * const tmp;
|
||||
#endif /* defined ALL_STATE */
|
||||
gmtload(gmtptr);
|
||||
}
|
||||
timesub(timep, offset, gmtptr, tmp);
|
||||
result = timesub(timep, offset, gmtptr, tmp);
|
||||
#ifdef TM_ZONE
|
||||
/*
|
||||
** Could get fancy here and deliver something such as
|
||||
@ -1116,14 +1144,14 @@ struct tm * const tmp;
|
||||
#endif /* State Farm */
|
||||
}
|
||||
#endif /* defined TM_ZONE */
|
||||
return result;
|
||||
}
|
||||
|
||||
struct tm *
|
||||
gmtime(timep)
|
||||
const time_t * const timep;
|
||||
{
|
||||
gmtsub(timep, 0L, &tm);
|
||||
return &tm;
|
||||
return gmtsub(timep, 0L, &tm);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1131,12 +1159,11 @@ const time_t * const timep;
|
||||
*/
|
||||
|
||||
struct tm *
|
||||
gmtime_r(timep, tm)
|
||||
gmtime_r(timep, tmp)
|
||||
const time_t * const timep;
|
||||
struct tm * tm;
|
||||
struct tm * tmp;
|
||||
{
|
||||
gmtsub(timep, 0L, tm);
|
||||
return tm;
|
||||
return gmtsub(timep, 0L, tmp);
|
||||
}
|
||||
|
||||
#ifdef STD_INSPIRED
|
||||
@ -1146,13 +1173,25 @@ offtime(timep, offset)
|
||||
const time_t * const timep;
|
||||
const long offset;
|
||||
{
|
||||
gmtsub(timep, offset, &tm);
|
||||
return &tm;
|
||||
return gmtsub(timep, offset, &tm);
|
||||
}
|
||||
|
||||
#endif /* defined STD_INSPIRED */
|
||||
|
||||
static void
|
||||
/*
|
||||
** Return the number of leap years through the end of the given year
|
||||
** where, to make the math easy, the answer for year zero is defined as zero.
|
||||
*/
|
||||
|
||||
static int
|
||||
leaps_thru_end_of(y)
|
||||
register const int y;
|
||||
{
|
||||
return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
|
||||
-(leaps_thru_end_of(-(y + 1)) + 1);
|
||||
}
|
||||
|
||||
static struct tm *
|
||||
timesub(timep, offset, sp, tmp)
|
||||
const time_t * const timep;
|
||||
const long offset;
|
||||
@ -1160,10 +1199,10 @@ register const struct state * const sp;
|
||||
register struct tm * const tmp;
|
||||
{
|
||||
register const struct lsinfo * lp;
|
||||
register long days;
|
||||
register time_t tdays;
|
||||
register int idays; /* unsigned would be so 2003 */
|
||||
register long rem;
|
||||
register long y;
|
||||
register int yleap;
|
||||
int y;
|
||||
register const int * ip;
|
||||
register long corr;
|
||||
register int hit;
|
||||
@ -1197,60 +1236,93 @@ register struct tm * const tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
days = *timep / SECSPERDAY;
|
||||
rem = *timep % SECSPERDAY;
|
||||
#ifdef mc68k
|
||||
if (*timep == 0x80000000) {
|
||||
/*
|
||||
** A 3B1 muffs the division on the most negative number.
|
||||
*/
|
||||
days = -24855;
|
||||
rem = -11648;
|
||||
y = EPOCH_YEAR;
|
||||
tdays = *timep / SECSPERDAY;
|
||||
rem = *timep - tdays * SECSPERDAY;
|
||||
while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
|
||||
int newy;
|
||||
register time_t tdelta;
|
||||
register int idelta;
|
||||
register int leapdays;
|
||||
|
||||
tdelta = tdays / DAYSPERLYEAR;
|
||||
idelta = tdelta;
|
||||
if (tdelta - idelta >= 1 || idelta - tdelta >= 1)
|
||||
return NULL;
|
||||
if (idelta == 0)
|
||||
idelta = (tdays < 0) ? -1 : 1;
|
||||
newy = y;
|
||||
if (increment_overflow(&newy, idelta))
|
||||
return NULL;
|
||||
leapdays = leaps_thru_end_of(newy - 1) -
|
||||
leaps_thru_end_of(y - 1);
|
||||
tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
|
||||
tdays -= leapdays;
|
||||
y = newy;
|
||||
}
|
||||
#endif /* defined mc68k */
|
||||
rem += (offset - corr);
|
||||
{
|
||||
register long seconds;
|
||||
|
||||
seconds = tdays * SECSPERDAY + 0.5;
|
||||
tdays = seconds / SECSPERDAY;
|
||||
rem += seconds - tdays * SECSPERDAY;
|
||||
}
|
||||
/*
|
||||
** Given the range, we can now fearlessly cast...
|
||||
*/
|
||||
idays = tdays;
|
||||
rem += offset - corr;
|
||||
while (rem < 0) {
|
||||
rem += SECSPERDAY;
|
||||
--days;
|
||||
--idays;
|
||||
}
|
||||
while (rem >= SECSPERDAY) {
|
||||
rem -= SECSPERDAY;
|
||||
++days;
|
||||
++idays;
|
||||
}
|
||||
while (idays < 0) {
|
||||
if (increment_overflow(&y, -1))
|
||||
return NULL;
|
||||
idays += year_lengths[isleap(y)];
|
||||
}
|
||||
while (idays >= year_lengths[isleap(y)]) {
|
||||
idays -= year_lengths[isleap(y)];
|
||||
if (increment_overflow(&y, 1))
|
||||
return NULL;
|
||||
}
|
||||
tmp->tm_year = y;
|
||||
if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
|
||||
return NULL;
|
||||
tmp->tm_yday = idays;
|
||||
/*
|
||||
** The "extra" mods below avoid overflow problems.
|
||||
*/
|
||||
tmp->tm_wday = EPOCH_WDAY +
|
||||
((y - EPOCH_YEAR) % DAYSPERWEEK) *
|
||||
(DAYSPERNYEAR % DAYSPERWEEK) +
|
||||
leaps_thru_end_of(y - 1) -
|
||||
leaps_thru_end_of(EPOCH_YEAR - 1) +
|
||||
idays;
|
||||
tmp->tm_wday %= DAYSPERWEEK;
|
||||
if (tmp->tm_wday < 0)
|
||||
tmp->tm_wday += DAYSPERWEEK;
|
||||
tmp->tm_hour = (int) (rem / SECSPERHOUR);
|
||||
rem = rem % SECSPERHOUR;
|
||||
rem %= SECSPERHOUR;
|
||||
tmp->tm_min = (int) (rem / SECSPERMIN);
|
||||
/*
|
||||
** A positive leap second requires a special
|
||||
** representation. This uses "... ??:59:60" et seq.
|
||||
*/
|
||||
tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
|
||||
tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
|
||||
if (tmp->tm_wday < 0)
|
||||
tmp->tm_wday += DAYSPERWEEK;
|
||||
y = EPOCH_YEAR;
|
||||
#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
|
||||
while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
|
||||
register long newy;
|
||||
|
||||
newy = y + days / DAYSPERNYEAR;
|
||||
if (days < 0)
|
||||
--newy;
|
||||
days -= (newy - y) * DAYSPERNYEAR +
|
||||
LEAPS_THRU_END_OF(newy - 1) -
|
||||
LEAPS_THRU_END_OF(y - 1);
|
||||
y = newy;
|
||||
}
|
||||
tmp->tm_year = y - TM_YEAR_BASE;
|
||||
tmp->tm_yday = (int) days;
|
||||
ip = mon_lengths[yleap];
|
||||
for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
|
||||
days = days - (long) ip[tmp->tm_mon];
|
||||
tmp->tm_mday = (int) (days + 1);
|
||||
ip = mon_lengths[isleap(y)];
|
||||
for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
|
||||
idays -= ip[tmp->tm_mon];
|
||||
tmp->tm_mday = (int) (idays + 1);
|
||||
tmp->tm_isdst = 0;
|
||||
#ifdef TM_GMTOFF
|
||||
tmp->TM_GMTOFF = offset;
|
||||
#endif /* defined TM_GMTOFF */
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
@ -1345,17 +1417,18 @@ register const struct tm * const btmp;
|
||||
static time_t
|
||||
time2sub(tmp, funcp, offset, okayp, do_norm_secs)
|
||||
struct tm * const tmp;
|
||||
void (* const funcp) P((const time_t*, long, struct tm*));
|
||||
struct tm * (* const funcp) P((const time_t*, long, struct tm*));
|
||||
const long offset;
|
||||
int * const okayp;
|
||||
const int do_norm_secs;
|
||||
{
|
||||
register const struct state * sp;
|
||||
register int dir;
|
||||
register int bits;
|
||||
register int i, j;
|
||||
register int saved_seconds;
|
||||
register long li;
|
||||
register time_t lo;
|
||||
register time_t hi;
|
||||
long y;
|
||||
time_t newt;
|
||||
time_t t;
|
||||
@ -1429,27 +1502,49 @@ const int do_norm_secs;
|
||||
yourtm.tm_sec = 0;
|
||||
}
|
||||
/*
|
||||
** Divide the search space in half
|
||||
** (this works whether time_t is signed or unsigned).
|
||||
** Do a binary search (this works whatever time_t's type is).
|
||||
*/
|
||||
bits = TYPE_BIT(time_t) - 1;
|
||||
/*
|
||||
** If time_t is signed, then 0 is just above the median,
|
||||
** assuming two's complement arithmetic.
|
||||
** If time_t is unsigned, then (1 << bits) is just above the median.
|
||||
*/
|
||||
t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits);
|
||||
if (!TYPE_SIGNED(time_t)) {
|
||||
lo = 0;
|
||||
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 {
|
||||
lo = 1;
|
||||
for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i)
|
||||
lo *= 2;
|
||||
hi = -(lo + 1);
|
||||
}
|
||||
for ( ; ; ) {
|
||||
(*funcp)(&t, offset, &mytm);
|
||||
dir = tmcomp(&mytm, &yourtm);
|
||||
t = lo / 2 + hi / 2;
|
||||
if (t < lo)
|
||||
t = lo;
|
||||
else if (t > hi)
|
||||
t = hi;
|
||||
if ((*funcp)(&t, offset, &mytm) == NULL) {
|
||||
/*
|
||||
** Assume that t is too extreme to be represented in
|
||||
** a struct tm; arrange things so that it is less
|
||||
** extreme on the next pass.
|
||||
*/
|
||||
dir = (t > 0) ? 1 : -1;
|
||||
} else dir = tmcomp(&mytm, &yourtm);
|
||||
if (dir != 0) {
|
||||
if (bits-- < 0)
|
||||
if (t == lo) {
|
||||
++t;
|
||||
++lo;
|
||||
} else if (t == hi) {
|
||||
--t;
|
||||
--hi;
|
||||
}
|
||||
if (lo > hi)
|
||||
return WRONG;
|
||||
if (bits < 0)
|
||||
--t; /* may be needed if new t is minimal */
|
||||
else if (dir > 0)
|
||||
t -= ((time_t) 1) << bits;
|
||||
else t += ((time_t) 1) << bits;
|
||||
if (dir > 0)
|
||||
hi = t;
|
||||
else lo = t;
|
||||
continue;
|
||||
}
|
||||
if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
|
||||
@ -1478,7 +1573,8 @@ const int do_norm_secs;
|
||||
continue;
|
||||
newt = t + sp->ttis[j].tt_gmtoff -
|
||||
sp->ttis[i].tt_gmtoff;
|
||||
(*funcp)(&newt, offset, &mytm);
|
||||
if ((*funcp)(&newt, offset, &mytm) == NULL)
|
||||
continue;
|
||||
if (tmcomp(&mytm, &yourtm) != 0)
|
||||
continue;
|
||||
if (mytm.tm_isdst != yourtm.tm_isdst)
|
||||
@ -1497,15 +1593,15 @@ label:
|
||||
if ((newt < t) != (saved_seconds < 0))
|
||||
return WRONG;
|
||||
t = newt;
|
||||
(*funcp)(&t, offset, tmp);
|
||||
*okayp = TRUE;
|
||||
if ((*funcp)(&t, offset, tmp))
|
||||
*okayp = TRUE;
|
||||
return t;
|
||||
}
|
||||
|
||||
static time_t
|
||||
time2(tmp, funcp, offset, okayp)
|
||||
struct tm * const tmp;
|
||||
void (* const funcp) P((const time_t*, long, struct tm*));
|
||||
struct tm * (* const funcp) P((const time_t*, long, struct tm*));
|
||||
const long offset;
|
||||
int * const okayp;
|
||||
{
|
||||
@ -1523,7 +1619,7 @@ int * const okayp;
|
||||
static time_t
|
||||
time1(tmp, funcp, offset)
|
||||
struct tm * const tmp;
|
||||
void (* const funcp) P((const time_t *, long, struct tm *));
|
||||
struct tm * (* const funcp) P((const time_t *, long, struct tm *));
|
||||
const long offset;
|
||||
{
|
||||
register time_t t;
|
||||
|
Loading…
Reference in New Issue
Block a user