about summary refs log tree commit diff
path: root/timezone/zdump.c
diff options
context:
space:
mode:
Diffstat (limited to 'timezone/zdump.c')
-rw-r--r--timezone/zdump.c460
1 files changed, 99 insertions, 361 deletions
diff --git a/timezone/zdump.c b/timezone/zdump.c
index 3c8d179fce..20bb916822 100644
--- a/timezone/zdump.c
+++ b/timezone/zdump.c
@@ -1,4 +1,4 @@
-static char	elsieid[] = "@(#)zdump.c	8.2";
+static char	elsieid[] = "@(#)zdump.c	7.40";
 
 /*
 ** This code has been made independent of the rest of the time
@@ -11,19 +11,6 @@ static char	elsieid[] = "@(#)zdump.c	8.2";
 #include "sys/types.h"	/* for time_t */
 #include "time.h"	/* for struct tm */
 #include "stdlib.h"	/* for exit, malloc, atoi */
-#include "float.h"	/* for FLT_MAX and DBL_MAX */
-#include "ctype.h"	/* for isalpha et al. */
-#ifndef isascii
-#define isascii(x) 1
-#endif /* !defined isascii */
-
-#ifndef ZDUMP_LO_YEAR
-#define ZDUMP_LO_YEAR	(-500)
-#endif /* !defined ZDUMP_LO_YEAR */
-
-#ifndef ZDUMP_HI_YEAR
-#define ZDUMP_HI_YEAR	2500
-#endif /* !defined ZDUMP_HI_YEAR */
 
 #ifndef MAX_STRING_LENGTH
 #define MAX_STRING_LENGTH	1024
@@ -74,20 +61,9 @@ static char	elsieid[] = "@(#)zdump.c	8.2";
 #endif /* !defined DAYSPERNYEAR */
 
 #ifndef isleap
-#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
+#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
 #endif /* !defined isleap */
 
-#ifndef isleap_sum
-/*
-** See tzfile.h for details on isleap_sum.
-*/
-#define isleap_sum(a, b)	isleap((a) % 400 + (b) % 400)
-#endif /* !defined isleap_sum */
-
-#define SECSPERDAY	((long) SECSPERHOUR * HOURSPERDAY)
-#define SECSPERNYEAR	(SECSPERDAY * DAYSPERNYEAR)
-#define SECSPERLYEAR	(SECSPERNYEAR + SECSPERDAY)
-
 #if HAVE_GETTEXT
 #include "locale.h"	/* for setlocale */
 #include "libintl.h"
@@ -130,106 +106,27 @@ static char	elsieid[] = "@(#)zdump.c	8.2";
 #endif /* !defined TZ_DOMAIN */
 
 #ifndef P
+#ifdef __STDC__
 #define P(x)	x
+#else /* !defined __STDC__ */
+#define P(x)	()
+#endif /* !defined __STDC__ */
 #endif /* !defined P */
 
 extern char **	environ;
 extern int	getopt P((int argc, char * const argv[],
-			const char * options));
+			  const char * options));
 extern char *	optarg;
 extern int	optind;
 extern char *	tzname[2];
 
-static time_t	absolute_min_time;
-static time_t	absolute_max_time;
-static size_t	longest;
-static char *	progname;
-static int	warned;
-
 static char *	abbr P((struct tm * tmp));
-static void	abbrok P((const char * abbrp, const char * zone));
 static long	delta P((struct tm * newp, struct tm * oldp));
-static void	dumptime P((const struct tm * tmp));
 static time_t	hunt P((char * name, time_t lot, time_t	hit));
-static void	setabsolutes P((void));
+static size_t	longest;
+static char *	progname;
 static void	show P((char * zone, time_t t, int v));
