[newlib-cygwin] localtime 1.78

Corinna Vinschen corinna@sourceware.org
Mon May 4 09:20:51 GMT 2020


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=0a41de2725dbf2f325e55016d85d76560845ff8d

commit 0a41de2725dbf2f325e55016d85d76560845ff8d
Author: Corinna Vinschen <corinna@vinschen.de>
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 <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);


More information about the Cygwin-cvs mailing list