localtime 1.78
This commit is contained in:
		| @@ -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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user