-static const char *	tformat P((void));
-static time_t	yeartot P((long y));
-
-#ifndef TYPECHECK
-#define my_localtime	localtime
-#else /* !defined TYPECHECK */
-static struct tm *
-my_localtime(tp)
-time_t *	tp;
-{
-	register struct tm *	tmp;
-
-	tmp = localtime(tp);
-	if (tp != NULL && tmp != NULL) {
-		struct tm	tm;
-		register time_t	t;
-
-		tm = *tmp;
-		t = mktime(&tm);
-		if (t - *tp >= 1 || *tp - t >= 1) {
-			(void) fflush(stdout);
-			(void) fprintf(stderr, "\n%s: ", progname);
-			(void) fprintf(stderr, tformat(), *tp);
-			(void) fprintf(stderr, " ->");
-			(void) fprintf(stderr, " year=%d", tmp->tm_year);
-			(void) fprintf(stderr, " mon=%d", tmp->tm_mon);
-			(void) fprintf(stderr, " mday=%d", tmp->tm_mday);
-			(void) fprintf(stderr, " hour=%d", tmp->tm_hour);
-			(void) fprintf(stderr, " min=%d", tmp->tm_min);
-			(void) fprintf(stderr, " sec=%d", tmp->tm_sec);
-			(void) fprintf(stderr, " isdst=%d", tmp->tm_isdst);
-			(void) fprintf(stderr, " -> ");
-			(void) fprintf(stderr, tformat(), t);
-			(void) fprintf(stderr, "\n");
-		}
-	}
-	return tmp;
-}
-#endif /* !defined TYPECHECK */
-
-static void
-abbrok(abbrp, zone)
-const char * const	abbrp;
-const char * const	zone;
-{
-	register const char *	cp;
-	register char *		wp;
-
-	if (warned)
-		return;
-	cp = abbrp;
-	wp = NULL;
-	while (isascii((unsigned char) *cp) && isalpha((unsigned char) *cp))
-		++cp;
-	if (cp - abbrp == 0)
-		wp = _("lacks alphabetic at start");
-	else if (cp - abbrp < 3)
-		wp = _("has fewer than 3 alphabetics");
-	else if (cp - abbrp > 6)
-		wp = _("has more than 6 alphabetics");
-	if (wp == NULL && (*cp == '+' || *cp == '-')) {
-		++cp;
-		if (isascii((unsigned char) *cp) &&
-			isdigit((unsigned char) *cp))
-				if (*cp++ == '1' && *cp >= '0' && *cp <= '4')
-					++cp;
-		if (*cp != '\0')
-			wp = _("differs from POSIX standard");
-	}
-	if (wp == NULL)
-		return;
-	(void) fflush(stdout);
-	(void) fprintf(stderr,
-		_("%s: warning: zone \"%s\" abbreviation \"%s\" %s\n"),
-		progname, zone, abbrp, wp);
-	warned = TRUE;
-}
+static void	dumptime P((const struct tm * tmp));
 
 int
 main(argc, argv)
@@ -239,24 +136,20 @@ char *	argv[];
 	register int		i;
 	register int		c;
 	register int		vflag;
-	register char *		cutarg;
-	register long		cutloyear = ZDUMP_LO_YEAR;
-	register long		cuthiyear = ZDUMP_HI_YEAR;
-	register time_t		cutlotime;
-	register time_t		cuthitime;
-	register char **	fakeenv;
+	register char *		cutoff;
+	register int		cutyear;
+	register long		cuttime;
+	char **			fakeenv;
 	time_t			now;
 	time_t			t;
 	time_t			newt;
+	time_t			hibit;
 	struct tm		tm;
 	struct tm		newtm;
-	register struct tm *	tmp;
-	register struct tm *	newtmp;
 
-	INITIALIZE(cutlotime);
-	INITIALIZE(cuthitime);
+	INITIALIZE(cuttime);
 #if HAVE_GETTEXT
