diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/libc/stdtime/asctime.c | 61 | ||||
| -rw-r--r-- | lib/libc/stdtime/difftime.c | 77 | ||||
| -rw-r--r-- | lib/libc/stdtime/localtime.c | 1617 | ||||
| -rw-r--r-- | lib/libc/stdtime/private.h | 252 | ||||
| -rw-r--r-- | lib/libc/stdtime/strftime.c | 604 | ||||
| -rw-r--r-- | lib/libc/stdtime/time2posix.3 | 119 | 
6 files changed, 0 insertions, 2730 deletions
| diff --git a/lib/libc/stdtime/asctime.c b/lib/libc/stdtime/asctime.c deleted file mode 100644 index a1834b65a273..000000000000 --- a/lib/libc/stdtime/asctime.c +++ /dev/null @@ -1,61 +0,0 @@ -/* -** 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[] = "@(#)asctime.c	7.7"; -#endif /* !defined NOID */ -#endif /* !defined lint */ - -/*LINTLIBRARY*/ - -#include "private.h" -#include "tzfile.h" - -/* -** A la X3J11, with core dump avoidance. -*/ - -char * -asctime(timeptr) -register const struct tm *	timeptr; -{ -	static const char	wday_name[][3] = { -		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -	}; -	static const char	mon_name[][3] = { -		"Jan", "Feb", "Mar", "Apr", "May", "Jun", -		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -	}; -	/* -	** Big enough for something such as -	** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n -	** (two three-character abbreviations, five strings denoting integers, -	** three explicit spaces, two explicit colons, a newline, -	** and a trailing ASCII nul). -	*/ -	static char		result[3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) + -					3 + 2 + 1 + 1]; -	register const char *	wn; -	register const char *	mn; - -	if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK) -		wn = "???"; -	else	wn = wday_name[timeptr->tm_wday]; -	if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR) -		mn = "???"; -	else	mn = mon_name[timeptr->tm_mon]; -	/* -	** The X3J11-suggested format is -	**	"%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n" -	** Since the .2 in 02.2d is ignored, we drop it. -	*/ -	(void) sprintf(result, "%.3s %.3s%3d %02d:%02d:%02d %d\n", -		wn, mn, -		timeptr->tm_mday, timeptr->tm_hour, -		timeptr->tm_min, timeptr->tm_sec, -		TM_YEAR_BASE + timeptr->tm_year); -	return result; -} diff --git a/lib/libc/stdtime/difftime.c b/lib/libc/stdtime/difftime.c deleted file mode 100644 index f178524f5152..000000000000 --- a/lib/libc/stdtime/difftime.c +++ /dev/null @@ -1,77 +0,0 @@ -/* -** 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[] = "@(#)difftime.c	7.7"; -#endif /* !defined NOID */ -#endif /* !defined lint */ - -/*LINTLIBRARY*/ - -#include "private.h" - -/* -** Algorithm courtesy Paul Eggert (eggert@twinsun.com). -*/ - -#ifdef HAVE_LONG_DOUBLE -#define long_double	long double -#endif /* defined HAVE_LONG_DOUBLE */ -#ifndef HAVE_LONG_DOUBLE -#define long_double	double -#endif /* !defined HAVE_LONG_DOUBLE */ - -double -difftime(time1, time0) -const time_t	time1; -const time_t	time0; -{ -	time_t	delta; -	time_t	hibit; - -	if (sizeof(time_t) < sizeof(double)) -		return (double) time1 - (double) time0; -	if (sizeof(time_t) < sizeof(long_double)) -		return (long_double) time1 - (long_double) time0; -	if (time1 < time0) -		return -difftime(time0, time1); -	/* -	** As much as possible, avoid loss of precision -	** by computing the difference before converting to double. -	*/ -	delta = time1 - time0; -	if (delta >= 0) -		return delta; -	/* -	** Repair delta overflow. -	*/ -	hibit = (~ (time_t) 0) << (TYPE_BIT(time_t) - 1); -	/* -	** The following expression rounds twice, which means -	** the result may not be the closest to the true answer. -	** For example, suppose time_t is 64-bit signed int, -	** long_double is IEEE 754 double with default rounding, -	** time1 = 9223372036854775807 and time0 = -1536. -	** Then the true difference is 9223372036854777343, -	** which rounds to 9223372036854777856 -	** with a total error of 513. -	** But delta overflows to -9223372036854774273, -	** which rounds to -9223372036854774784, and correcting -	** this by subtracting 2 * (long_double) hibit -	** (i.e. by adding 2**64 = 18446744073709551616) -	** yields 9223372036854776832, which -	** rounds to 9223372036854775808 -	** with a total error of 1535 instead. -	** This problem occurs only with very large differences. -	** It's too painful to fix this portably. -	** We are not alone in this problem; -	** some C compilers round twice when converting -	** large unsigned types to small floating types, -	** so if time_t is unsigned the "return delta" above -	** has the same double-rounding problem with those compilers. -	*/ -	return delta - 2 * (long_double) hibit; -} diff --git a/lib/libc/stdtime/localtime.c b/lib/libc/stdtime/localtime.c deleted file mode 100644 index 541f49ffdfe9..000000000000 --- a/lib/libc/stdtime/localtime.c +++ /dev/null @@ -1,1617 +0,0 @@ -/* -** 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.57"; -#endif /* !defined NOID */ -#endif /* !defined lint */ - -/* -** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu). -** POSIX-style TZ environment variable handling from Guy Harris -** (guy@auspex.com). -*/ - -/*LINTLIBRARY*/ - -#include "private.h" -#include "tzfile.h" -#include "fcntl.h" - -/* -** SunOS 4.1.1 headers lack O_BINARY. -*/ - -#ifdef O_BINARY -#define OPEN_MODE	(O_RDONLY | O_BINARY) -#endif /* defined O_BINARY */ -#ifndef O_BINARY -#define OPEN_MODE	O_RDONLY -#endif /* !defined O_BINARY */ - -#ifndef WILDABBR -/* -** Someone might make incorrect use of a time zone abbreviation: -**	1.	They might reference tzname[0] before calling tzset (explicitly -**		or implicitly). -**	2.	They might reference tzname[1] before calling tzset (explicitly -**		or implicitly). -**	3.	They might reference tzname[1] after setting to a time zone -**		in which Daylight Saving Time is never observed. -**	4.	They might reference tzname[0] after setting to a time zone -**		in which Standard Time is never observed. -**	5.	They might reference tm.TM_ZONE after calling offtime. -** What's best to do in the above cases is open to debate; -** for now, we just set things up so that in any of the five cases -** WILDABBR is used.  Another possibility:  initialize tzname[0] to the -** string "tzname[0] used before set", and similarly for the other cases. -** And another:  initialize tzname[0] to "ERA", with an explanation in the -** manual page of what this "time zone abbreviation" means (doing this so -** that tzname[0] has the "normal" length of three characters). -*/ -#define WILDABBR	"   " -#endif /* !defined WILDABBR */ - -static char		wildabbr[] = "WILDABBR"; - -static const char	gmt[] = "GMT"; - -struct ttinfo {				/* time type information */ -	long		tt_gmtoff;	/* GMT 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 GMT */ -}; - -struct lsinfo {				/* leap second information */ -	time_t		ls_trans;	/* transition time */ -	long		ls_corr;	/* correction to apply */ -}; - -#define BIGGEST(a, b)	(((a) > (b)) ? (a) : (b)) - -#ifdef TZNAME_MAX -#define MY_TZNAME_MAX	TZNAME_MAX -#endif /* defined TZNAME_MAX */ -#ifndef TZNAME_MAX -#define MY_TZNAME_MAX	255 -#endif /* !defined TZNAME_MAX */ - -struct state { -	int		leapcnt; -	int		timecnt; -	int		typecnt; -	int		charcnt; -	time_t		ats[TZ_MAX_TIMES]; -	unsigned char	types[TZ_MAX_TIMES]; -	struct ttinfo	ttis[TZ_MAX_TYPES]; -	char		chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), -				(2 * (MY_TZNAME_MAX + 1)))]; -	struct lsinfo	lsis[TZ_MAX_LEAPS]; -}; - -struct rule { -	int		r_type;		/* type of rule--see below */ -	int		r_day;		/* day number of rule */ -	int		r_week;		/* week number of rule */ -	int		r_mon;		/* month number of rule */ -	long		r_time;		/* transition time of rule */ -}; - -#define JULIAN_DAY		0	/* Jn - Julian day */ -#define DAY_OF_YEAR		1	/* n - day of year */ -#define MONTH_NTH_DAY_OF_WEEK	2	/* Mm.n.d - month, week, day of week */ - -/* -** Prototypes for static functions. -*/ - -static long		detzcode P((const char * codep)); -static const char *	getzname P((const char * strp)); -static const char *	getnum P((const char * strp, int * nump, int min, -				int max)); -static const char *	getsecs P((const char * strp, long * secsp)); -static const char *	getoffset P((const char * strp, long * offsetp)); -static const char *	getrule P((const char * strp, struct rule * rulep)); -static void		gmtload P((struct state * sp)); -static void		gmtsub P((const time_t * timep, long offset, -				struct tm * tmp)); -static void		localsub P((const time_t * timep, long offset, -				struct tm * tmp)); -static int		increment_overflow P((int * number, int delta)); -static int		normalize_overflow P((int * tensptr, int * unitsptr, -				int base)); -static void		settzname P((void)); -static time_t		time1 P((struct tm * tmp, -				void(*funcp) P((const time_t *, -				long, struct tm *)), -				long offset)); -static time_t		time2 P((struct tm *tmp, -				void(*funcp) P((const time_t *, -				long, struct tm*)), -				long offset, int * okayp)); -static void		timesub P((const time_t * timep, long offset, -				const struct state * sp, struct tm * tmp)); -static int		tmcomp P((const struct tm * atmp, -				const struct tm * btmp)); -static time_t		transtime P((time_t janfirst, int year, -				const struct rule * rulep, long offset)); -static int		tzload P((const char * name, struct state * sp)); -static int		tzparse P((const char * name, struct state * sp, -				int lastditch)); - -#ifdef ALL_STATE -static struct state *	lclptr; -static struct state *	gmtptr; -#endif /* defined ALL_STATE */ - -#ifndef ALL_STATE -static struct state	lclmem; -static struct state	gmtmem; -#define lclptr		(&lclmem) -#define gmtptr		(&gmtmem) -#endif /* State Farm */ - -#ifndef TZ_STRLEN_MAX -#define TZ_STRLEN_MAX 255 -#endif /* !defined TZ_STRLEN_MAX */ - -static char		lcl_TZname[TZ_STRLEN_MAX + 1]; -static int		lcl_is_set; -static int		gmt_is_set; - -char *			tzname[2] = { -	wildabbr, -	wildabbr -}; - -/* -** Section 4.12.3 of X3.159-1989 requires that -**	Except for the strftime function, these functions [asctime, -**	ctime, gmtime, localtime] return values in one of two static -**	objects: a broken-down time structure and an array of char. -** Thanks to Paul Eggert (eggert@twinsun.com) for noting this. -*/ - -static struct tm	tm; - -#ifdef USG_COMPAT -time_t			timezone = 0; -int			daylight = 0; -#endif /* defined USG_COMPAT */ - -#ifdef ALTZONE -time_t			altzone = 0; -#endif /* defined ALTZONE */ - -static long -detzcode(codep) -const char * const	codep; -{ -	register long	result; -	register int	i; - -	result = (codep[0] & 0x80) ? ~0L : 0L; -	for (i = 0; i < 4; ++i) -		result = (result << 8) | (codep[i] & 0xff); -	return result; -} - -static void -settzname P((void)) -{ -	register struct state * const	sp = lclptr; -	register int			i; - -	tzname[0] = wildabbr; -	tzname[1] = wildabbr; -#ifdef USG_COMPAT -	daylight = 0; -	timezone = 0; -#endif /* defined USG_COMPAT */ -#ifdef ALTZONE -	altzone = 0; -#endif /* defined ALTZONE */ -#ifdef ALL_STATE -	if (sp == NULL) { -		tzname[0] = tzname[1] = gmt; -		return; -	} -#endif /* defined ALL_STATE */ -	for (i = 0; i < sp->typecnt; ++i) { -		register const struct ttinfo * const	ttisp = &sp->ttis[i]; - -		tzname[ttisp->tt_isdst] = -			&sp->chars[ttisp->tt_abbrind]; -#ifdef USG_COMPAT -		if (ttisp->tt_isdst) -			daylight = 1; -		if (i == 0 || !ttisp->tt_isdst) -			timezone = -(ttisp->tt_gmtoff); -#endif /* defined USG_COMPAT */ -#ifdef ALTZONE -		if (i == 0 || ttisp->tt_isdst) -			altzone = -(ttisp->tt_gmtoff); -#endif /* defined ALTZONE */ -	} -	/* -	** And to get the latest zone names into tzname. . . -	*/ -	for (i = 0; i < sp->timecnt; ++i) { -		register const struct ttinfo * const	ttisp = -							&sp->ttis[ -								sp->types[i]]; - -		tzname[ttisp->tt_isdst] = -			&sp->chars[ttisp->tt_abbrind]; -	} -} - -static int -tzload(name, sp) -register const char *		name; -register struct state * const	sp; -{ -	register const char *	p; -	register int		i; -	register int		fid; - -	if (name == NULL && (name = TZDEFAULT) == NULL) -		return -1; -	{ -		register int	doaccess; -		/* -		** Section 4.9.1 of the C standard says that -		** "FILENAME_MAX expands to an integral constant expression -		** that is the sie needed for an array of char large enough -		** to hold the longest file name string that the implementation -		** guarantees can be opened." -		*/ -		char		fullname[FILENAME_MAX + 1]; - -		if (name[0] == ':') -			++name; -		doaccess = name[0] == '/'; -		if (!doaccess) { -			if ((p = TZDIR) == NULL) -				return -1; -			if ((strlen(p) + strlen(name) + 1) >= sizeof fullname) -				return -1; -			(void) strcpy(fullname, p); -			(void) strcat(fullname, "/"); -			(void) strcat(fullname, name); -			/* -			** Set doaccess if '.' (as in "../") shows up in name. -			*/ -			if (strchr(name, '.') != NULL) -				doaccess = TRUE; -			name = fullname; -		} -		if (doaccess && access(name, R_OK) != 0) -			return -1; -		if ((fid = open(name, OPEN_MODE)) == -1) -			return -1; -	} -	{ -		struct tzhead *	tzhp; -		char		buf[sizeof *sp + sizeof *tzhp]; -		int		ttisstdcnt; -		int		ttisgmtcnt; - -		i = read(fid, buf, sizeof buf); -		if (close(fid) != 0) -			return -1; -		p = buf; -		p += sizeof tzhp->tzh_reserved; -		ttisstdcnt = (int) detzcode(p); -		p += 4; -		ttisgmtcnt = (int) detzcode(p); -		p += 4; -		sp->leapcnt = (int) detzcode(p); -		p += 4; -		sp->timecnt = (int) detzcode(p); -		p += 4; -		sp->typecnt = (int) detzcode(p); -		p += 4; -		sp->charcnt = (int) detzcode(p); -		p += 4; -		if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS || -			sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES || -			sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES || -			sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS || -			(ttisstdcnt != sp->typecnt && ttisstdcnt != 0) || -			(ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0)) -				return -1; -		if (i - (p - buf) < sp->timecnt * 4 +	/* ats */ -			sp->timecnt +			/* types */ -			sp->typecnt * (4 + 2) +		/* ttinfos */ -			sp->charcnt +			/* chars */ -			sp->leapcnt * (4 + 4) +		/* lsinfos */ -			ttisstdcnt +			/* ttisstds */ -			ttisgmtcnt)			/* ttisgmts */ -				return -1; -		for (i = 0; i < sp->timecnt; ++i) { -			sp->ats[i] = detzcode(p); -			p += 4; -		} -		for (i = 0; i < sp->timecnt; ++i) { -			sp->types[i] = (unsigned char) *p++; -			if (sp->types[i] >= sp->typecnt) -				return -1; -		} -		for (i = 0; i < sp->typecnt; ++i) { -			register struct ttinfo *	ttisp; - -			ttisp = &sp->ttis[i]; -			ttisp->tt_gmtoff = detzcode(p); -			p += 4; -			ttisp->tt_isdst = (unsigned char) *p++; -			if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1) -				return -1; -			ttisp->tt_abbrind = (unsigned char) *p++; -			if (ttisp->tt_abbrind < 0 || -				ttisp->tt_abbrind > sp->charcnt) -					return -1; -		} -		for (i = 0; i < sp->charcnt; ++i) -			sp->chars[i] = *p++; -		sp->chars[i] = '\0';	/* ensure '\0' at end */ -		for (i = 0; i < sp->leapcnt; ++i) { -			register struct lsinfo *	lsisp; - -			lsisp = &sp->lsis[i]; -			lsisp->ls_trans = detzcode(p); -			p += 4; -			lsisp->ls_corr = detzcode(p); -			p += 4; -		} -		for (i = 0; i < sp->typecnt; ++i) { -			register struct ttinfo *	ttisp; - -			ttisp = &sp->ttis[i]; -			if (ttisstdcnt == 0) -				ttisp->tt_ttisstd = FALSE; -			else { -				ttisp->tt_ttisstd = *p++; -				if (ttisp->tt_ttisstd != TRUE && -					ttisp->tt_ttisstd != FALSE) -						return -1; -			} -		} -		for (i = 0; i < sp->typecnt; ++i) { -			register struct ttinfo *	ttisp; - -			ttisp = &sp->ttis[i]; -			if (ttisgmtcnt == 0) -				ttisp->tt_ttisgmt = FALSE; -			else { -				ttisp->tt_ttisgmt = *p++; -				if (ttisp->tt_ttisgmt != TRUE && -					ttisp->tt_ttisgmt != FALSE) -						return -1; -			} -		} -	} -	return 0; -} - -static const int	mon_lengths[2][MONSPERYEAR] = { -	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, -	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } -}; - -static const int	year_lengths[2] = { -	DAYSPERNYEAR, DAYSPERLYEAR -}; - -/* -** Given a pointer into a time zone string, scan until a character that is not -** a valid character in a zone name is found.  Return a pointer to that -** character. -*/ - -static const char * -getzname(strp) -register const char *	strp; -{ -	register char	c; - -	while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && -		c != '+') -			++strp; -	return strp; -} - -/* -** Given a pointer into a time zone string, extract a number from that string. -** Check that the number is within a specified range; if it is not, return -** NULL. -** Otherwise, return a pointer to the first character not part of the number. -*/ - -static const char * -getnum(strp, nump, min, max) -register const char *	strp; -int * const		nump; -const int		min; -const int		max; -{ -	register char	c; -	register int	num; - -	if (strp == NULL || !is_digit(c = *strp)) -		return NULL; -	num = 0; -	do { -		num = num * 10 + (c - '0'); -		if (num > max) -			return NULL;	/* illegal value */ -		c = *++strp; -	} while (is_digit(c)); -	if (num < min) -		return NULL;		/* illegal value */ -	*nump = num; -	return strp; -} - -/* -** Given a pointer into a time zone string, extract a number of seconds, -** in hh[:mm[:ss]] form, from the string. -** If any error occurs, return NULL. -** Otherwise, return a pointer to the first character not part of the number -** of seconds. -*/ - -static const char * -getsecs(strp, secsp) -register const char *	strp; -long * const		secsp; -{ -	int	num; - -	/* -	** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like -	** "M10.4.6/26", which does not conform to Posix, -	** but which specifies the equivalent of -	** ``02:00 on the first Sunday on or after 23 Oct''. -	*/ -	strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); -	if (strp == NULL) -		return NULL; -	*secsp = num * (long) SECSPERHOUR; -	if (*strp == ':') { -		++strp; -		strp = getnum(strp, &num, 0, MINSPERHOUR - 1); -		if (strp == NULL) -			return NULL; -		*secsp += num * SECSPERMIN; -		if (*strp == ':') { -			++strp; -			/* `SECSPERMIN' allows for leap seconds.  */ -			strp = getnum(strp, &num, 0, SECSPERMIN); -			if (strp == NULL) -				return NULL; -			*secsp += num; -		} -	} -	return strp; -} - -/* -** Given a pointer into a time zone string, extract an offset, in -** [+-]hh[:mm[:ss]] form, from the string. -** If any error occurs, return NULL. -** Otherwise, return a pointer to the first character not part of the time. -*/ - -static const char * -getoffset(strp, offsetp) -register const char *	strp; -long * const		offsetp; -{ -	register int	neg = 0; - -	if (*strp == '-') { -		neg = 1; -		++strp; -	} else if (*strp == '+') -		++strp; -	strp = getsecs(strp, offsetp); -	if (strp == NULL) -		return NULL;		/* illegal time */ -	if (neg) -		*offsetp = -*offsetp; -	return strp; -} - -/* -** Given a pointer into a time zone string, extract a rule in the form -** date[/time].  See POSIX section 8 for the format of "date" and "time". -** If a valid rule is not found, return NULL. -** Otherwise, return a pointer to the first character not part of the rule. -*/ - -static const char * -getrule(strp, rulep) -const char *			strp; -register struct rule * const	rulep; -{ -	if (*strp == 'J') { -		/* -		** Julian day. -		*/ -		rulep->r_type = JULIAN_DAY; -		++strp; -		strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); -	} else if (*strp == 'M') { -		/* -		** Month, week, day. -		*/ -		rulep->r_type = MONTH_NTH_DAY_OF_WEEK; -		++strp; -		strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); -		if (strp == NULL) -			return NULL; -		if (*strp++ != '.') -			return NULL; -		strp = getnum(strp, &rulep->r_week, 1, 5); -		if (strp == NULL) -			return NULL; -		if (*strp++ != '.') -			return NULL; -		strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); -	} else if (is_digit(*strp)) { -		/* -		** Day of year. -		*/ -		rulep->r_type = DAY_OF_YEAR; -		strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); -	} else	return NULL;		/* invalid format */ -	if (strp == NULL) -		return NULL; -	if (*strp == '/') { -		/* -		** Time specified. -		*/ -		++strp; -		strp = getsecs(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 GMT, in a year, the -** year, a rule, and the offset from GMT at the time that rule takes effect, -** calculate the Epoch-relative time that rule takes effect. -*/ - -static time_t -transtime(janfirst, year, rulep, offset) -const time_t				janfirst; -const int				year; -register const struct rule * const	rulep; -const long				offset; -{ -	register int	leapyear; -	register time_t	value; -	register int	i; -	int		d, m1, yy0, yy1, yy2, dow; - -	INITIALIZE(value); -	leapyear = isleap(year); -	switch (rulep->r_type) { - -	case JULIAN_DAY: -		/* -		** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap -		** years. -		** In non-leap years, or if the day number is 59 or less, just -		** add SECSPERDAY times the day number-1 to the time of -		** January 1, midnight, to get the day. -		*/ -		value = janfirst + (rulep->r_day - 1) * SECSPERDAY; -		if (leapyear && rulep->r_day >= 60) -			value += SECSPERDAY; -		break; - -	case DAY_OF_YEAR: -		/* -		** n - day of year. -		** Just add SECSPERDAY times the day number to the time of -		** January 1, midnight, to get the day. -		*/ -		value = janfirst + rulep->r_day * SECSPERDAY; -		break; - -	case MONTH_NTH_DAY_OF_WEEK: -		/* -		** Mm.n.d - nth "dth day" of month m. -		*/ -		value = janfirst; -		for (i = 0; i < rulep->r_mon - 1; ++i) -			value += mon_lengths[leapyear][i] * SECSPERDAY; - -		/* -		** Use Zeller's Congruence to get day-of-week of first day of -		** month. -		*/ -		m1 = (rulep->r_mon + 9) % 12 + 1; -		yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; -		yy1 = yy0 / 100; -		yy2 = yy0 % 100; -		dow = ((26 * m1 - 2) / 10 + -			1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; -		if (dow < 0) -			dow += DAYSPERWEEK; - -		/* -		** "dow" is the day-of-week of the first day of the month.  Get -		** the day-of-month (zero-origin) of the first "dow" day of the -		** month. -		*/ -		d = rulep->r_day - dow; -		if (d < 0) -			d += DAYSPERWEEK; -		for (i = 1; i < rulep->r_week; ++i) { -			if (d + DAYSPERWEEK >= -				mon_lengths[leapyear][rulep->r_mon - 1]) -					break; -			d += DAYSPERWEEK; -		} - -		/* -		** "d" is the day-of-month (zero-origin) of the day we want. -		*/ -		value += d * SECSPERDAY; -		break; -	} - -	/* -	** "value" is the Epoch-relative time of 00:00:00 GMT 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 GMT. -	*/ -	return value + rulep->r_time + offset; -} - -/* -** Given a POSIX section 8-style TZ string, fill in the rule tables as -** appropriate. -*/ - -static int -tzparse(name, sp, lastditch) -const char *			name; -register struct state * const	sp; -const int			lastditch; -{ -	const char *			stdname; -	const char *			dstname; -	size_t				stdlen; -	size_t				dstlen; -	long				stdoffset; -	long				dstoffset; -	register time_t *		atp; -	register unsigned char *	typep; -	register char *			cp; -	register int			load_result; - -	INITIALIZE(dstname); -	stdname = name; -	if (lastditch) { -		stdlen = strlen(name);	/* length of standard zone name */ -		name += stdlen; -		if (stdlen >= sizeof sp->chars) -			stdlen = (sizeof sp->chars) - 1; -	} else { -		name = getzname(name); -		stdlen = name - stdname; -		if (stdlen < 3) -			return -1; -	} -	if (*name == '\0') -		return -1;	/* was "stdoffset = 0;" */ -	else { -		name = getoffset(name, &stdoffset); -		if (name == NULL) -			return -1; -	} -	load_result = tzload(TZDEFRULES, sp); -	if (load_result != 0) -		sp->leapcnt = 0;		/* so, we're off a little */ -	if (*name != '\0') { -		dstname = name; -		name = getzname(name); -		dstlen = name - dstname;	/* length of DST zone name */ -		if (dstlen < 3) -			return -1; -		if (*name != '\0' && *name != ',' && *name != ';') { -			name = getoffset(name, &dstoffset); -			if (name == NULL) -				return -1; -		} else	dstoffset = stdoffset - SECSPERHOUR; -		if (*name == ',' || *name == ';') { -			struct rule	start; -			struct rule	end; -			register int	year; -			register time_t	janfirst; -			time_t		starttime; -			time_t		endtime; - -			++name; -			if ((name = getrule(name, &start)) == NULL) -				return -1; -			if (*name++ != ',') -				return -1; -			if ((name = getrule(name, &end)) == NULL) -				return -1; -			if (*name != '\0') -				return -1; -			sp->typecnt = 2;	/* standard time and DST */ -			/* -			** Two transitions per year, from EPOCH_YEAR to 2037. -			*/ -			sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1); -			if (sp->timecnt > TZ_MAX_TIMES) -				return -1; -			sp->ttis[0].tt_gmtoff = -dstoffset; -			sp->ttis[0].tt_isdst = 1; -			sp->ttis[0].tt_abbrind = stdlen + 1; -			sp->ttis[1].tt_gmtoff = -stdoffset; -			sp->ttis[1].tt_isdst = 0; -			sp->ttis[1].tt_abbrind = 0; -			atp = sp->ats; -			typep = sp->types; -			janfirst = 0; -			for (year = EPOCH_YEAR; year <= 2037; ++year) { -				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 */ -				} -				janfirst += year_lengths[isleap(year)] * -					SECSPERDAY; -			} -		} else { -			register long	theirstdoffset; -			register long	theirdstoffset; -			register long	theiroffset; -			register int	isdst; -			register int	i; -			register int	j; - -			if (*name != '\0') -				return -1; -			if (load_result != 0) -				return -1; -			/* -			** Initial values of theirstdoffset and theirdstoffset. -			*/ -			theirstdoffset = 0; -			for (i = 0; i < sp->timecnt; ++i) { -				j = sp->types[i]; -				if (!sp->ttis[j].tt_isdst) { -					theirstdoffset = -						-sp->ttis[j].tt_gmtoff; -					break; -				} -			} -			theirdstoffset = 0; -			for (i = 0; i < sp->timecnt; ++i) { -				j = sp->types[i]; -				if (sp->ttis[j].tt_isdst) { -					theirdstoffset = -						-sp->ttis[j].tt_gmtoff; -					break; -				} -			} -			/* -			** Initially we're assumed to be in standard time. -			*/ -			isdst = FALSE; -			theiroffset = theirstdoffset; -			/* -			** Now juggle transition times and types -			** tracking offsets as you do. -			*/ -			for (i = 0; i < sp->timecnt; ++i) { -				j = sp->types[i]; -				sp->types[i] = sp->ttis[j].tt_isdst; -				if (sp->ttis[j].tt_ttisgmt) { -					/* No adjustment to transition time */ -				} else { -					/* -					** If summer time is in effect, and the -					** transition time was not specified as -					** standard time, add the summer time -					** offset to the transition time; -					** otherwise, add the standard time -					** offset to the transition time. -					*/ -					/* -					** Transitions from DST to DDST -					** will effectively disappear since -					** POSIX provides for only one DST -					** offset. -					*/ -					if (isdst && !sp->ttis[j].tt_ttisstd) { -						sp->ats[i] += dstoffset - -							theirdstoffset; -					} else { -						sp->ats[i] += stdoffset - -							theirstdoffset; -					} -				} -				theiroffset = -sp->ttis[j].tt_gmtoff; -				if (sp->ttis[j].tt_isdst) -					theirdstoffset = theiroffset; -				else	theirstdoffset = theiroffset; -			} -			/* -			** Finally, fill in ttis. -			** ttisstd and ttisgmt need not be handled. -			*/ -			sp->ttis[0].tt_gmtoff = -stdoffset; -			sp->ttis[0].tt_isdst = FALSE; -			sp->ttis[0].tt_abbrind = 0; -			sp->ttis[1].tt_gmtoff = -dstoffset; -			sp->ttis[1].tt_isdst = TRUE; -			sp->ttis[1].tt_abbrind = stdlen + 1; -		} -	} else { -		dstlen = 0; -		sp->typecnt = 1;		/* only standard time */ -		sp->timecnt = 0; -		sp->ttis[0].tt_gmtoff = -stdoffset; -		sp->ttis[0].tt_isdst = 0; -		sp->ttis[0].tt_abbrind = 0; -	} -	sp->charcnt = stdlen + 1; -	if (dstlen != 0) -		sp->charcnt += dstlen + 1; -	if (sp->charcnt > sizeof sp->chars) -		return -1; -	cp = sp->chars; -	(void) strncpy(cp, stdname, stdlen); -	cp += stdlen; -	*cp++ = '\0'; -	if (dstlen != 0) { -		(void) strncpy(cp, dstname, dstlen); -		*(cp + dstlen) = '\0'; -	} -	return 0; -} - -static void -gmtload(sp) -struct state * const	sp; -{ -	if (tzload(gmt, sp) != 0) -		(void) tzparse(gmt, sp, TRUE); -} - -#ifndef STD_INSPIRED -/* -** A non-static declaration of tzsetwall in a system header file -** may cause a warning about this upcoming static declaration... -*/ -static -#endif /* !defined STD_INSPIRED */ -void -tzsetwall P((void)) -{ -	if (lcl_is_set < 0) -		return; -	lcl_is_set = -1; - -#ifdef ALL_STATE -	if (lclptr == NULL) { -		lclptr = (struct state *) malloc(sizeof *lclptr); -		if (lclptr == NULL) { -			settzname();	/* all we can do */ -			return; -		} -	} -#endif /* defined ALL_STATE */ -	if (tzload((char *) NULL, lclptr) != 0) -		gmtload(lclptr); -	settzname(); -} - -void -tzset P((void)) -{ -	register const char *	name; - -	name = getenv("TZ"); -	if (name == NULL) { -		tzsetwall(); -		return; -	} - -	if (lcl_is_set > 0  &&  strcmp(lcl_TZname, name) == 0) -		return; -	lcl_is_set = (strlen(name) < sizeof(lcl_TZname)); -	if (lcl_is_set) -		(void) strcpy(lcl_TZname, name); - -#ifdef ALL_STATE -	if (lclptr == NULL) { -		lclptr = (struct state *) malloc(sizeof *lclptr); -		if (lclptr == NULL) { -			settzname();	/* all we can do */ -			return; -		} -	} -#endif /* defined ALL_STATE */ -	if (*name == '\0') { -		/* -		** User wants it fast rather than right. -		*/ -		lclptr->leapcnt = 0;		/* so, we're off a little */ -		lclptr->timecnt = 0; -		lclptr->ttis[0].tt_gmtoff = 0; -		lclptr->ttis[0].tt_abbrind = 0; -		(void) strcpy(lclptr->chars, gmt); -	} else if (tzload(name, lclptr) != 0) -		if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0) -			(void) gmtload(lclptr); -	settzname(); -} - -/* -** The easy way to behave "as if no library function calls" localtime -** is to not call it--so we drop its guts into "localsub", which can be -** freely called.  (And no, the PANS doesn't require the above behavior-- -** but it *is* desirable.) -** -** The unused offset argument is for the benefit of mktime variants. -*/ - -/*ARGSUSED*/ -static void -localsub(timep, offset, tmp) -const time_t * const	timep; -const long		offset; -struct tm * const	tmp; -{ -	register struct state *		sp; -	register const struct ttinfo *	ttisp; -	register int			i; -	const time_t			t = *timep; - -	sp = lclptr; -#ifdef ALL_STATE -	if (sp == NULL) { -		gmtsub(timep, offset, tmp); -		return; -	} -#endif /* defined ALL_STATE */ -	if (sp->timecnt == 0 || t < sp->ats[0]) { -		i = 0; -		while (sp->ttis[i].tt_isdst) -			if (++i >= sp->typecnt) { -				i = 0; -				break; -			} -	} else { -		for (i = 1; i < sp->timecnt; ++i) -			if (t < sp->ats[i]) -				break; -		i = sp->types[i - 1]; -	} -	ttisp = &sp->ttis[i]; -	/* -	** To get (wrong) behavior that's compatible with System V Release 2.0 -	** you'd replace the statement below with -	**	t += ttisp->tt_gmtoff; -	**	timesub(&t, 0L, sp, tmp); -	*/ -	timesub(&t, ttisp->tt_gmtoff, sp, tmp); -	tmp->tm_isdst = ttisp->tt_isdst; -	tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind]; -#ifdef TM_ZONE -	tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind]; -#endif /* defined TM_ZONE */ -} - -struct tm * -localtime(timep) -const time_t * const	timep; -{ -	tzset(); -	localsub(timep, 0L, &tm); -	return &tm; -} - -/* -** gmtsub is to gmtime as localsub is to localtime. -*/ - -static void -gmtsub(timep, offset, tmp) -const time_t * const	timep; -const long		offset; -struct tm * const	tmp; -{ -	if (!gmt_is_set) { -		gmt_is_set = TRUE; -#ifdef ALL_STATE -		gmtptr = (struct state *) malloc(sizeof *gmtptr); -		if (gmtptr != NULL) -#endif /* defined ALL_STATE */ -			gmtload(gmtptr); -	} -	timesub(timep, offset, gmtptr, tmp); -#ifdef TM_ZONE -	/* -	** Could get fancy here and deliver something such as -	** "GMT+xxxx" or "GMT-xxxx" if offset is non-zero, -	** but this is no time for a treasure hunt. -	*/ -	if (offset != 0) -		tmp->TM_ZONE = wildabbr; -	else { -#ifdef ALL_STATE -		if (gmtptr == NULL) -			tmp->TM_ZONE = gmt; -		else	tmp->TM_ZONE = gmtptr->chars; -#endif /* defined ALL_STATE */ -#ifndef ALL_STATE -		tmp->TM_ZONE = gmtptr->chars; -#endif /* State Farm */ -	} -#endif /* defined TM_ZONE */ -} - -struct tm * -gmtime(timep) -const time_t * const	timep; -{ -	gmtsub(timep, 0L, &tm); -	return &tm; -} - -#ifdef STD_INSPIRED - -struct tm * -offtime(timep, offset) -const time_t * const	timep; -const long		offset; -{ -	gmtsub(timep, offset, &tm); -	return &tm; -} - -#endif /* defined STD_INSPIRED */ - -static void -timesub(timep, offset, sp, tmp) -const time_t * const			timep; -const long				offset; -register const struct state * const	sp; -register struct tm * const		tmp; -{ -	register const struct lsinfo *	lp; -	register long			days; -	register long			rem; -	register int			y; -	register int			yleap; -	register const int *		ip; -	register long			corr; -	register int			hit; -	register int			i; - -	corr = 0; -	hit = 0; -#ifdef ALL_STATE -	i = (sp == NULL) ? 0 : sp->leapcnt; -#endif /* defined ALL_STATE */ -#ifndef ALL_STATE -	i = sp->leapcnt; -#endif /* State Farm */ -	while (--i >= 0) { -		lp = &sp->lsis[i]; -		if (*timep >= lp->ls_trans) { -			if (*timep == lp->ls_trans) { -				hit = ((i == 0 && lp->ls_corr > 0) || -					lp->ls_corr > sp->lsis[i - 1].ls_corr); -				if (hit) -					while (i > 0 && -						sp->lsis[i].ls_trans == -						sp->lsis[i - 1].ls_trans + 1 && -						sp->lsis[i].ls_corr == -						sp->lsis[i - 1].ls_corr + 1) { -							++hit; -							--i; -					} -			} -			corr = lp->ls_corr; -			break; -		} -	} -	days = *timep / SECSPERDAY; -	rem = *timep % SECSPERDAY; -#ifdef mc68k -	if (*timep == 0x80000000) { -		/* -		** A 3B1 muffs the division on the most negative number. -		*/ -		days = -24855; -		rem = -11648; -	} -#endif /* defined mc68k */ -	rem += (offset - corr); -	while (rem < 0) { -		rem += SECSPERDAY; -		--days; -	} -	while (rem >= SECSPERDAY) { -		rem -= SECSPERDAY; -		++days; -	} -	tmp->tm_hour = (int) (rem / SECSPERHOUR); -	rem = rem % SECSPERHOUR; -	tmp->tm_min = (int) (rem / SECSPERMIN); -	/* -	** 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; -#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]; -	for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon)) -		days = days - (long) ip[tmp->tm_mon]; -	tmp->tm_mday = (int) (days + 1); -	tmp->tm_isdst = 0; -#ifdef TM_GMTOFF -	tmp->TM_GMTOFF = offset; -#endif /* defined TM_GMTOFF */ -} - -char * -ctime(timep) -const time_t * const	timep; -{ -/* -** Section 4.12.3.2 of X3.159-1989 requires that -**	The ctime funciton converts the calendar time pointed to by timer -**	to local time in the form of a string.  It is equivalent to -**		asctime(localtime(timer)) -*/ -	return asctime(localtime(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. -**	[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). -*/ - -#ifndef WRONG -#define WRONG	(-1) -#endif /* !defined WRONG */ - -/* -** Simplified normalize logic courtesy Paul Eggert (eggert@twinsun.com). -*/ - -static int -increment_overflow(number, delta) -int *	number; -int	delta; -{ -	int	number0; - -	number0 = *number; -	*number += delta; -	return (*number < number0) != (delta < 0); -} - -static int -normalize_overflow(tensptr, unitsptr, base) -int * const	tensptr; -int * const	unitsptr; -const int	base; -{ -	register int	tensdelta; - -	tensdelta = (*unitsptr >= 0) ? -		(*unitsptr / base) : -		(-1 - (-1 - *unitsptr) / base); -	*unitsptr -= tensdelta * base; -	return increment_overflow(tensptr, tensdelta); -} - -static int -tmcomp(atmp, btmp) -register const struct tm * const atmp; -register const struct tm * const btmp; -{ -	register int	result; - -	if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && -		(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) -			result = atmp->tm_sec - btmp->tm_sec; -	return result; -} - -static time_t -time2(tmp, funcp, offset, okayp) -struct tm * const	tmp; -void (* const		funcp) P((const time_t*, long, struct tm*)); -const long		offset; -int * const		okayp; -{ -	register const struct state *	sp; -	register int			dir; -	register int			bits; -	register int			i, j ; -	register int			saved_seconds; -	time_t				newt; -	time_t				t; -	struct tm			yourtm, mytm; - -	*okayp = FALSE; -	yourtm = *tmp; -	if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR)) -		return WRONG; -	if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) -		return WRONG; -	if (normalize_overflow(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR)) -		return WRONG; -	/* -	** Turn yourtm.tm_year into an actual year number for now. -	** It is converted back to an offset from TM_YEAR_BASE later. -	*/ -	if (increment_overflow(&yourtm.tm_year, TM_YEAR_BASE)) -		return WRONG; -	while (yourtm.tm_mday <= 0) { -		if (increment_overflow(&yourtm.tm_year, -1)) -			return WRONG; -		i = yourtm.tm_year + (1 < yourtm.tm_mon); -		yourtm.tm_mday += year_lengths[isleap(i)]; -	} -	while (yourtm.tm_mday > DAYSPERLYEAR) { -		i = yourtm.tm_year + (1 < yourtm.tm_mon); -		yourtm.tm_mday -= year_lengths[isleap(i)]; -		if (increment_overflow(&yourtm.tm_year, 1)) -			return WRONG; -	} -	for ( ; ; ) { -		i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon]; -		if (yourtm.tm_mday <= i) -			break; -		yourtm.tm_mday -= i; -		if (++yourtm.tm_mon >= MONSPERYEAR) { -			yourtm.tm_mon = 0; -			if (increment_overflow(&yourtm.tm_year, 1)) -				return WRONG; -		} -	} -	if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE)) -		return WRONG; -	if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) { -		/* -		** We can't set tm_sec to 0, because that might push the -		** time below the minimum representable time. -		** Set tm_sec to 59 instead. -		** This assumes that the minimum representable time is -		** not in the same minute that a leap second was deleted from, -		** which is a safer assumption than using 58 would be. -		*/ -		if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN)) -			return WRONG; -		saved_seconds = yourtm.tm_sec; -		yourtm.tm_sec = SECSPERMIN - 1; -	} else { -		saved_seconds = yourtm.tm_sec; -		yourtm.tm_sec = 0; -	} -	/* -	** Divide the search space in half -	** (this works whether time_t is signed or unsigned). -	*/ -	bits = TYPE_BIT(time_t) - 1; -	/* -	** 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 = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits); -	for ( ; ; ) { -		(*funcp)(&t, offset, &mytm); -		dir = tmcomp(&mytm, &yourtm); -		if (dir != 0) { -			if (bits-- < 0) -				return WRONG; -			if (bits < 0) -				--t; /* may be needed if new t is minimal */ -			else if (dir > 0) -				t -= ((time_t) 1) << bits; -			else	t += ((time_t) 1) << bits; -			continue; -		} -		if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) -			break; -		/* -		** Right time, wrong type. -		** Hunt for right time, right type. -		** It's okay to guess wrong since the guess -		** gets checked. -		*/ -		/* -		** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's. -		*/ -		sp = (const struct state *) -			(((void *) funcp == (void *) localsub) ? -			lclptr : gmtptr); -#ifdef ALL_STATE -		if (sp == NULL) -			return WRONG; -#endif /* defined ALL_STATE */ -		for (i = sp->typecnt - 1; i >= 0; --i) { -			if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) -				continue; -			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 - -					sp->ttis[i].tt_gmtoff; -				(*funcp)(&newt, offset, &mytm); -				if (tmcomp(&mytm, &yourtm) != 0) -					continue; -				if (mytm.tm_isdst != yourtm.tm_isdst) -					continue; -				/* -				** We have a match. -				*/ -				t = newt; -				goto label; -			} -		} -		return WRONG; -	} -label: -	newt = t + saved_seconds; -	if ((newt < t) != (saved_seconds < 0)) -		return WRONG; -	t = newt; -	(*funcp)(&t, offset, tmp); -	*okayp = TRUE; -	return t; -} - -static time_t -time1(tmp, funcp, offset) -struct tm * const	tmp; -void (* const		funcp) P((const time_t *, long, struct tm *)); -const long		offset; -{ -	register time_t			t; -	register const struct state *	sp; -	register int			samei, otheri; -	int				okay; - -	if (tmp->tm_isdst > 1) -		tmp->tm_isdst = 1; -	t = time2(tmp, funcp, offset, &okay); -#ifdef PCTS -	/* -	** PCTS code courtesy Grant Sullivan (grant@osf.org). -	*/ -	if (okay) -		return t; -	if (tmp->tm_isdst < 0) -		tmp->tm_isdst = 0;	/* reset to std and try again */ -#endif /* defined PCTS */ -#ifndef PCTS -	if (okay || tmp->tm_isdst < 0) -		return t; -#endif /* !defined PCTS */ -	/* -	** We're supposed to assume that somebody took a time of one type -	** and did some math on it that yielded a "struct tm" that's bad. -	** We try to divine the type they started from and adjust to the -	** type they need. -	*/ -	/* -	** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's. -	*/ -	sp = (const struct state *) (((void *) funcp == (void *) localsub) ? -		lclptr : gmtptr); -#ifdef ALL_STATE -	if (sp == NULL) -		return WRONG; -#endif /* defined ALL_STATE */ -	for (samei = sp->typecnt - 1; samei >= 0; --samei) { -		if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) -			continue; -		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 - -					sp->ttis[samei].tt_gmtoff; -			tmp->tm_isdst = !tmp->tm_isdst; -			t = time2(tmp, funcp, offset, &okay); -			if (okay) -				return t; -			tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff - -					sp->ttis[samei].tt_gmtoff; -			tmp->tm_isdst = !tmp->tm_isdst; -		} -	} -	return WRONG; -} - -time_t -mktime(tmp) -struct tm * const	tmp; -{ -	tzset(); -	return time1(tmp, localsub, 0L); -} - -#ifdef STD_INSPIRED - -time_t -timelocal(tmp) -struct tm * const	tmp; -{ -	tmp->tm_isdst = -1;	/* in case it wasn't initialized */ -	return mktime(tmp); -} - -time_t -timegm(tmp) -struct tm * const	tmp; -{ -	tmp->tm_isdst = 0; -	return time1(tmp, gmtsub, 0L); -} - -time_t -timeoff(tmp, offset) -struct tm * const	tmp; -const long		offset; -{ -	tmp->tm_isdst = 0; -	return time1(tmp, gmtsub, offset); -} - -#endif /* defined STD_INSPIRED */ - -#ifdef CMUCS - -/* -** The following is supplied for compatibility with -** previous versions of the CMUCS runtime library. -*/ - -long -gtime(tmp) -struct tm * const	tmp; -{ -	const time_t	t = mktime(tmp); - -	if (t == WRONG) -		return -1; -	return t; -} - -#endif /* defined CMUCS */ - -/* -** XXX--is the below the right way to conditionalize?? -*/ - -#ifdef STD_INSPIRED - -/* -** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599 -** shall correspond to "Wed Dec 31 23:59:59 GMT 1986", which -** is not the case if we are accounting for leap seconds. -** So, we provide the following conversion routines for use -** when exchanging timestamps with POSIX conforming systems. -*/ - -static long -leapcorr(timep) -time_t *	timep; -{ -	register struct state *		sp; -	register struct lsinfo *	lp; -	register int			i; - -	sp = lclptr; -	i = sp->leapcnt; -	while (--i >= 0) { -		lp = &sp->lsis[i]; -		if (*timep >= lp->ls_trans) -			return lp->ls_corr; -	} -	return 0; -} - -time_t -time2posix(t) -time_t	t; -{ -	tzset(); -	return t - leapcorr(&t); -} - -time_t -posix2time(t) -time_t	t; -{ -	time_t	x; -	time_t	y; - -	tzset(); -	/* -	** For a positive leap second hit, the result -	** is not unique.  For a negative leap second -	** hit, the corresponding time doesn't exist, -	** so we return an adjacent second. -	*/ -	x = t + leapcorr(&t); -	y = x - leapcorr(&x); -	if (y < t) { -		do { -			x++; -			y = x - leapcorr(&x); -		} while (y < t); -		if (t != y) -			return x - 1; -	} else if (y > t) { -		do { -			--x; -			y = x - leapcorr(&x); -		} while (y > t); -		if (t != y) -			return x + 1; -	} -	return x; -} - -#endif /* defined STD_INSPIRED */ diff --git a/lib/libc/stdtime/private.h b/lib/libc/stdtime/private.h deleted file mode 100644 index f81bf4867bdb..000000000000 --- a/lib/libc/stdtime/private.h +++ /dev/null @@ -1,252 +0,0 @@ -#ifndef PRIVATE_H - -#define PRIVATE_H - -/* -** This file is in the public domain, so clarified as of -** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov). -*/ - -/* -** This header is for use ONLY with the time conversion code. -** There is no guarantee that it will remain unchanged, -** or that it will remain at all. -** Do NOT copy it to any system include directory. -** Thank you! -*/ - -/* -** ID -*/ - -#ifndef lint -#ifndef NOID -static char	privatehid[] = "@(#)private.h	7.43"; -#endif /* !defined NOID */ -#endif /* !defined lint */ - -/* -** Defaults for preprocessor symbols. -** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'. -*/ - -#ifndef HAVE_ADJTIME -#define HAVE_ADJTIME		1 -#endif /* !defined HAVE_ADJTIME */ - -#ifndef HAVE_GETTEXT -#define HAVE_GETTEXT		0 -#endif /* !defined HAVE_GETTEXT */ - -#ifndef HAVE_SETTIMEOFDAY -#define HAVE_SETTIMEOFDAY	3 -#endif /* !defined HAVE_SETTIMEOFDAY */ - -#ifndef HAVE_STRERROR -#define HAVE_STRERROR		0 -#endif /* !defined HAVE_STRERROR */ - -#ifndef HAVE_UNISTD_H -#define HAVE_UNISTD_H		1 -#endif /* !defined HAVE_UNISTD_H */ - -#ifndef HAVE_UTMPX_H -#define HAVE_UTMPX_H		0 -#endif /* !defined HAVE_UTMPX_H */ - -#ifndef LOCALE_HOME -#define LOCALE_HOME		"/usr/lib/locale" -#endif /* !defined LOCALE_HOME */ - -/* -** Nested includes -*/ - -#include "sys/types.h"	/* for time_t */ -#include "stdio.h" -#include "errno.h" -#include "string.h" -#include "limits.h"	/* for CHAR_BIT */ -#include "time.h" -#include "stdlib.h" - -#if HAVE_GETTEXT - 0 -#include "libintl.h" -#endif /* HAVE_GETTEXT - 0 */ - -#if HAVE_UNISTD_H - 0 -#include "unistd.h"	/* for F_OK and R_OK */ -#endif /* HAVE_UNISTD_H - 0 */ - -#if !(HAVE_UNISTD_H - 0) -#ifndef F_OK -#define F_OK	0 -#endif /* !defined F_OK */ -#ifndef R_OK -#define R_OK	4 -#endif /* !defined R_OK */ -#endif /* !(HAVE_UNISTD_H - 0) */ - -/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX.  */ -#define is_digit(c) ((unsigned)(c) - '0' <= 9) - -/* -** Workarounds for compilers/systems. -*/ - -/* -** SunOS 4.1.1 cc lacks const. -*/ - -#ifndef const -#ifndef __STDC__ -#define const -#endif /* !defined __STDC__ */ -#endif /* !defined const */ - -/* -** SunOS 4.1.1 cc lacks prototypes. -*/ - -#ifndef P -#ifdef __STDC__ -#define P(x)	x -#endif /* defined __STDC__ */ -#ifndef __STDC__ -#define P(x)	() -#endif /* !defined __STDC__ */ -#endif /* !defined P */ - -/* -** SunOS 4.1.1 headers lack EXIT_SUCCESS. -*/ - -#ifndef EXIT_SUCCESS -#define EXIT_SUCCESS	0 -#endif /* !defined EXIT_SUCCESS */ - -/* -** SunOS 4.1.1 headers lack EXIT_FAILURE. -*/ - -#ifndef EXIT_FAILURE -#define EXIT_FAILURE	1 -#endif /* !defined EXIT_FAILURE */ - -/* -** SunOS 4.1.1 headers lack FILENAME_MAX. -*/ - -#ifndef FILENAME_MAX - -#ifndef MAXPATHLEN -#ifdef unix -#include "sys/param.h" -#endif /* defined unix */ -#endif /* !defined MAXPATHLEN */ - -#ifdef MAXPATHLEN -#define FILENAME_MAX	MAXPATHLEN -#endif /* defined MAXPATHLEN */ -#ifndef MAXPATHLEN -#define FILENAME_MAX	1024		/* Pure guesswork */ -#endif /* !defined MAXPATHLEN */ - -#endif /* !defined FILENAME_MAX */ - -/* -** SunOS 4.1.1 libraries lack remove. -*/ - -#ifndef remove -extern int	unlink P((const char * filename)); -#define remove	unlink -#endif /* !defined remove */ - -/* -** Some ancient errno.h implementations don't declare errno. -** But some newer errno.h implementations define it as a macro. -** Fix the former without affecting the latter. -*/ -#ifndef errno -extern int errno; -#endif /* !defined errno */ - -/* -** Finally, some convenience items. -*/ - -#ifndef TRUE -#define TRUE	1 -#endif /* !defined TRUE */ - -#ifndef FALSE -#define FALSE	0 -#endif /* !defined FALSE */ - -#ifndef TYPE_BIT -#define TYPE_BIT(type)	(sizeof (type) * CHAR_BIT) -#endif /* !defined TYPE_BIT */ - -#ifndef TYPE_SIGNED -#define TYPE_SIGNED(type) (((type) -1) < 0) -#endif /* !defined TYPE_SIGNED */ - -#ifndef INT_STRLEN_MAXIMUM -/* -** 302 / 1000 is log10(2.0) rounded up. -** Subtract one for the sign bit if the type is signed; -** add one for integer division truncation; -** add one more for a minus sign if the type is signed. -*/ -#define INT_STRLEN_MAXIMUM(type) \ -    ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 100 + 1 + TYPE_SIGNED(type)) -#endif /* !defined INT_STRLEN_MAXIMUM */ - -/* -** INITIALIZE(x) -*/ - -#ifndef GNUC_or_lint -#ifdef lint -#define GNUC_or_lint -#endif /* defined lint */ -#ifndef lint -#ifdef __GNUC__ -#define GNUC_or_lint -#endif /* defined __GNUC__ */ -#endif /* !defined lint */ -#endif /* !defined GNUC_or_lint */ - -#ifndef INITIALIZE -#ifdef GNUC_or_lint -#define INITIALIZE(x)	((x) = 0) -#endif /* defined GNUC_or_lint */ -#ifndef GNUC_or_lint -#define INITIALIZE(x) -#endif /* !defined GNUC_or_lint */ -#endif /* !defined INITIALIZE */ - -/* -** For the benefit of GNU folk... -** `_(MSGID)' uses the current locale's message library string for MSGID. -** The default is to use gettext if available, and use MSGID otherwise. -*/ - -#ifndef _ -#if HAVE_GETTEXT - 0 -#define _(msgid) gettext(msgid) -#else /* !(HAVE_GETTEXT - 0) */ -#define _(msgid) msgid -#endif /* !(HAVE_GETTEXT - 0) */ -#endif /* !defined _ */ - -#ifndef TZ_DOMAIN -#define TZ_DOMAIN "tz" -#endif /* !defined TZ_DOMAIN */ - -/* -** UNIX was a registered trademark of UNIX System Laboratories in 1993. -*/ - -#endif /* !defined PRIVATE_H */ diff --git a/lib/libc/stdtime/strftime.c b/lib/libc/stdtime/strftime.c deleted file mode 100644 index a5ba85c90473..000000000000 --- a/lib/libc/stdtime/strftime.c +++ /dev/null @@ -1,604 +0,0 @@ -#ifndef lint -#ifndef NOID -static char	elsieid[] = "@(#)strftime.c	7.47"; -/* -** Based on the UCB version with the ID appearing below. -** This is ANSIish only when "multibyte character == plain character". -*/ -#endif /* !defined NOID */ -#endif /* !defined lint */ - -#include "private.h" - -/* -** Copyright (c) 1989 The Regents of the University of California. -** All rights reserved. -** -** Redistribution and use in source and binary forms are permitted -** provided that the above copyright notice and this paragraph are -** duplicated in all such forms and that any documentation, -** advertising materials, and other materials related to such -** distribution and use acknowledge that the software was developed -** by the University of California, Berkeley.  The name of the -** University may not be used to endorse or promote products derived -** from this software without specific prior written permission. -** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -*/ - -#ifndef LIBC_SCCS -#ifndef lint -static const char	sccsid[] = "@(#)strftime.c	5.4 (Berkeley) 3/14/89"; -#endif /* !defined lint */ -#endif /* !defined LIBC_SCCS */ - -#include "tzfile.h" -#include "fcntl.h" -#include "locale.h" - -struct lc_time_T { -	const char *	mon[12]; -	const char *	month[12]; -	const char *	wday[7]; -	const char *	weekday[7]; -	const char *	X_fmt; -	const char *	x_fmt; -	const char *	c_fmt; -	const char *	am; -	const char *	pm; -	const char *	date_fmt; -}; - -#ifdef LOCALE_HOME -#include "sys/stat.h" -static struct lc_time_T		localebuf; -static struct lc_time_T *	_loc P((void)); -#define Locale	_loc() -#endif /* defined LOCALE_HOME */ -#ifndef LOCALE_HOME -#define Locale	(&C_time_locale) -#endif /* !defined LOCALE_HOME */ - -static const struct lc_time_T	C_time_locale = { -	{ -		"Jan", "Feb", "Mar", "Apr", "May", "Jun", -		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -	}, { -		"January", "February", "March", "April", "May", "June", -		"July", "August", "September", "October", "November", "December" -	}, { -		"Sun", "Mon", "Tue", "Wed", -		"Thu", "Fri", "Sat" -	}, { -		"Sunday", "Monday", "Tuesday", "Wednesday", -		"Thursday", "Friday", "Saturday" -	}, - -	/* X_fmt */ -	"%H:%M:%S", - -	/* -	** x_fmt -	** Since the C language standard calls for -	** "date, using locale's date format," anything goes. -	** Using just numbers (as here) makes Quakers happier; -	** it's also compatible with SVR4. -	*/ -	"%m/%d/%y", - -	/* -	** c_fmt -	** Note that -	**	"%a %b %d %H:%M:%S %Y" -	** is used by Solaris 2.3. -	*/ -	"%D %X",	/* %m/%d/%y %H:%M:%S */ - -	/* am */ -	"AM", - -	/* pm */ -	"PM", - -	/* date_fmt */ -	"%a %b %e %H:%M:%S %Z %Y" -}; - -static char *	_add P((const char *, char *, const char *)); -static char *	_conv P((int, const char *, char *, const char *)); -static char *	_fmt P((const char *, const struct tm *, char *, const char *)); - -size_t strftime P((char *, size_t, const char *, const struct tm *)); - -extern char *	tzname[]; - -size_t -strftime(s, maxsize, format, t) -char * const		s; -const size_t		maxsize; -const char * const	format; -const struct tm * const	t; -{ -	char *	p; - -	tzset(); -#ifdef LOCALE_HOME -	localebuf.mon[0] = 0; -#endif /* defined LOCALE_HOME */ -	p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize); -	if (p == s + maxsize) -		return 0; -	*p = '\0'; -	return p - s; -} - -static char * -_fmt(format, t, pt, ptlim) -const char *		format; -const struct tm * const	t; -char *			pt; -const char * const	ptlim; -{ -	for ( ; *format; ++format) { -		if (*format == '%') { -label: -			switch (*++format) { -			case '\0': -				--format; -				break; -			case 'A': -				pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ? -					"?" : Locale->weekday[t->tm_wday], -					pt, ptlim); -				continue; -			case 'a': -				pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ? -					"?" : Locale->wday[t->tm_wday], -					pt, ptlim); -				continue; -			case 'B': -				pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ? -					"?" : Locale->month[t->tm_mon], -					pt, ptlim); -				continue; -			case 'b': -			case 'h': -				pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ? -					"?" : Locale->mon[t->tm_mon], -					pt, ptlim); -				continue; -			case 'C': -				/* -				** %C used to do a... -				**	_fmt("%a %b %e %X %Y", t); -				** ...whereas now POSIX 1003.2 calls for -				** something completely different. -				** (ado, 5/24/93) -				*/ -				pt = _conv((t->tm_year + TM_YEAR_BASE) / 100, -					"%02d", pt, ptlim); -				continue; -			case 'c': -				pt = _fmt(Locale->c_fmt, t, pt, ptlim); -				continue; -			case 'D': -				pt = _fmt("%m/%d/%y", t, pt, ptlim); -				continue; -			case 'd': -				pt = _conv(t->tm_mday, "%02d", pt, ptlim); -				continue; -			case 'E': -			case 'O': -				/* -				** POSIX locale extensions, a la -				** Arnold Robbins' strftime version 3.0. -				** The sequences -				**	%Ec %EC %Ex %Ey %EY -				**	%Od %oe %OH %OI %Om %OM -				**	%OS %Ou %OU %OV %Ow %OW %Oy -				** are supposed to provide alternate -				** representations. -				** (ado, 5/24/93) -				*/ -				goto label; -			case 'e': -				pt = _conv(t->tm_mday, "%2d", pt, ptlim); -				continue; -			case 'H': -				pt = _conv(t->tm_hour, "%02d", pt, ptlim); -				continue; -			case 'I': -				pt = _conv((t->tm_hour % 12) ? -					(t->tm_hour % 12) : 12, -					"%02d", pt, ptlim); -				continue; -			case 'j': -				pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim); -				continue; -			case 'k': -				/* -				** This used to be... -				**	_conv(t->tm_hour % 12 ? -				**		t->tm_hour % 12 : 12, 2, ' '); -				** ...and has been changed to the below to -				** match SunOS 4.1.1 and Arnold Robbins' -				** strftime version 3.0.  That is, "%k" and -				** "%l" have been swapped. -				** (ado, 5/24/93) -				*/ -				pt = _conv(t->tm_hour, "%2d", pt, ptlim); -				continue; -#ifdef KITCHEN_SINK -			case 'K': -				/* -				** After all this time, still unclaimed! -				*/ -				pt = _add("kitchen sink", pt, ptlim); -				continue; -#endif /* defined KITCHEN_SINK */ -			case 'l': -				/* -				** This used to be... -				**	_conv(t->tm_hour, 2, ' '); -				** ...and has been changed to the below to -				** match SunOS 4.1.1 and Arnold Robbin's -				** strftime version 3.0.  That is, "%k" and -				** "%l" have been swapped. -				** (ado, 5/24/93) -				*/ -				pt = _conv((t->tm_hour % 12) ? -					(t->tm_hour % 12) : 12, -					"%2d", pt, ptlim); -				continue; -			case 'M': -				pt = _conv(t->tm_min, "%02d", pt, ptlim); -				continue; -			case 'm': -				pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim); -				continue; -			case 'n': -				pt = _add("\n", pt, ptlim); -				continue; -			case 'p': -				pt = _add((t->tm_hour >= 12) ? -					Locale->pm : -					Locale->am, -					pt, ptlim); -				continue; -			case 'R': -				pt = _fmt("%H:%M", t, pt, ptlim); -				continue; -			case 'r': -				pt = _fmt("%I:%M:%S %p", t, pt, ptlim); -				continue; -			case 'S': -				pt = _conv(t->tm_sec, "%02d", pt, ptlim); -				continue; -			case 's': -				{ -					struct tm	tm; -					char		buf[INT_STRLEN_MAXIMUM( -								time_t) + 1]; -					time_t		mkt; - -					tm = *t; -					mkt = mktime(&tm); -					if (TYPE_SIGNED(time_t)) -						(void) sprintf(buf, "%ld", -							(long) mkt); -					else	(void) sprintf(buf, "%lu", -							(unsigned long) mkt); -					pt = _add(buf, pt, ptlim); -				} -				continue; -			case 'T': -				pt = _fmt("%H:%M:%S", t, pt, ptlim); -				continue; -			case 't': -				pt = _add("\t", pt, ptlim); -				continue; -			case 'U': -				pt = _conv((t->tm_yday + 7 - t->tm_wday) / 7, -					"%02d", pt, ptlim); -				continue; -			case 'u': -				/* -				** From Arnold Robbins' strftime version 3.0: -				** "ISO 8601: Weekday as a decimal number -				** [1 (Monday) - 7]" -				** (ado, 5/24/93) -				*/ -				pt = _conv((t->tm_wday == 0) ? 7 : t->tm_wday, -					"%d", pt, ptlim); -				continue; -			case 'V':	/* ISO 8601 week number */ -			case 'G':	/* ISO 8601 year (four digits) */ -			case 'g':	/* ISO 8601 year (two digits) */ -/* -** From Arnold Robbins' strftime version 3.0:  "the week number of the -** year (the first Monday as the first day of week 1) as a decimal number -** (01-53)." -** (ado, 1993-05-24) -** -** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn: -** "Week 01 of a year is per definition the first week which has the -** Thursday in this year, which is equivalent to the week which contains -** the fourth day of January. In other words, the first week of a new year -** is the week which has the majority of its days in the new year. Week 01 -** might also contain days from the previous year and the week before week -** 01 of a year is the last week (52 or 53) of the previous year even if -** it contains days from the new year. A week starts with Monday (day 1) -** and ends with Sunday (day 7).  For example, the first week of the year -** 1997 lasts from 1996-12-30 to 1997-01-05..." -** (ado, 1996-01-02) -*/ -				{ -					int	year; -					int	yday; -					int	wday; -					int	w; - -					year = t->tm_year + TM_YEAR_BASE; -					yday = t->tm_yday; -					wday = t->tm_wday; -					for ( ; ; ) { -						int	len; -						int	bot; -						int	top; - -						len = isleap(year) ? -							DAYSPERLYEAR : -							DAYSPERNYEAR; -						/* -						** What yday (-3 ... 3) does -						** the ISO year begin on? -						*/ -						bot = ((yday + 11 - wday) % -							DAYSPERWEEK) - 3; -						/* -						** What yday does the NEXT -						** ISO year begin on? -						*/ -						top = bot - -							(len % DAYSPERWEEK); -						if (top < -3) -							top += DAYSPERWEEK; -						top += len; -						if (yday >= top) { -							++year; -							w = 1; -							break; -						} -						if (yday >= bot) { -							w = 1 + ((yday - bot) / -								DAYSPERWEEK); -							break; -						} -						--year; -						yday += isleap(year) ? -							DAYSPERLYEAR : -							DAYSPERNYEAR; -					} -#ifdef XPG4_1994_04_09 -					if (w == 52 && t->tm_mon == TM_JANUARY) -						w = 53; -#endif /* defined XPG4_1994_04_09 */ -					if (*format == 'V') -						pt = _conv(w, "%02d", -							pt, ptlim); -					else if (*format == 'G') -						pt = _conv(year, "%02d", -							pt, ptlim); -					else	pt = _conv(year, "%04d", -							pt, ptlim); -				} -				continue; -			case 'v': -				/* -				** From Arnold Robbins' strftime version 3.0: -				** "date as dd-bbb-YYYY" -				** (ado, 5/24/93) -				*/ -				pt = _fmt("%e-%b-%Y", t, pt, ptlim); -				continue; -			case 'W': -				pt = _conv((t->tm_yday + 7 - -					(t->tm_wday ? -					(t->tm_wday - 1) : 6)) / 7, -					"%02d", pt, ptlim); -				continue; -			case 'w': -				pt = _conv(t->tm_wday, "%d", pt, ptlim); -				continue; -			case 'X': -				pt = _fmt(Locale->X_fmt, t, pt, ptlim); -				continue; -			case 'x': -				pt = _fmt(Locale->x_fmt, t, pt, ptlim); -				continue; -			case 'y': -				pt = _conv((t->tm_year + TM_YEAR_BASE) % 100, -					"%02d", pt, ptlim); -				continue; -			case 'Y': -				pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d", -					pt, ptlim); -				continue; -			case 'Z': -#ifdef TM_ZONE -				if (t->TM_ZONE != NULL) -					pt = _add(t->TM_ZONE, pt, ptlim); -				else -#endif /* defined TM_ZONE */ -				if (t->tm_isdst == 0 || t->tm_isdst == 1) { -					pt = _add(tzname[t->tm_isdst], -						pt, ptlim); -				} else  pt = _add("?", pt, ptlim); -				continue; -			case '+': -				pt = _fmt(Locale->date_fmt, t, pt, ptlim); -				continue; -			case '%': -			/* -			 * X311J/88-090 (4.12.3.5): if conversion char is -			 * undefined, behavior is undefined.  Print out the -			 * character itself as printf(3) also does. -			 */ -			default: -				break; -			} -		} -		if (pt == ptlim) -			break; -		*pt++ = *format; -	} -	return pt; -} - -static char * -_conv(n, format, pt, ptlim) -const int		n; -const char * const	format; -char * const		pt; -const char * const	ptlim; -{ -	char	buf[INT_STRLEN_MAXIMUM(int) + 1]; - -	(void) sprintf(buf, format, n); -	return _add(buf, pt, ptlim); -} - -static char * -_add(str, pt, ptlim) -const char *		str; -char *			pt; -const char * const	ptlim; -{ -	while (pt < ptlim && (*pt = *str++) != '\0') -		++pt; -	return pt; -} - -#ifdef LOCALE_HOME -static struct lc_time_T * -_loc P((void)) -{ -	static const char	locale_home[] = LOCALE_HOME; -	static const char	lc_time[] = "LC_TIME"; -	static char *		locale_buf; -	static char		locale_buf_C[] = "C"; - -	int			fd; -	int			oldsun;	/* "...ain't got nothin' to do..." */ -	char *			lbuf; -	char *			name; -	char *			p; -	const char **		ap; -	const char *		plim; -	char			filename[FILENAME_MAX]; -	struct stat		st; -	size_t			namesize; -	size_t			bufsize; - -	/* -	** Use localebuf.mon[0] to signal whether locale is already set up. -	*/ -	if (localebuf.mon[0]) -		return &localebuf; -	name = setlocale(LC_TIME, (char *) NULL); -	if (name == NULL || *name == '\0') -		goto no_locale; -	/* -	** If the locale name is the same as our cache, use the cache. -	*/ -	lbuf = locale_buf; -	if (lbuf != NULL && strcmp(name, lbuf) == 0) { -		p = lbuf; -		for (ap = (const char **) &localebuf; -			ap < (const char **) (&localebuf + 1); -				++ap) -					*ap = p += strlen(p) + 1; -		return &localebuf; -	} -	/* -	** Slurp the locale file into the cache. -	*/ -	namesize = strlen(name) + 1; -	if (sizeof(filename) < -		sizeof(locale_home) + namesize + sizeof(lc_time)) -			goto no_locale; -	oldsun = 0; -	(void) sprintf(filename, "%s/%s/%s", locale_home, name, lc_time); -	fd = open(filename, O_RDONLY); -	if (fd < 0) { -		/* -		** Old Sun systems have a different naming and data convention. -		*/ -		oldsun = 1; -		(void) sprintf(filename, "%s/%s/%s", locale_home, -			lc_time, name); -		fd = open(filename, O_RDONLY); -		if (fd < 0) -			goto no_locale; -	} -	if (fstat(fd, &st) != 0) -		goto bad_locale; -	if (st.st_size <= 0) -		goto bad_locale; -	bufsize = namesize + st.st_size; -	locale_buf = NULL; -	lbuf = (lbuf == NULL || lbuf == locale_buf_C) ? -		malloc(bufsize) : realloc(lbuf, bufsize); -	if (lbuf == NULL) -		goto bad_locale; -	(void) strcpy(lbuf, name); -	p = lbuf + namesize; -	plim = p + st.st_size; -	if (read(fd, p, (size_t) st.st_size) != st.st_size) -		goto bad_lbuf; -	if (close(fd) != 0) -		goto bad_lbuf; -	/* -	** Parse the locale file into localebuf. -	*/ -	if (plim[-1] != '\n') -		goto bad_lbuf; -	for (ap = (const char **) &localebuf; -		ap < (const char **) (&localebuf + 1); -			++ap) { -				if (p == plim) -					goto bad_lbuf; -				*ap = p; -				while (*p != '\n') -					++p; -				*p++ = '\0'; -	} -	if (oldsun) { -		/* -		** SunOS 4 used an obsolescent format; see localdtconv(3). -		** c_fmt had the ``short format for dates and times together'' -		** (SunOS 4 date, "%a %b %e %T %Z %Y" in the C locale); -		** date_fmt had the ``long format for dates'' -		** (SunOS 4 strftime %C, "%A, %B %e, %Y" in the C locale). -		** Discard the latter in favor of the former. -		*/ -		localebuf.date_fmt = localebuf.c_fmt; -	} -	/* -	** Record the successful parse in the cache. -	*/ -	locale_buf = lbuf; - -	return &localebuf; - -bad_lbuf: -	free(lbuf); -bad_locale: -	(void) close(fd); -no_locale: -	localebuf = C_time_locale; -	locale_buf = locale_buf_C; -	return &localebuf; -} -#endif /* defined LOCALE_HOME */ diff --git a/lib/libc/stdtime/time2posix.3 b/lib/libc/stdtime/time2posix.3 deleted file mode 100644 index 846a52ed1931..000000000000 --- a/lib/libc/stdtime/time2posix.3 +++ /dev/null @@ -1,119 +0,0 @@ -.TH TIME2POSIX 3 -.SH NAME -time2posix, posix2time \- convert seconds since the Epoch -.SH SYNOPSIS -.nf -.B #include <sys/types.h> -.B #include <time.h> -.PP -.B time_t time2posix(t) -.B time_t t -.PP -.B time_t posix2time(t) -.B time_t t -.PP -.B cc ... -lz -.fi -.SH DESCRIPTION -IEEE Standard 1003.1 -(POSIX) -legislates that a time_t value of -536457599 shall correspond to "Wed Dec 31 23:59:59 GMT 1986." -This effectively implies that POSIX time_t's cannot include leap -seconds and, -therefore, -that the system time must be adjusted as each leap occurs. -.PP -If the time package is configured with leap-second support -enabled, -however, -no such adjustment is needed and -time_t values continue to increase over leap events -(as a true `seconds since...' value). -This means that these values will differ from those required by POSIX -by the net number of leap seconds inserted since the Epoch. -.PP -Typically this is not a problem as the type time_t is intended -to be -(mostly) -opaque\(emtime_t values should only be obtained-from and -passed-to functions such as -.IR time(2) , -.IR localtime(3) , -.IR mktime(3) , -and -.IR difftime(3) . -However, -POSIX gives an arithmetic -expression for directly computing a time_t value from a given date/time, -and the same relationship is assumed by some -(usually older) -applications. -Any programs creating/dissecting time_t's -using such a relationship will typically not handle intervals -over leap seconds correctly. -.PP -The -.I time2posix -and -.I posix2time -functions are provided to address this time_t mismatch by converting -between local time_t values and their POSIX equivalents. -This is done by accounting for the number of time-base changes that -would have taken place on a POSIX system as leap seconds were inserted -or deleted. -These converted values can then be used in lieu of correcting the older -applications, -or when communicating with POSIX-compliant systems. -.PP -.I Time2posix -is single-valued. -That is, -every local time_t -corresponds to a single POSIX time_t. -.I Posix2time -is less well-behaved: -for a positive leap second hit the result is not unique, -and for a negative leap second hit the corresponding -POSIX time_t doesn't exist so an adjacent value is returned. -Both of these are good indicators of the inferiority of the -POSIX representation. -.PP -The following table summarizes the relationship between a time -T and it's conversion to, -and back from, -the POSIX representation over the leap second inserted at the end of June, -1993. -.nf -.ta \w'93/06/30 'u +\w'23:59:59 'u +\w'A+0 'u +\w'X=time2posix(T) 'u -DATE	TIME	T	X=time2posix(T)	posix2time(X) -93/06/30	23:59:59	A+0	B+0	A+0 -93/06/30	23:59:60	A+1	B+1	A+1 or A+2 -93/07/01	00:00:00	A+2	B+1	A+1 or A+2 -93/07/01	00:00:01	A+3	B+2	A+3 - -A leap second deletion would look like... - -DATE	TIME	T	X=time2posix(T)	posix2time(X) -??/06/30	23:59:58	A+0	B+0	A+0 -??/07/01	00:00:00	A+1	B+2	A+1 -??/07/01	00:00:01	A+2	B+3	A+2 -.sp -.ce -	[Note: posix2time(B+1) => A+0 or A+1] -.fi -.PP -If leap-second support is not enabled, -local time_t's and -POSIX time_t's are equivalent, -and both -.I time2posix -and -.I posix2time -degenerate to the identity function. -.SH SEE ALSO -difftime(3), -localtime(3), -mktime(3), -time(2) -.\" @(#)time2posix.3	7.3 | 
