From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id 68FF5383E824; Mon, 4 May 2020 09:20:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 68FF5383E824 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Corinna Vinschen To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin] localtime 1.78 X-Act-Checkin: newlib-cygwin X-Git-Author: Corinna Vinschen X-Git-Refname: refs/heads/master X-Git-Oldrev: b8aa5f7a0fe70a9a53fe4019227271a78758ae67 X-Git-Newrev: 0a41de2725dbf2f325e55016d85d76560845ff8d Message-Id: <20200504092051.68FF5383E824@sourceware.org> Date: Mon, 4 May 2020 09:20:51 +0000 (GMT) X-BeenThere: cygwin-cvs@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Cygwin core component git logs List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 04 May 2020 09:20:51 -0000 https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=0a41de2725dbf2f325e55016d85d76560845ff8d commit 0a41de2725dbf2f325e55016d85d76560845ff8d Author: Corinna Vinschen Date: Tue Apr 28 21:14:01 2020 +0200 localtime 1.78 Diff: --- winsup/cygwin/localtime.cc | 132 +++++++++++++++++++++++---------------------- 1 file changed, 68 insertions(+), 64 deletions(-) diff --git a/winsup/cygwin/localtime.cc b/winsup/cygwin/localtime.cc index d3d629618..794c03e2d 100644 --- a/winsup/cygwin/localtime.cc +++ b/winsup/cygwin/localtime.cc @@ -1,4 +1,4 @@ -/* $NetBSD: localtime.c,v 1.77 2013/07/30 15:30:37 joerg Exp $ */ +/* $NetBSD: localtime.c,v 1.78 2013/09/20 19:06:54 christos Exp $ */ /* ** This file is in the public domain, so clarified as of @@ -71,6 +71,11 @@ static char privatehid[] = "@(#)private.h 7.48"; #include "limits.h" /* for CHAR_BIT */ #include "stdlib.h" #include "unistd.h" /* for F_OK and R_OK */ +#if 0 +#include +#endif +#define time_t_min LONG_MIN +#define time_t_max LONG_MAX /* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ #define is_digit(c) ((unsigned)(c) - '0' <= 9) @@ -85,7 +90,7 @@ static char privatehid[] = "@(#)private.h 7.48"; #if 0 static char elsieid[] = "@(#)localtime.cc 8.17"; #else -__RCSID("$NetBSD: localtime.c,v 1.77 2013/07/30 15:30:37 joerg Exp $"); +__RCSID("$NetBSD: localtime.c,v 1.78 2013/09/20 19:06:54 christos Exp $"); #endif /* @@ -406,11 +411,11 @@ static const char gmt[] = "GMT"; #endif /* !defined TZDEFDST */ 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_abbrind; /* abbreviation list index */ 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 */ @@ -642,9 +647,8 @@ settzname (void) static int differ_by_repeat(const time_t t1, const time_t t0) { - if (TYPE_INTEGRAL(time_t) && - TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS) - return 0; + if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS) + return 0; return (int_fast64_t)t1 - (int_fast64_t)t0 == SECSPERREPEAT; } @@ -864,11 +868,9 @@ tzload(timezone_t sp, const char *name, const int doextend) for (i = 0; i < nread; ++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) -/* CONSTCOND */ - && TYPE_INTEGRAL(time_t)) + if (stored >= (int) sizeof(time_t)) break; } if (doextend && nread > 2 && @@ -1191,14 +1193,14 @@ getrule(const char *strp, struct rule *const rulep) ** Time specified. */ ++strp; - strp = getsecs(strp, &rulep->r_time); + strp = getoffset(strp, &rulep->r_time); } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ return strp; } /* ** 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. */ @@ -1281,10 +1283,10 @@ transtime(const time_t janfirst, const int year, const struct rule *const rulep, } /* - ** "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 ** time on that day, add the transition time and the current offset - ** from UTC. + ** from UT. */ return (time_t)(value + rulep->r_time + offset); } @@ -1361,8 +1363,9 @@ tzparse(timezone_t sp, const char *name, const int lastditch) if (*name == ',' || *name == ';') { struct rule start; struct rule end; - int year; - time_t janfirst; + int year; + int yearlim; + time_t janfirst; time_t starttime; time_t endtime; @@ -1390,33 +1393,39 @@ tzparse(timezone_t sp, const char *name, const int lastditch) typep = sp->types; janfirst = 0; sp->timecnt = 0; - for (year = EPOCH_YEAR; - sp->timecnt + 2 <= TZ_MAX_TIMES; - ++year) { - time_t newfirst; + yearlim = EPOCH_YEAR + YEARSPERREPEAT; + for (year = EPOCH_YEAR; year < yearlim; year++) { + int_fast32_t yearsecs; starttime = transtime(janfirst, year, &start, stdoffset); endtime = transtime(janfirst, year, &end, dstoffset); - 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 */ + yearsecs = (year_lengths[isleap(year)] + * SECSPERDAY); + if (starttime > endtime + || (starttime < endtime + && (endtime - starttime + < (yearsecs + + (stdoffset - dstoffset))))) { + if (&sp->ats[TZ_MAX_TIMES - 2] < atp) + break; + 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; - newfirst = janfirst; - newfirst += (time_t) - (year_lengths[isleap(year)] * SECSPERDAY); - if (newfirst <= janfirst) + if (time_t_max - janfirst < yearsecs) break; - janfirst = newfirst; + janfirst += yearsecs; } /* ** Get zone offsets into tzinfo (for newlib). . . @@ -1428,6 +1437,10 @@ tzparse(timezone_t sp, const char *name, const int lastditch) __gettzinfo ()->__tzrule[1].offset = -sp->ttis[0].tt_gmtoff; } + //_DIAGASSERT(__type_fit(int, atp - sp->ats)); + sp->timecnt = (int)(atp - sp->ats); + if (!sp->timecnt) + sp->typecnt = 1; /* Perpetual DST. */ } else { int_fast32_t theirstdoffset; int_fast32_t theirdstoffset; @@ -1759,22 +1772,14 @@ localsub(const timezone_t sp, const time_t * const timep, const int_fast32_t off (sp->goahead && t > sp->ats[sp->timecnt - 1])) { time_t newt = t; time_t seconds; - time_t tcycles; - int_fast64_t icycles; + time_t years; if (t < sp->ats[0]) seconds = sp->ats[0] - t; else seconds = t - sp->ats[sp->timecnt - 1]; --seconds; - tcycles = (time_t) - (seconds / YEARSPERREPEAT / AVGSECSPERYEAR); - ++tcycles; - icycles = tcycles; - if (tcycles - icycles >= 1 || icycles - tcycles >= 1) - return NULL; - seconds = (time_t) icycles; - seconds *= YEARSPERREPEAT; - seconds *= AVGSECSPERYEAR; + years = (time_t)((seconds / SECSPERREPEAT + 1) * YEARSPERREPEAT); + seconds = (time_t)(years * AVGSECSPERYEAR); if (t < sp->ats[0]) newt += seconds; else newt -= seconds; @@ -1787,8 +1792,8 @@ localsub(const timezone_t sp, const time_t * const timep, const int_fast32_t off newy = tmp->tm_year; if (t < sp->ats[0]) - newy -= (time_t)icycles * YEARSPERREPEAT; - else newy += (time_t)icycles * YEARSPERREPEAT; + newy -= years; + else newy += years; tmp->tm_year = (int)newy; if (tmp->tm_year != newy) return NULL; @@ -1873,7 +1878,7 @@ gmtsub(const timezone_t sp, const time_t *const timep, #ifdef TM_ZONE /* ** 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. */ if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS) @@ -1997,9 +2002,10 @@ timesub(const timezone_t sp, const time_t *const timep, int leapdays; tdelta = tdays / DAYSPERLYEAR; - idelta = (int) tdelta; - if (tdelta - idelta >= 1 || idelta - tdelta >= 1) + if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta) + && tdelta <= INT_MAX)) return NULL; + idelta = tdelta; if (idelta == 0) idelta = (tdays < 0) ? -1 : 1; newy = y; @@ -2013,9 +2019,8 @@ timesub(const timezone_t sp, const time_t *const timep, } { int_fast32_t seconds; - const time_t half_second = (time_t)0.5; - seconds = (int_fast32_t)(tdays * SECSPERDAY + half_second); + seconds = (int_fast32_t)(tdays * SECSPERDAY); tdays = (time_t)(seconds / SECSPERDAY); rem += (int_fast64_t)(seconds - tdays * SECSPERDAY); } @@ -2179,8 +2184,9 @@ tmcomp(const struct tm *const atmp, const struct tm *const btmp) { int result; - if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && - (result = (atmp->tm_mon - btmp->tm_mon)) == 0 && + if (atmp->tm_year != btmp->tm_year) + 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_hour - btmp->tm_hour)) == 0 && (result = (atmp->tm_min - btmp->tm_min)) == 0) @@ -2283,7 +2289,6 @@ again: if (!TYPE_SIGNED(time_t)) { lo = 0; hi = lo - 1; - /* LINTED const not */ } else { lo = 1; for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i) @@ -2309,14 +2314,14 @@ again: } else dir = tmcomp(&mytm, &yourtm); if (dir != 0) { if (t == lo) { - ++t; - if (t <= lo) + if (t == time_t_max) goto overflow; + ++t; ++lo; } else if (t == hi) { - --t; - if (t >= hi) + if (t == time_t_min) goto overflow; + --t; --hi; } #ifdef NO_ERROR_IN_DST_GAP @@ -2541,8 +2546,7 @@ timeoff(struct tm *const tmp, long offset) ** previous versions of the CMUCS runtime library. */ -extern "C" -int_fast32_t +extern "C" long gtime(struct tm *const tmp) { const time_t t = mktime(tmp);