-	(void) setlocale(LC_ALL, "");
+	(void) setlocale(LC_MESSAGES, "");
 #ifdef TZ_DOMAINDIR
 	(void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
 #endif /* defined TEXTDOMAINDIR */
@@ -266,60 +159,49 @@ char *	argv[];
 	for (i = 1; i < argc; ++i)
 		if (strcmp(argv[i], "--version") == 0) {
 			(void) printf("%s\n", elsieid);
-			exit(EXIT_SUCCESS);
+			(void) exit(EXIT_SUCCESS);
 		}
 	vflag = 0;
-	cutarg = NULL;
+	cutoff = NULL;
 	while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v')
 		if (c == 'v')
 			vflag = 1;
-		else	cutarg = optarg;
+		else	cutoff = optarg;
 	if ((c != EOF && c != -1) ||
 		(optind == argc - 1 && strcmp(argv[optind], "=") == 0)) {
 			(void) fprintf(stderr,
-_("%s: usage is %s [ --version ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n"),
-				progname, progname);
-			exit(EXIT_FAILURE);
+_("%s: usage is %s [ --version ] [ -v ] [ -c cutoff ] zonename ...\n"),
+				argv[0], argv[0]);
+			(void) exit(EXIT_FAILURE);
 	}
-	if (vflag) {
-		if (cutarg != NULL) {
-			long	lo;
-			long	hi;
-			char	dummy;
-
-			if (sscanf(cutarg, "%ld%c", &hi, &dummy) == 1) {
-				cuthiyear = hi;
-			} else if (sscanf(cutarg, "%ld,%ld%c",
-				&lo, &hi, &dummy) == 2) {
-					cutloyear = lo;
-					cuthiyear = hi;
-			} else {
-(void) fprintf(stderr, _("%s: wild -c argument %s\n"),
-					progname, cutarg);
-				exit(EXIT_FAILURE);
-			}
-		}
-		setabsolutes();
-		cutlotime = yeartot(cutloyear);
-		cuthitime = yeartot(cuthiyear);
+	if (cutoff != NULL) {
+		int	y;
+
+		cutyear = atoi(cutoff);
+		cuttime = 0;
+		for (y = EPOCH_YEAR; y < cutyear; ++y)
+			cuttime += DAYSPERNYEAR + isleap(y);
+		cuttime *= SECSPERHOUR * HOURSPERDAY;
 	}
 	(void) time(&now);
 	longest = 0;
 	for (i = optind; i < argc; ++i)
 		if (strlen(argv[i]) > longest)
 			longest = strlen(argv[i]);
+	for (hibit = 1; (hibit << 1) != 0; hibit <<= 1)
+		continue;
 	{
 		register int	from;
 		register int	to;
 
-		for (i = 0; environ[i] != NULL; ++i)
+		for (i = 0;  environ[i] != NULL;  ++i)
 			continue;
 		fakeenv = (char **) malloc((size_t) ((i + 2) *
 			sizeof *fakeenv));
 		if (fakeenv == NULL ||
 			(fakeenv[0] = (char *) malloc(longest + 4)) == NULL) {
 					(void) perror(progname);
-					exit(EXIT_FAILURE);
+					(void) exit(EXIT_FAILURE);
 		}
 		to = 0;
 		(void) strcpy(fakeenv[to++], "TZ=");
@@ -337,175 +219,85 @@ _("%s: usage is %s [ --version ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n"),
 			show(argv[i], now, FALSE);
 			continue;
 		}
-		warned = FALSE;
-		t = absolute_min_time;
+		/*
+		** Get lowest value of t.
+		*/
+		t = hibit;
+		if (t > 0)		/* time_t is unsigned */
+			t = 0;
 		show(argv[i], t, TRUE);
 		t += SECSPERHOUR * HOURSPERDAY;
 		show(argv[i], t, TRUE);
-		if (t < cutlotime)
-			t = cutlotime;
-		tmp = my_localtime(&t);
-		if (tmp != NULL) {
-			tm = *tmp;
-			(void) strncpy(buf, abbr(&tm), (sizeof buf) - 1);
-		}
+		tm = *localtime(&t);
+		(void) strncpy(buf, abbr(&tm), (sizeof buf) - 1);
 		for ( ; ; ) {
-			if (t >= cuthitime)
+			if (cutoff != NULL && t >= cuttime)
 				break;
 			newt = t + SECSPERHOUR * 12;
-			if (newt >= cuthitime)
+			if (cutoff != NULL && newt >= cuttime)
 				break;
 			if (newt <= t)
 				break;
-			newtmp = localtime(&newt);
-			if (newtmp != NULL)
-				newtm = *newtmp;
-			if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) :
-				(delta(&newtm, &tm) != (newt - t) ||
+			newtm = *localtime(&newt);
+			if (delta(&newtm, &tm) != (newt - t) ||
 				newtm.tm_isdst != tm.tm_isdst ||
-				strcmp(abbr(&newtm), buf) != 0)) {
+				strcmp(abbr(&newtm), buf) != 0) {
 					newt = hunt(argv[i], t, newt);
-					newtmp = localtime(&newt);
-					if (newtmp != NULL) {
-						newtm = *newtmp;
-						(void) strncpy(buf,
-							abbr(&newtm),
-							(sizeof buf) - 1);
-					}
+					newtm = *localtime(&newt);
+					(void) strncpy(buf, abbr(&newtm),
+						(sizeof buf) - 1);
 			}
 			t = newt;
 			tm = newtm;
-			tmp = newtmp;
 		}
