diff options
Diffstat (limited to 'lib/libc/stdtime/localtime.c')
-rw-r--r-- | lib/libc/stdtime/localtime.c | 115 |
1 files changed, 59 insertions, 56 deletions
diff --git a/lib/libc/stdtime/localtime.c b/lib/libc/stdtime/localtime.c index c4cfc88..ecb201b 100644 --- a/lib/libc/stdtime/localtime.c +++ b/lib/libc/stdtime/localtime.c @@ -1,8 +1,11 @@ - +/* +** This file is in the public domain, so clarified as of +** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov). +*/ #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)localtime.c 7.44"; +static char elsieid[] = "@(#)localtime.c 7.57"; #endif /* !defined NOID */ #endif /* !defined lint */ @@ -200,7 +203,7 @@ const char * const codep; register long result; register int i; - result = (codep[0] & 0x80) ? ~0L : 0L; + result = (codep[0] & 0x80) ? ~0L : 0L; for (i = 0; i < 4; ++i) result = (result << 8) | (codep[i] & 0xff); return result; @@ -209,8 +212,8 @@ const char * const codep; static void settzname P((void)) { - register struct state * const sp = lclptr; - register int i; + register struct state * const sp = lclptr; + register int i; tzname[0] = wildabbr; tzname[1] = wildabbr; @@ -425,7 +428,7 @@ register const char * strp; { register char c; - while ((c = *strp) != '\0' && !isdigit(c) && c != ',' && c != '-' && + while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && c != '+') ++strp; return strp; @@ -448,15 +451,15 @@ const int max; register char c; register int num; - if (strp == NULL || !isdigit(*strp)) + if (strp == NULL || !is_digit(c = *strp)) return NULL; num = 0; - while ((c = *strp) != '\0' && isdigit(c)) { + do { num = num * 10 + (c - '0'); if (num > max) return NULL; /* illegal value */ - ++strp; - } + c = *++strp; + } while (is_digit(c)); if (num < min) return NULL; /* illegal value */ *nump = num; @@ -518,14 +521,13 @@ getoffset(strp, offsetp) register const char * strp; long * const offsetp; { - register int neg; + register int neg = 0; if (*strp == '-') { neg = 1; ++strp; - } else if (isdigit(*strp) || *strp++ == '+') - neg = 0; - else return NULL; /* illegal offset */ + } else if (*strp == '+') + ++strp; strp = getsecs(strp, offsetp); if (strp == NULL) return NULL; /* illegal time */ @@ -570,7 +572,7 @@ register struct rule * const rulep; if (*strp++ != '.') return NULL; strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); - } else if (isdigit(*strp)) { + } else if (is_digit(*strp)) { /* ** Day of year. */ @@ -812,7 +814,8 @@ const int lastditch; for (i = 0; i < sp->timecnt; ++i) { j = sp->types[i]; if (!sp->ttis[j].tt_isdst) { - theirstdoffset = -sp->ttis[j].tt_gmtoff; + theirstdoffset = + -sp->ttis[j].tt_gmtoff; break; } } @@ -820,7 +823,8 @@ const int lastditch; for (i = 0; i < sp->timecnt; ++i) { j = sp->types[i]; if (sp->ttis[j].tt_isdst) { - theirdstoffset = -sp->ttis[j].tt_gmtoff; + theirdstoffset = + -sp->ttis[j].tt_gmtoff; break; } } @@ -1284,30 +1288,27 @@ register struct tm * const tmp; tmp->tm_hour = (int) (rem / SECSPERHOUR); rem = rem % SECSPERHOUR; tmp->tm_min = (int) (rem / SECSPERMIN); - tmp->tm_sec = (int) (rem % SECSPERMIN); - if (hit) - /* - ** A positive leap second requires a special - ** representation. This uses "... ??:59:60" et seq. - */ - tmp->tm_sec += hit; + /* + ** 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; - if (days >= 0) - for ( ; ; ) { - yleap = isleap(y); - if (days < (long) year_lengths[yleap]) - break; - ++y; - days = days - (long) year_lengths[yleap]; - } - else do { - --y; - yleap = isleap(y); - days = days + (long) year_lengths[yleap]; - } while (days < 0); +#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) + while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) { + register int 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]; @@ -1336,7 +1337,8 @@ const time_t * const timep; /* ** Adapted from code provided by Robert Elz, who writes: ** The "best" way to do mktime I think is based on an idea of Bob -** Kridle's (so its said...) from a long time ago. (mtxinu!kridle now). +** Kridle's (so its said...) from a long time ago. +** [kridle@xinet.com as of 1996-01-16.] ** It does a binary search of the time_t space. Since time_t's are ** just 32 bits, its a max of 32 iterations (even at 64 bits it ** would still be very reasonable). @@ -1426,10 +1428,12 @@ int * const okayp; while (yourtm.tm_mday <= 0) { if (increment_overflow(&yourtm.tm_year, -1)) return WRONG; - yourtm.tm_mday += year_lengths[isleap(yourtm.tm_year)]; + i = yourtm.tm_year + (1 < yourtm.tm_mon); + yourtm.tm_mday += year_lengths[isleap(i)]; } while (yourtm.tm_mday > DAYSPERLYEAR) { - yourtm.tm_mday -= year_lengths[isleap(yourtm.tm_year)]; + i = yourtm.tm_year + (1 < yourtm.tm_mon); + yourtm.tm_mday -= year_lengths[isleap(i)]; if (increment_overflow(&yourtm.tm_year, 1)) return WRONG; } @@ -1464,17 +1468,16 @@ int * const okayp; yourtm.tm_sec = 0; } /* - ** Calculate the number of magnitude bits in a time_t - ** (this works regardless of whether time_t is - ** signed or unsigned, though lint complains if unsigned). + ** Divide the search space in half + ** (this works whether time_t is signed or unsigned). */ - for (bits = 0, t = 1; t > 0; ++bits, t <<= 1) - continue; + bits = TYPE_BIT(time_t) - 1; /* - ** If time_t is signed, then 0 is the median value, - ** if time_t is unsigned, then 1 << bits is median. + ** 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 = (t < 0) ? 0 : ((time_t) 1 << bits); + t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits); for ( ; ; ) { (*funcp)(&t, offset, &mytm); dir = tmcomp(&mytm, &yourtm); @@ -1482,10 +1485,10 @@ int * const okayp; if (bits-- < 0) return WRONG; if (bits < 0) - --t; + --t; /* may be needed if new t is minimal */ else if (dir > 0) - t -= (time_t) 1 << bits; - else t += (time_t) 1 << bits; + t -= ((time_t) 1) << bits; + else t += ((time_t) 1) << bits; continue; } if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) @@ -1506,10 +1509,10 @@ int * const okayp; if (sp == NULL) return WRONG; #endif /* defined ALL_STATE */ - for (i = 0; i < sp->typecnt; ++i) { + for (i = sp->typecnt - 1; i >= 0; --i) { if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) continue; - for (j = 0; j < sp->typecnt; ++j) { + for (j = sp->typecnt - 1; j >= 0; --j) { if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) continue; newt = t + sp->ttis[j].tt_gmtoff - @@ -1541,7 +1544,7 @@ label: static time_t time1(tmp, funcp, offset) struct tm * const tmp; -void (* const funcp) P((const time_t*, long, struct tm*)); +void (* const funcp) P((const time_t *, long, struct tm *)); const long offset; { register time_t t; @@ -1580,10 +1583,10 @@ const long offset; if (sp == NULL) return WRONG; #endif /* defined ALL_STATE */ - for (samei = 0; samei < sp->typecnt; ++samei) { + for (samei = sp->typecnt - 1; samei >= 0; --samei) { if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) continue; - for (otheri = 0; otheri < sp->typecnt; ++otheri) { + for (otheri = sp->typecnt - 1; otheri >= 0; --otheri) { if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) continue; tmp->tm_sec += sp->ttis[otheri].tt_gmtoff - |