aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2020-04-28 21:14:01 +0200
committerCorinna Vinschen <corinna@vinschen.de>2020-04-28 21:14:01 +0200
commit0a41de2725dbf2f325e55016d85d76560845ff8d (patch)
treee16bbe316a3d1c3b719785a6e181e30275179878
parentb8aa5f7a0fe70a9a53fe4019227271a78758ae67 (diff)
downloadnewlib-0a41de2725dbf2f325e55016d85d76560845ff8d.zip
newlib-0a41de2725dbf2f325e55016d85d76560845ff8d.tar.gz
newlib-0a41de2725dbf2f325e55016d85d76560845ff8d.tar.bz2
localtime 1.78
-rw-r--r--winsup/cygwin/localtime.cc132
1 files changed, 68 insertions, 64 deletions
diff --git a/winsup/cygwin/localtime.cc b/winsup/cygwin/localtime.cc
index d3d6296..794c03e 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 <assert.h>
+#endif
+#define time_t_min LONG_MIN
+#define time_t_max LONG_MAX
/* Unlike <ctype.h>'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);