-		t = absolute_max_time;
+		/*
+		** Get highest value of t.
+		*/
+		t = ~((time_t) 0);
+		if (t < 0)		/* time_t is signed */
+			t &= ~hibit;
 		t -= SECSPERHOUR * HOURSPERDAY;
 		show(argv[i], t, TRUE);
 		t += SECSPERHOUR * HOURSPERDAY;
 		show(argv[i], t, TRUE);
 	}
 	if (fflush(stdout) || ferror(stdout)) {
-		(void) fprintf(stderr, "%s: ", progname);
-		(void) perror(_("Error writing to standard output"));
-		exit(EXIT_FAILURE);
+		(void) fprintf(stderr, "%s: ", argv[0]);
+		(void) perror(_("Error writing standard output"));
+		(void) exit(EXIT_FAILURE);
 	}
 	exit(EXIT_SUCCESS);
-	/* If exit fails to exit... */
-	return EXIT_FAILURE;
-}
-
-static void
-setabsolutes()
-{
-	if (0.5 == (time_t) 0.5) {
-		/*
-		** time_t is floating.
-		*/
-		if (sizeof (time_t) == sizeof (float)) {
-			absolute_min_time = (time_t) -FLT_MAX;
-			absolute_max_time = (time_t) FLT_MAX;
-		} else if (sizeof (time_t) == sizeof (double)) {
-			absolute_min_time = (time_t) -DBL_MAX;
-			absolute_max_time = (time_t) DBL_MAX;
-		} else {
-			(void) fprintf(stderr,
-_("%s: use of -v on system with floating time_t other than float or double\n"),
-				progname);
-			exit(EXIT_FAILURE);
-		}
-	} else if (0 > (time_t) -1) {
-		/*
-		** time_t is signed.  Assume overflow wraps around.
-		*/
-		time_t t = 0;
-		time_t t1 = 1;
-
-		while (t < t1) {
-			t = t1;
-			t1 = 2 * t1 + 1;
-		}
-		  
-		absolute_max_time = t;
-		t = -t;
-		absolute_min_time = t - 1;
-		if (t < absolute_min_time)
-			absolute_min_time = t;
-	} else {
-		/*
-		** time_t is unsigned.
-		*/
-		absolute_min_time = 0;
-		absolute_max_time = absolute_min_time - 1;
-	}
-}
 
-static time_t
-yeartot(y)
-const long	y;
-{
-	register long	myy;
-	register long	seconds;
-	register time_t	t;
-
-	myy = EPOCH_YEAR;
-	t = 0;
-	while (myy != y) {
-		if (myy < y) {
-			seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR;
-			++myy;
-			if (t > absolute_max_time - seconds) {
-				t = absolute_max_time;
-				break;
-			}
-			t += seconds;
-		} else {
-			--myy;
-			seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR;
-			if (t < absolute_min_time + seconds) {
-				t = absolute_min_time;
-				break;
-			}
-			t -= seconds;
-		}
-	}
-	return t;
+	/* gcc -Wall pacifier */
+	for ( ; ; )
+		continue;
 }
 
 static time_t
-hunt(char *name, time_t lot, time_t hit)
+hunt(name, lot, hit)
+char *	name;
+time_t	lot;
+time_t	hit;
 {
-	time_t			t;
-	long			diff;
-	struct tm		lotm;
-	register struct tm *	lotmp;
-	struct tm		tm;
-	register struct tm *	tmp;
-	char			loab[MAX_STRING_LENGTH];
-
-	lotmp = my_localtime(&lot);
-	if (lotmp != NULL) {
-		lotm = *lotmp;
-		(void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1);
-	}
-	for ( ; ; ) {
-		diff = (long) (hit - lot);
-		if (diff < 2)
-			break;
-		t = lot;
-		t += diff / 2;
+	time_t		t;
+	struct tm	lotm;
+	struct tm	tm;
+	static char	loab[MAX_STRING_LENGTH];
+
+	lotm = *localtime(&lot);
+	(void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1);
+	while ((hit - lot) >= 2) {
+		t = lot / 2 + hit / 2;
 		if (t <= lot)
 			++t;
 		else if (t >= hit)
 			--t;
-		tmp = my_localtime(&t);
-		if (tmp != NULL)
-			tm = *tmp;
-		if ((lotmp == NULL || tmp == NULL) ? (lotmp == tmp) :
-			(delta(&tm, &lotm) == (t - lot) &&
+		tm = *localtime(&t);
+		if (delta(&tm, &lotm) == (t - lot) &&
 			tm.tm_isdst == lotm.tm_isdst &&
-			strcmp(abbr(&tm), loab) == 0)) {
+			strcmp(abbr(&tm), loab) == 0) {
 				lot = t;
 				lotm = tm;
-				lotmp = tmp;
 		} else	hit = t;
 	}
 	show(name, lot, TRUE);
@@ -514,7 +306,7 @@ hunt(char *name, time_t lot, time_t hit)
 }
 
 /*
-** Thanks to Paul Eggert for logic used in delta.
+** Thanks to Paul Eggert (eggert@twinsun.com) for logic used in delta.
 */
 
 static long
@@ -522,14 +314,14 @@ delta(newp, oldp)
 struct tm *	newp;
 struct tm *	oldp;
 {
-	register long	result;
-	register int	tmy;
+	long	result;
+	int	tmy;
 
 	if (newp->tm_year < oldp->tm_year)
 		return -delta(oldp, newp);
 	result = 0;
 	for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy)
-		result += DAYSPERNYEAR + isleap_sum(tmy, TM_YEAR_BASE);
+		result += DAYSPERNYEAR + isleap(tmy + (long) TM_YEAR_BASE);
 	result += newp->tm_yday - oldp->tm_yday;
 	result *= HOURSPERDAY;
 	result += newp->tm_hour - oldp->tm_hour;
@@ -541,36 +333,29 @@ struct tm *	oldp;
 }
 
 static void
-show(char *zone, time_t t, int v)
+show(zone, t, v)
+char *	zone;
+time_t	t;
+int	v;
 {
-	register struct tm *	tmp;
+	struct tm *	tmp;
 
 	(void) printf("%-*s  ", (int) longest, zone);
 	if (v) {
-		tmp = gmtime(&t);
-		if (tmp == NULL) {
-			(void) printf(tformat(), t);
-		} else {
-			dumptime(tmp);
-			(void) printf(" UTC");
-		}
-		(void) printf(" = ");
+		dumptime(gmtime(&t));
+		(void) printf(" UTC = ");
 	}
-	tmp = my_localtime(&t);
+	tmp = localtime(&t);
 	dumptime(tmp);
-	if (tmp != NULL) {
-		if (*abbr(tmp) != '\0')
-			(void) printf(" %s", abbr(tmp));
-		if (v) {
-			(void) printf(" isdst=%d", tmp->tm_isdst);
+	if (*abbr(tmp) != '\0')
+		(void) printf(" %s", abbr(tmp));
+	if (v) {
+		(void) printf(" isdst=%d", tmp->tm_isdst);
 #ifdef TM_GMTOFF
-			(void) printf(" gmtoff=%ld", tmp->TM_GMTOFF);
+		(void) printf(" gmtoff=%ld", tmp->TM_GMTOFF);
 #endif /* defined TM_GMTOFF */
-		}
 	}
 	(void) printf("\n");
-	if (tmp != NULL && *abbr(tmp) != '\0')
-		abbrok(abbr(tmp), zone);
 }
 
 static char *
@@ -586,33 +371,6 @@ struct tm *	tmp;
 	return (result == NULL) ? &nada : result;
 }
 
-/*
-** The code below can fail on certain theoretical systems;
-** it works on all known real-world systems as of 2004-12-30.
-*/
-
-static const char *
-tformat()
-{
-	if (0.5 == (time_t) 0.5) {	/* floating */
-		if (sizeof (time_t) > sizeof (double))
-			return "%Lg";
-		return "%g";
-	}
-	if (0 > (time_t) -1) {		/* signed */
-		if (sizeof (time_t) > sizeof (long))
-			return "%lld";
-		if (sizeof (time_t) > sizeof (int))
-			return "%ld";
-		return "%d";
-	}
-	if (sizeof (time_t) > sizeof (unsigned long))
-		return "%llu";
-	if (sizeof (time_t) > sizeof (unsigned int))
-		return "%lu";
-	return "%u";
-}
-
 static void
 dumptime(timeptr)
 register const struct tm *	timeptr;
@@ -626,13 +384,7 @@ register const struct tm *	timeptr;
 	};
 	register const char *	wn;
 	register const char *	mn;
-	register int		lead;
-	register int		trail;
 
-	if (timeptr == NULL) {
-		(void) printf("NULL");
-		return;
-	}
 	/*
 	** The packaged versions of localtime and gmtime never put out-of-range
 	** values in tm_wday or tm_mon, but since this code might be compiled
@@ -646,23 +398,9 @@ register const struct tm *	timeptr;
 		(int) (sizeof mon_name / sizeof mon_name[0]))
 			mn = "???";
 	else		mn = mon_name[timeptr->tm_mon];
-	(void) printf("%.3s %.3s%3d %.2d:%.2d:%.2d ",
+	(void) printf("%.3s %.3s%3d %.2d:%.2d:%.2d %ld",
 		wn, mn,
 		timeptr->tm_mday, timeptr->tm_hour,
-		timeptr->tm_min, timeptr->tm_sec);
-#define DIVISOR	10
-	trail = timeptr->tm_year % DIVISOR + TM_YEAR_BASE % DIVISOR;
-	lead = timeptr->tm_year / DIVISOR + TM_YEAR_BASE / DIVISOR +
-		trail / DIVISOR;
-	trail %= DIVISOR;
-	if (trail < 0 && lead > 0) {
-		trail += DIVISOR;
-		--lead;
-	} else if (lead < 0 && trail > 0) {
-		trail -= DIVISOR;
-		++lead;
-	}
-	if (lead == 0)
-		(void) printf("%d", trail);
-	else	(void) printf("%d%d", lead, ((trail < 0) ? -trail : trail));
+		timeptr->tm_min, timeptr->tm_sec,
+		timeptr->tm_year + (long) TM_YEAR_BASE);
 }