summaryrefslogtreecommitdiff
path: root/elsie.nci.nih.gov/src
diff options
context:
space:
mode:
Diffstat (limited to 'elsie.nci.nih.gov/src')
-rw-r--r--elsie.nci.nih.gov/src/Makefile12
-rw-r--r--elsie.nci.nih.gov/src/date.c22
-rw-r--r--elsie.nci.nih.gov/src/difftime.c98
-rw-r--r--elsie.nci.nih.gov/src/europe11
-rw-r--r--elsie.nci.nih.gov/src/localtime.c46
-rw-r--r--elsie.nci.nih.gov/src/newstrftime.32
-rw-r--r--elsie.nci.nih.gov/src/northamerica14
-rw-r--r--elsie.nci.nih.gov/src/private.h13
-rw-r--r--elsie.nci.nih.gov/src/southamerica4
-rwxr-xr-xelsie.nci.nih.gov/src/tzselect308
-rw-r--r--elsie.nci.nih.gov/src/workman.sh29
-rw-r--r--elsie.nci.nih.gov/src/zdump.820
-rw-r--r--elsie.nci.nih.gov/src/zdump.8.txt20
-rw-r--r--elsie.nci.nih.gov/src/zdump.c278
-rw-r--r--elsie.nci.nih.gov/src/zic.c85
15 files changed, 762 insertions, 200 deletions
diff --git a/elsie.nci.nih.gov/src/Makefile b/elsie.nci.nih.gov/src/Makefile
index 86f9769..14fc5f7 100644
--- a/elsie.nci.nih.gov/src/Makefile
+++ b/elsie.nci.nih.gov/src/Makefile
@@ -1,4 +1,4 @@
-# @(#)Makefile 7.98
+# @(#)Makefile 7.102
# Change the line below for your time zone (after finding the zone you want in
# the time zone files, or adding it to a time zone file).
@@ -91,7 +91,6 @@ LDLIBS=
# -DHAVE_GETTEXT=1 if `gettext' works (GNU, Linux, Solaris); also see LDLIBS
# -DHAVE_INCOMPATIBLE_CTIME_R=1 if your system's time.h declares
# ctime_r and asctime_r incompatibly with the POSIX standard (Solaris 8).
-# -DHAVE_LONG_DOUBLE=1 if your compiler supports the `long double' type
# -DHAVE_SETTIMEOFDAY=0 if settimeofday does not exist (SVR0?)
# -DHAVE_SETTIMEOFDAY=1 if settimeofday has just 1 arg (SVR4)
# -DHAVE_SETTIMEOFDAY=2 if settimeofday uses 2nd arg (4.3BSD)
@@ -395,6 +394,15 @@ public: $(ENCHILADA) zic
tar cf - $(DOCS) $(SOURCES) $(MISC) *.[1-8].txt | gzip -9 > tzcode.tar.gz
tar cf - $(DATA) | gzip -9 > tzdata.tar.gz
+typecheck:
+ make clean
+ for i in "long long" double unsigned; \
+ do \
+ make CFLAGS="-D_TIME_T \"-Dtime_t=$$i\"" ; \
+ ./zdump -v US/Eastern ; \
+ make clean ; \
+ done
+
zonenames: $(TDATA)
@$(AWK) '/^Zone/ { print $$2 } /^Link/ { print $$3 }' $(TDATA)
diff --git a/elsie.nci.nih.gov/src/date.c b/elsie.nci.nih.gov/src/date.c
index e34eaa5..0113887 100644
--- a/elsie.nci.nih.gov/src/date.c
+++ b/elsie.nci.nih.gov/src/date.c
@@ -1,6 +1,6 @@
#ifndef lint
#ifndef NOID
-static char elsieid[] = "@(#)date.c 7.38";
+static char elsieid[] = "@(#)date.c 7.40";
/*
** Modified from the UCB version with the SCCS ID appearing below.
*/
@@ -116,14 +116,15 @@ char * argv[];
INITIALIZE(dsttime);
INITIALIZE(adjust);
INITIALIZE(t);
-#if HAVE_GETTEXT - 0
- (void) setlocale(LC_MESSAGES, "");
+#ifdef LC_ALL
+ (void) setlocale(LC_ALL, "");
+#endif /* defined(LC_ALL) */
+#if HAVE_GETTEXT
#ifdef TZ_DOMAINDIR
(void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
#endif /* defined(TEXTDOMAINDIR) */
(void) textdomain(TZ_DOMAIN);
-#endif /* HAVE_GETTEXT - 0 */
- (void) setlocale(LC_TIME, "");
+#endif /* HAVE_GETTEXT */
(void) time(&now);
format = value = NULL;
while ((ch = getopt(argc, argv, "ucnd:t:a:")) != EOF && ch != -1) {
@@ -630,8 +631,15 @@ const time_t t;
time_t outt;
tm = *localtime(&t);
- cent = (tm.tm_year + TM_YEAR_BASE) / 100;
- year_in_cent = (tm.tm_year + TM_YEAR_BASE) - cent * 100;
+#define DIVISOR 100
+ year_in_cent = tm.tm_year % DIVISOR + TM_YEAR_BASE % DIVISOR;
+ cent = tm.tm_year / DIVISOR + TM_YEAR_BASE / DIVISOR +
+ year_in_cent / DIVISOR;
+ year_in_cent %= DIVISOR;
+ if (year_in_cent < 0) {
+ year_in_cent += DIVISOR;
+ --cent;
+ }
month = tm.tm_mon + 1;
day = tm.tm_mday;
hour = tm.tm_hour;
diff --git a/elsie.nci.nih.gov/src/difftime.c b/elsie.nci.nih.gov/src/difftime.c
index 1d1519e..0be1b1c 100644
--- a/elsie.nci.nih.gov/src/difftime.c
+++ b/elsie.nci.nih.gov/src/difftime.c
@@ -1,83 +1,65 @@
/*
** This file is in the public domain, so clarified as of
-** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
+** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
*/
#ifndef lint
#ifndef NOID
-static char elsieid[] = "@(#)difftime.c 7.9";
+static char elsieid[] = "@(#)difftime.c 7.17";
#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 */
+#include "private.h" /* for time_t, TYPE_INTEGRAL, and TYPE_SIGNED */
double
difftime(time1, time0)
const time_t time1;
const time_t time0;
{
- time_t delta;
- time_t hibit;
-
- {
- time_t tt;
- double d;
- long_double ld;
-
- if (sizeof tt < sizeof d)
- return (double) time1 - (double) time0;
- if (sizeof tt < sizeof ld)
- return (long_double) time1 - (long_double) time0;
+ /*
+ ** If (sizeof (double) > sizeof (time_t)) simply convert and subtract
+ ** (assuming that the larger type has more precision).
+ ** This is the common real-world case circa 2004.
+ */
+ if (sizeof (double) > sizeof (time_t))
+ return (double) time1 - (double) time0;
+ if (!TYPE_INTEGRAL(time_t)) {
+ /*
+ ** time_t is floating.
+ */
+ return time1 - time0;
+ }
+ if (!TYPE_SIGNED(time_t)) {
+ /*
+ ** time_t is integral and unsigned.
+ ** The difference of two unsigned values can't overflow
+ ** if the minuend is greater than or equal to the subtrahend.
+ */
+ if (time1 >= time0)
+ return time1 - time0;
+ else return -((double) (time0 - time1));
}
- if (time1 < time0)
- return -difftime(time0, time1);
/*
- ** As much as possible, avoid loss of precision
- ** by computing the difference before converting to double.
+ ** time_t is integral and signed.
+ ** Handle cases where both time1 and time0 have the same sign
+ ** (meaning that their difference cannot overflow).
*/
- delta = time1 - time0;
- if (delta >= 0)
- return delta;
+ if ((time1 < 0) == (time0 < 0))
+ return time1 - time0;
/*
- ** Repair delta overflow.
+ ** time1 and time0 have opposite signs.
+ ** Punt if unsigned long is too narrow.
*/
- hibit = (~ (time_t) 0) << (TYPE_BIT(time_t) - 1);
+ if (sizeof (unsigned long) < sizeof (time_t))
+ return (double) time1 - (double) time0;
/*
- ** 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.
+ ** Stay calm...decent optimizers will eliminate the complexity below.
*/
- return delta - 2 * (long_double) hibit;
+ if (time1 >= 0 /* && time0 < 0 */)
+ return (unsigned long) time1 +
+ (unsigned long) (-(time0 + 1)) + 1;
+ return -(double) ((unsigned long) time0 +
+ (unsigned long) (-(time1 + 1)) + 1);
}
diff --git a/elsie.nci.nih.gov/src/europe b/elsie.nci.nih.gov/src/europe
index eeb114f..04546c7 100644
--- a/elsie.nci.nih.gov/src/europe
+++ b/elsie.nci.nih.gov/src/europe
@@ -1,4 +1,4 @@
-# @(#)europe 7.88
+# @(#)europe 7.90
# This data is by no means authoritative; if you think you know better,
# go ahead and edit the file (and please send any changes to
@@ -708,7 +708,7 @@ Zone Europe/Sofia 1:33:16 - LMT 1880
# see Serbia and Montenegro
# Cyprus
-# See the `asia' file.
+# Please see the `asia' file for Asia/Nicosia.
# Czech Republic
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
@@ -1055,6 +1055,11 @@ Zone Europe/Berlin 0:53:28 - LMT 1893 Apr
1:00 Germany CE%sT 1980
1:00 EU CE%sT
+# Georgia
+# Please see the "asia" file for Asia/Tbilisi.
+# Herodotus (Histories, IV.45) says Georgia north of the Phasis (now Rioni)
+# is in Europe. Our reference location Tbilisi is in the Asian part.
+
# Gibraltar
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Europe/Gibraltar -0:21:24 - LMT 1880 Aug 2
@@ -1611,7 +1616,7 @@ Zone Europe/Oslo 0:43:00 - LMT 1895 Jan 1
# From Paul Eggert (2001-05-01):
#
# Actually, Jan Mayen was never occupied by Germany during World War II,
-# so it must have diverged from Oslo time during the war, as Olso was
+# so it must have diverged from Oslo time during the war, as Oslo was
# keeping Berlin time.
#
# <http://home.no.net/janmayen/history.htm> says that the meteorologists
diff --git a/elsie.nci.nih.gov/src/localtime.c b/elsie.nci.nih.gov/src/localtime.c
index 8cdcd80..6cc1b22 100644
--- a/elsie.nci.nih.gov/src/localtime.c
+++ b/elsie.nci.nih.gov/src/localtime.c
@@ -1,11 +1,17 @@
/*
+** XXX--do the right thing if time_t is double and
+** the value fed to gmtime or localtime is very very negative or
+** very very positive (which causes problems with the days-and-rem logic).
+*/
+
+/*
** This file is in the public domain, so clarified as of
** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
*/
#ifndef lint
#ifndef NOID
-static char elsieid[] = "@(#)localtime.c 7.80";
+static char elsieid[] = "@(#)localtime.c 7.83";
#endif /* !defined NOID */
#endif /* !defined lint */
@@ -409,6 +415,33 @@ register struct state * const sp;
return -1;
}
}
+ /*
+ ** Out-of-sort ats should mean we're running on a
+ ** signed time_t system but using a data file with
+ ** unsigned values (or vice versa).
+ */
+ for (i = 0; i < sp->timecnt - 2; ++i)
+ if (sp->ats[i] > sp->ats[i + 1]) {
+ ++i;
+ if (TYPE_SIGNED(time_t)) {
+ /*
+ ** Ignore the end (easy).
+ */
+ sp->timecnt = i;
+ } else {
+ /*
+ ** Ignore the beginning (harder).
+ */
+ register int j;
+
+ for (j = 0; j + i < sp->timecnt; ++j) {
+ sp->ats[j] = sp->ats[j + i];
+ sp->types[j] = sp->types[j + i];
+ }
+ sp->timecnt = j;
+ }
+ break;
+ }
}
return 0;
}
@@ -1188,7 +1221,7 @@ register struct tm * const tmp;
}
}
days = *timep / SECSPERDAY;
- rem = *timep % SECSPERDAY;
+ rem = *timep - ((time_t) days) * SECSPERDAY;
#ifdef mc68k
if (*timep == 0x80000000) {
/*
@@ -1219,7 +1252,8 @@ register struct tm * const tmp;
if (tmp->tm_wday < 0)
tmp->tm_wday += DAYSPERWEEK;
y = EPOCH_YEAR;
-#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
+#define IPQ(i, p) ((i) / (p) - (((i) % (p)) < 0))
+#define LEAPS_THRU_END_OF(y) (IPQ((y), 4) - IPQ((y), 100) + IPQ((y), 400))
while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
register long newy;
@@ -1450,7 +1484,7 @@ const int do_norm_secs;
** 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);
+ t = TYPE_SIGNED(time_t) ? 0 : (((unsigned long) 1) << bits);
for ( ; ; ) {
(*funcp)(&t, offset, &mytm);
dir = tmcomp(&mytm, &yourtm);
@@ -1460,8 +1494,8 @@ const int do_norm_secs;
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;
+ t -= ((long) 1) << bits;
+ else t += ((long) 1) << bits;
continue;
}
if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
diff --git a/elsie.nci.nih.gov/src/newstrftime.3 b/elsie.nci.nih.gov/src/newstrftime.3
index 8d5f982..61bb57f 100644
--- a/elsie.nci.nih.gov/src/newstrftime.3
+++ b/elsie.nci.nih.gov/src/newstrftime.3
@@ -35,7 +35,7 @@
.\" SUCH DAMAGE.
.\"
.\" from: @(#)strftime.3 5.12 (Berkeley) 6/29/91
-.\" $Id: newstrftime.3,v 1.6 2004/10/25 04:27:18 zenzen Exp $
+.\" $Id: newstrftime.3,v 1.7 2004/12/17 12:39:51 zenzen Exp $
.\"
.TH NEWSTRFTIME 3
.SH NAME
diff --git a/elsie.nci.nih.gov/src/northamerica b/elsie.nci.nih.gov/src/northamerica
index 6e755b0..19b635f 100644
--- a/elsie.nci.nih.gov/src/northamerica
+++ b/elsie.nci.nih.gov/src/northamerica
@@ -1,4 +1,4 @@
-# @(#)northamerica 7.69
+# @(#)northamerica 7.70
# also includes Central America and the Caribbean
# This data is by no means authoritative; if you think you know better,
@@ -1731,6 +1731,15 @@ Zone America/Costa_Rica -5:36:20 - LMT 1890 # San Jose
# to DST--and one more hour on 1999-04-04--when the announcers will have
# returned to Baltimore, which switches on that date.)
+# From Evert van der Veer via Steffen Thorsen (2004-10-28):
+# Cuba is not going back to standard time this year.
+# From Paul Eggert (2004-10-28):
+# http://www.granma.cu/ingles/2004/septiembre/juev30/41medid-i.html
+# says that it's due to a problem at the Antonio Guiteras
+# thermoelectric plant, and says "This October there will be no return
+# to normal hours (after daylight saving time)".
+# For now, let's assume that it's a one-year temporary measure.
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Cuba 1928 only - Jun 10 0:00 1:00 D
Rule Cuba 1928 only - Oct 10 0:00 0 S
@@ -1759,8 +1768,9 @@ Rule Cuba 1991 1995 - Oct Sun>=8 0:00s 0 S
Rule Cuba 1996 only - Oct 6 0:00s 0 S
Rule Cuba 1997 only - Oct 12 0:00s 0 S
Rule Cuba 1998 1999 - Mar lastSun 0:00s 1:00 D
-Rule Cuba 1998 max - Oct lastSun 0:00s 0 S
+Rule Cuba 1998 2003 - Oct lastSun 0:00s 0 S
Rule Cuba 2000 max - Apr Sun>=1 0:00s 1:00 D
+Rule Cuba 2005 max - Oct lastSun 0:00s 0 S
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone America/Havana -5:29:28 - LMT 1890
diff --git a/elsie.nci.nih.gov/src/private.h b/elsie.nci.nih.gov/src/private.h
index 5766305..5de2f7d 100644
--- a/elsie.nci.nih.gov/src/private.h
+++ b/elsie.nci.nih.gov/src/private.h
@@ -21,7 +21,7 @@
#ifndef lint
#ifndef NOID
-static char privatehid[] = "@(#)private.h 7.54";
+static char privatehid[] = "@(#)private.h 7.55";
#endif /* !defined NOID */
#endif /* !defined lint */
@@ -208,6 +208,7 @@ extern char * asctime_r();
/*
** Private function declarations.
*/
+
char * icalloc P((int nelem, int elsize));
char * icatalloc P((char * old, const char * new));
char * icpyalloc P((const char * string));
@@ -217,7 +218,6 @@ void icfree P((char * pointer));
void ifree P((char * pointer));
char * scheck P((const char *string, const char *format));
-
/*
** Finally, some convenience items.
*/
@@ -238,6 +238,15 @@ char * scheck P((const char *string, const char *format));
#define TYPE_SIGNED(type) (((type) -1) < 0)
#endif /* !defined TYPE_SIGNED */
+/*
+** Since the definition of TYPE_INTEGRAL contains floating point numbers,
+** it cannot be used in preprocessor directives.
+*/
+
+#ifndef TYPE_INTEGRAL
+#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5)
+#endif /* !defined TYPE_INTEGRAL */
+
#ifndef INT_STRLEN_MAXIMUM
/*
** 302 / 1000 is log10(2.0) rounded up.
diff --git a/elsie.nci.nih.gov/src/southamerica b/elsie.nci.nih.gov/src/southamerica
index 9124910..eacd182 100644
--- a/elsie.nci.nih.gov/src/southamerica
+++ b/elsie.nci.nih.gov/src/southamerica
@@ -1,4 +1,4 @@
-# @(#)southamerica 7.54
+# @(#)southamerica 7.55
# This data is by no means authoritative; if you think you know better,
# go ahead and edit the file (and please send any changes to
@@ -671,7 +671,7 @@ Zone America/Campo_Grande -3:38:28 - LMT 1914
# Mato Grosso (MT)
Zone America/Cuiaba -3:44:20 - LMT 1914
-4:00 Brazil AM%sT 2003 Sep 24
- -4:00 - AMT 2004 Oct 4
+ -4:00 - AMT 2004 Oct 1
-4:00 Brazil AM%sT
#
# west Para (PA), Rondonia (RO)
diff --git a/elsie.nci.nih.gov/src/tzselect b/elsie.nci.nih.gov/src/tzselect
new file mode 100755
index 0000000..9111742
--- /dev/null
+++ b/elsie.nci.nih.gov/src/tzselect
@@ -0,0 +1,308 @@
+#! /bin/ksh
+
+# '@(#)tzselect.ksh 1.7'
+
+# Ask the user about the time zone, and output the resulting TZ value to stdout.
+# Interact with the user via stderr and stdin.
+
+# Contributed by Paul Eggert <eggert@twinsun.com>.
+
+# Porting notes:
+#
+# This script requires several features of the Korn shell.
+# If your host lacks the Korn shell,
+# you can use either of the following free programs instead:
+#
+# <a href=ftp://ftp.gnu.org/pub/gnu/>
+# Bourne-Again shell (bash)
+# </a>
+#
+# <a href=ftp://ftp.cs.mun.ca/pub/pdksh/pdksh.tar.gz>
+# Public domain ksh
+# </a>
+#
+# This script also uses several features of modern awk programs.
+# If your host lacks awk, or has an old awk that does not conform to Posix.2,
+# you can use either of the following free programs instead:
+#
+# <a href=ftp://ftp.gnu.org/pub/gnu/>
+# GNU awk (gawk)
+# </a>
+#
+# <a href=ftp://ftp.whidbey.net/pub/brennan/>
+# mawk
+# </a>
+
+
+# Specify default values for environment variables if they are unset.
+: ${AWK=nawk}
+: ${TZDIR=/home/stub/src/pytz/build/etc/zoneinfo}
+
+# Check for awk Posix compliance.
+($AWK -v x=y 'BEGIN { exit 123 }') </dev/null >/dev/null 2>&1
+[ $? = 123 ] || {
+ echo >&2 "$0: Sorry, your \`$AWK' program is not Posix compatible."
+ exit 1
+}
+
+# Make sure the tables are readable.
+TZ_COUNTRY_TABLE=$TZDIR/iso3166.tab
+TZ_ZONE_TABLE=$TZDIR/zone.tab
+for f in $TZ_COUNTRY_TABLE $TZ_ZONE_TABLE
+do
+ <$f || {
+ echo >&2 "$0: time zone files are not set up correctly"
+ exit 1
+ }
+done
+
+newline='
+'
+IFS=$newline
+
+
+# Work around a bug in bash 1.14.7 and earlier, where $PS3 is sent to stdout.
+case $(echo 1 | (select x in x; do break; done) 2>/dev/null) in
+?*) PS3=
+esac
+
+
+# Begin the main loop. We come back here if the user wants to retry.
+while
+
+ echo >&2 'Please identify a location' \
+ 'so that time zone rules can be set correctly.'
+
+ continent=
+ country=
+ region=
+
+
+ # Ask the user for continent or ocean.
+
+ echo >&2 'Please select a continent or ocean.'
+
+ select continent in \
+ Africa \
+ Americas \
+ Antarctica \
+ 'Arctic Ocean' \
+ Asia \
+ 'Atlantic Ocean' \
+ Australia \
+ Europe \
+ 'Indian Ocean' \
+ 'Pacific Ocean' \
+ 'none - I want to specify the time zone using the Posix TZ format.'
+ do
+ case $continent in
+ '')
+ echo >&2 'Please enter a number in range.';;
+ ?*)
+ case $continent in
+ Americas) continent=America;;
+ *' '*) continent=$(expr "$continent" : '\([^ ]*\)')
+ esac
+ break
+ esac
+ done
+ case $continent in
+ '')
+ exit 1;;
+ none)
+ # Ask the user for a Posix TZ string. Check that it conforms.
+ while
+ echo >&2 'Please enter the desired value' \
+ 'of the TZ environment variable.'
+ echo >&2 'For example, GST-10 is a zone named GST' \
+ 'that is 10 hours ahead (east) of UTC.'
+ read TZ
+ $AWK -v TZ="$TZ" 'BEGIN {
+ tzname = "[^-+,0-9][^-+,0-9][^-+,0-9]+"
+ time = "[0-2]?[0-9](:[0-5][0-9](:[0-5][0-9])?)?"
+ offset = "[-+]?" time
+ date = "(J?[0-9]+|M[0-9]+\.[0-9]+\.[0-9]+)"
+ datetime = "," date "(/" time ")?"
+ tzpattern = "^(:.*|" tzname offset "(" tzname \
+ "(" offset ")?(" datetime datetime ")?)?)$"
+ if (TZ ~ tzpattern) exit 1
+ exit 0
+ }'
+ do
+ echo >&2 "\`$TZ' is not a conforming" \
+ 'Posix time zone string.'
+ done
+ TZ_for_date=$TZ;;
+ *)
+ # Get list of names of countries in the continent or ocean.
+ countries=$($AWK -F'\t' \
+ -v continent="$continent" \
+ -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
+ '
+ /^#/ { next }
+ $3 ~ ("^" continent "/") {
+ if (!cc_seen[$1]++) cc_list[++ccs] = $1
+ }
+ END {
+ while (getline <TZ_COUNTRY_TABLE) {
+ if ($0 !~ /^#/) cc_name[$1] = $2
+ }
+ for (i = 1; i <= ccs; i++) {
+ country = cc_list[i]
+ if (cc_name[country]) {
+ country = cc_name[country]
+ }
+ print country
+ }
+ }
+ ' <$TZ_ZONE_TABLE | sort -f)
+
+
+ # If there's more than one country, ask the user which one.
+ case $countries in
+ *"$newline"*)
+ echo >&2 'Please select a country.'
+ select country in $countries
+ do
+ case $country in
+ '') echo >&2 'Please enter a number in range.';;
+ ?*) break
+ esac
+ done
+
+ case $country in
+ '') exit 1
+ esac;;
+ *)
+ country=$countries
+ esac
+
+
+ # Get list of names of time zone rule regions in the country.
+ regions=$($AWK -F'\t' \
+ -v country="$country" \
+ -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
+ '
+ BEGIN {
+ cc = country
+ while (getline <TZ_COUNTRY_TABLE) {
+ if ($0 !~ /^#/ && country == $2) {
+ cc = $1
+ break
+ }
+ }
+ }
+ $1 == cc { print $4 }
+ ' <$TZ_ZONE_TABLE)
+
+
+ # If there's more than one region, ask the user which one.
+ case $regions in
+ *"$newline"*)
+ echo >&2 'Please select one of the following' \
+ 'time zone regions.'
+ select region in $regions
+ do
+ case $region in
+ '') echo >&2 'Please enter a number in range.';;
+ ?*) break
+ esac
+ done
+ case $region in
+ '') exit 1
+ esac;;
+ *)
+ region=$regions
+ esac
+
+ # Determine TZ from country and region.
+ TZ=$($AWK -F'\t' \
+ -v country="$country" \
+ -v region="$region" \
+ -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
+ '
+ BEGIN {
+ cc = country
+ while (getline <TZ_COUNTRY_TABLE) {
+ if ($0 !~ /^#/ && country == $2) {
+ cc = $1
+ break
+ }
+ }
+ }
+ $1 == cc && $4 == region { print $3 }
+ ' <$TZ_ZONE_TABLE)
+
+ # Make sure the corresponding zoneinfo file exists.
+ TZ_for_date=$TZDIR/$TZ
+ <$TZ_for_date || {
+ echo >&2 "$0: time zone files are not set up correctly"
+ exit 1
+ }
+ esac
+
+
+ # Use the proposed TZ to output the current date relative to UTC.
+ # Loop until they agree in seconds.
+ # Give up after 8 unsuccessful tries.
+
+ extra_info=
+ for i in 1 2 3 4 5 6 7 8
+ do
+ TZdate=$(LANG=C TZ="$TZ_for_date" date)
+ UTdate=$(LANG=C TZ=UTC0 date)
+ TZsec=$(expr "$TZdate" : '.*:\([0-5][0-9]\)')
+ UTsec=$(expr "$UTdate" : '.*:\([0-5][0-9]\)')
+ case $TZsec in
+ $UTsec)
+ extra_info="
+Local time is now: $TZdate.
+Universal Time is now: $UTdate."
+ break
+ esac
+ done
+
+
+ # Output TZ info and ask the user to confirm.
+
+ echo >&2 ""
+ echo >&2 "The following information has been given:"
+ echo >&2 ""
+ case $country+$region in
+ ?*+?*) echo >&2 " $country$newline $region";;
+ ?*+) echo >&2 " $country";;
+ +) echo >&2 " TZ='$TZ'"
+ esac
+ echo >&2 ""
+ echo >&2 "Therefore TZ='$TZ' will be used.$extra_info"
+ echo >&2 "Is the above information OK?"
+
+ ok=
+ select ok in Yes No
+ do
+ case $ok in
+ '') echo >&2 'Please enter 1 for Yes, or 2 for No.';;
+ ?*) break
+ esac
+ done
+ case $ok in
+ '') exit 1;;
+ Yes) break
+ esac
+do :
+done
+
+case $SHELL in
+*csh) file=.login line="setenv TZ '$TZ'";;
+*) file=.profile line="TZ='$TZ'; export TZ"
+esac
+
+echo >&2 "
+You can make this change permanent for yourself by appending the line
+ $line
+to the file '$file' in your home directory; then log out and log in again.
+
+Here is that TZ value again, this time on standard output so that you
+can use the $0 command in shell scripts:"
+
+echo "$TZ"
diff --git a/elsie.nci.nih.gov/src/workman.sh b/elsie.nci.nih.gov/src/workman.sh
new file mode 100644
index 0000000..57a2893
--- /dev/null
+++ b/elsie.nci.nih.gov/src/workman.sh
@@ -0,0 +1,29 @@
+#! /bin/sh
+
+# @(#)workman.sh 1.7
+
+# Tell groff not to emit SGR escape sequences (ANSI color escapes).
+GROFF_NO_SGR=1
+export GROFF_NO_SGR
+
+echo ".am TH
+.hy 0
+.na
+..
+.rm }H
+.rm }F" | nroff -man - ${1+"$@"} | perl -ne '
+ chomp;
+ s/.\010//g;
+ s/\s*$//;
+ if (/^$/) {
+ $sawblank = 1;
+ next;
+ } else {
+ if ($sawblank && $didprint) {
+ print "\n";
+ $sawblank = 0;
+ }
+ print "$_\n";
+ $didprint = 1;
+ }
+'
diff --git a/elsie.nci.nih.gov/src/zdump.8 b/elsie.nci.nih.gov/src/zdump.8
index dff68c2..b22a129 100644
--- a/elsie.nci.nih.gov/src/zdump.8
+++ b/elsie.nci.nih.gov/src/zdump.8
@@ -10,7 +10,7 @@ zdump \- time zone dumper
.B \-v
] [
.B \-c
-cutoffyear ] [ zonename ... ]
+[loyear,]hiyear ] [ zonename ... ]
.SH DESCRIPTION
.I Zdump
prints the current time in each
@@ -38,8 +38,20 @@ if the given time is Daylight Saving Time or
.B isdst=0
otherwise.
.TP
-.BI "\-c " cutoffyear
-Cut off the verbose output near the start of the given year.
+.BI "\-c " [loyear,]hiyear
+Cut off verbose output near the start of the given year(s).
+By default,
+the program cuts off verbose output near the starts of the years -500 and 2500.
+.SH LIMITATIONS
+The
+.B \-v
+option may not be used on systems with floating-point time_t values
+that are neither float nor double.
+.PP
+Time discontinuities are found by sampling the results returned by localtime
+at twelve-hour intervals.
+This works in all real-world cases;
+one can construct artificial time zones for which this fails.
.SH "SEE ALSO"
newctime(3), tzfile(5), zic(8)
-.\" @(#)zdump.8 7.4
+.\" @(#)zdump.8 7.7
diff --git a/elsie.nci.nih.gov/src/zdump.8.txt b/elsie.nci.nih.gov/src/zdump.8.txt
index 3499d78..78c647f 100644
--- a/elsie.nci.nih.gov/src/zdump.8.txt
+++ b/elsie.nci.nih.gov/src/zdump.8.txt
@@ -3,8 +3,8 @@ NAME
zdump - time zone dumper
SYNOPSIS
- zdump [ --version ] [ -v ] [ -c cutoffyear ] [ zonename ...
- ]
+ zdump [ --version ] [ -v ] [ -c [loyear,]hiyear ] [ zonename
+ ... ]
DESCRIPTION
Zdump prints the current time in each zonename named on the
@@ -25,9 +25,19 @@ DESCRIPTION
isdst=1 if the given time is Daylight Saving Time or
isdst=0 otherwise.
- -c cutoffyear
- Cut off the verbose output near the start of the given
- year.
+ -c [loyear,]hiyear
+ Cut off verbose output near the start of the given
+ year(s). By default, the program cuts off verbose
+ output near the starts of the years -500 and 2500.
+
+LIMITATIONS
+ The -v option may not be used on systems with floating-point
+ time_t values that are neither float nor double.
+
+ Time discontinuities are found by sampling the results
+ returned by localtime at twelve-hour intervals. This works
+ in all real-world cases; one can construct artificial time
+ zones for which this fails.
SEE ALSO
newctime(3), tzfile(5), zic(8)
diff --git a/elsie.nci.nih.gov/src/zdump.c b/elsie.nci.nih.gov/src/zdump.c
index 6e697f3..7142d04 100644
--- a/elsie.nci.nih.gov/src/zdump.c
+++ b/elsie.nci.nih.gov/src/zdump.c
@@ -1,4 +1,4 @@
-static char elsieid[] = "@(#)zdump.c 7.47";
+static char elsieid[] = "@(#)zdump.c 7.57";
/*
** This code has been made independent of the rest of the time
@@ -11,6 +11,15 @@ static char elsieid[] = "@(#)zdump.c 7.47";
#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 */
+
+#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
@@ -71,6 +80,10 @@ static char elsieid[] = "@(#)zdump.c 7.47";
#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"
@@ -122,18 +135,23 @@ static char elsieid[] = "@(#)zdump.c 7.47";
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 char * abbr P((struct tm * tmp));
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 size_t longest;
-static char * progname;
+static void setabsolutes();
static void show P((char * zone, time_t t, int v));
-static void dumptime P((const struct tm * tmp));
+static time_t yeartot P((long y));
int
main(argc, argv)
@@ -143,18 +161,22 @@ char * argv[];
register int i;
register int c;
register int vflag;
- register char * cutoff;
- register int cutyear;
- register long cuttime;
- char ** fakeenv;
+ 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;
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(cuttime);
+ INITIALIZE(cutlotime);
+ INITIALIZE(cuthitime);
#if HAVE_GETTEXT
(void) setlocale(LC_MESSAGES, "");
#ifdef TZ_DOMAINDIR
@@ -169,39 +191,50 @@ char * argv[];
(void) exit(EXIT_SUCCESS);
}
vflag = 0;
- cutoff = NULL;
+ cutarg = NULL;
while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v')
if (c == 'v')
vflag = 1;
- else cutoff = optarg;
+ else cutarg = optarg;
if ((c != EOF && c != -1) ||
(optind == argc - 1 && strcmp(argv[optind], "=") == 0)) {
(void) fprintf(stderr,
-_("%s: usage is %s [ --version ] [ -v ] [ -c cutoff ] zonename ...\n"),
- argv[0], argv[0]);
+_("%s: usage is %s [ --version ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n"),
+ progname, progname);
(void) exit(EXIT_FAILURE);
}
- if (cutoff != NULL) {
- int y;
-
- cutyear = atoi(cutoff);
- cuttime = 0;
- for (y = EPOCH_YEAR; y < cutyear; ++y)
- cuttime += DAYSPERNYEAR + isleap(y);
- cuttime *= SECSPERHOUR * HOURSPERDAY;
+ if (vflag) {
+ if (cutarg != NULL) {
+ long lo;
+ long hi;
+ char c;
+
+ if (sscanf(cutarg, "%ld%c", &hi, &c) == 1) {
+ cuthiyear = hi;
+ } else if (sscanf(cutarg, "%ld,%ld%c",
+ &lo, &hi, &c) == 2) {
+ cutloyear = lo;
+ cuthiyear = hi;
+ } else {
+(void) fprintf(stderr, _("%s: wild -c argument %s\n"),
+ progname, cutarg);
+ (void) exit(EXIT_FAILURE);
+ }
+ }
+ setabsolutes();
+ cutlotime = yeartot(cutloyear);
+ cuthitime = yeartot(cuthiyear);
}
(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));
@@ -226,58 +259,129 @@ _("%s: usage is %s [ --version ] [ -v ] [ -c cutoff ] zonename ...\n"),
show(argv[i], now, FALSE);
continue;
}
- /*
- ** Get lowest value of t.
- */
- t = hibit;
- if (t > 0) /* time_t is unsigned */
- t = 0;
+ t = absolute_min_time;
show(argv[i], t, TRUE);
t += SECSPERHOUR * HOURSPERDAY;
show(argv[i], t, TRUE);
- tm = *localtime(&t);
- (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1);
+ if (t < cutlotime)
+ t = cutlotime;
+ tmp = localtime(&t);
+ if (tmp != NULL) {
+ tm = *tmp;
+ (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1);
+ }
for ( ; ; ) {
- if (cutoff != NULL && t >= cuttime)
+ if (t >= cuthitime)
break;
newt = t + SECSPERHOUR * 12;
- if (cutoff != NULL && newt >= cuttime)
+ if (newt >= cuthitime)
break;
if (newt <= t)
break;
- newtm = *localtime(&newt);
- if (delta(&newtm, &tm) != (newt - t) ||
+ newtmp = localtime(&newt);
+ if (newtmp != NULL)
+ newtm = *newtmp;
+ if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) :
+ (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);
- newtm = *localtime(&newt);
- (void) strncpy(buf, abbr(&newtm),
- (sizeof buf) - 1);
+ newtmp = localtime(&newt);
+ if (newtmp != NULL) {
+ newtm = *newtmp;
+ (void) strncpy(buf,
+ abbr(&newtm),
+ (sizeof buf) - 1);
+ }
}
t = newt;
tm = newtm;
+ tmp = newtmp;
}
- /*
- ** Get highest value of t.
- */
- t = ~((time_t) 0);
- if (t < 0) /* time_t is signed */
- t &= ~hibit;
+ t = absolute_max_time;
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: ", argv[0]);
+ (void) fprintf(stderr, "%s: ", progname);
(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);
+ (void) exit(EXIT_FAILURE);
+ }
+ } else if (0 > (time_t) -1) {
+ /*
+ ** time_t is signed.
+ */
+ register time_t hibit;
- /* gcc -Wall pacifier */
- for ( ; ; )
- continue;
+ for (hibit = 1; (hibit * 2) != 0; hibit *= 2)
+ continue;
+ absolute_min_time = hibit;
+ absolute_max_time = -(hibit + 1);
+ } 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;
}
static time_t
@@ -286,25 +390,39 @@ char * name;
time_t lot;
time_t hit;
{
- 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;
+ 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 = 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;
if (t <= lot)
++t;
else if (t >= hit)
--t;
- tm = *localtime(&t);
- if (delta(&tm, &lotm) == (t - lot) &&
+ tmp = localtime(&t);
+ if (tmp != NULL)
+ tm = *tmp;
+ if ((lotmp == NULL || tmp == NULL) ? (lotmp == tmp) :
+ (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);
@@ -321,8 +439,8 @@ delta(newp, oldp)
struct tm * newp;
struct tm * oldp;
{
- long result;
- int tmy;
+ register long result;
+ register int tmy;
if (newp->tm_year < oldp->tm_year)
return -delta(oldp, newp);
@@ -345,22 +463,30 @@ char * zone;
time_t t;
int v;
{
- struct tm * tmp;
+ register struct tm * tmp;
(void) printf("%-*s ", (int) longest, zone);
if (v) {
- dumptime(gmtime(&t));
- (void) printf(" UTC = ");
+ tmp = gmtime(&t);
+ if (tmp == NULL) {
+ (void) printf("%g", (double) t);
+ } else {
+ dumptime(tmp);
+ (void) printf(" UTC");
+ }
+ (void) printf(" = ");
}
tmp = localtime(&t);
dumptime(tmp);
- if (*abbr(tmp) != '\0')
- (void) printf(" %s", abbr(tmp));
- if (v) {
- (void) printf(" isdst=%d", tmp->tm_isdst);
+ if (tmp != NULL) {
+ 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");
}
@@ -394,6 +520,10 @@ register const struct tm * timeptr;
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
diff --git a/elsie.nci.nih.gov/src/zic.c b/elsie.nci.nih.gov/src/zic.c
index 1a046ff..5a044f6 100644
--- a/elsie.nci.nih.gov/src/zic.c
+++ b/elsie.nci.nih.gov/src/zic.c
@@ -1,4 +1,10 @@
-static char elsieid[] = "@(#)zic.c 7.116";
+static char elsieid[] = "@(#)zic.c 7.118";
+
+/*
+** Regardless of the type of time_t, we do our work using this type.
+*/
+
+typedef int zic_t;
#include "private.h"
#include "locale.h"
@@ -50,7 +56,7 @@ struct rule {
const char * r_abbrvar; /* variable part of abbreviation */
int r_todo; /* a rule to do (used in outzone) */
- time_t r_temp; /* used in outzone */
+ zic_t r_temp; /* used in outzone */
};
/*
@@ -76,7 +82,7 @@ struct zone {
int z_nrules;
struct rule z_untilrule;
- time_t z_untiltime;
+ zic_t z_untiltime;
};
extern int getopt P((int argc, char * const argv[],
@@ -85,10 +91,10 @@ extern int link P((const char * fromname, const char * toname));
extern char * optarg;
extern int optind;
-static void addtt P((time_t starttime, int type));
+static void addtt P((zic_t starttime, int type));
static int addtype P((long gmtoff, const char * abbr, int isdst,
int ttisstd, int ttisgmt));
-static void leapadd P((time_t t, int positive, int rolling, int count));
+static void leapadd P((zic_t t, int positive, int rolling, int count));
static void adjleap P((void));
static void associate P((void));
static int ciequal P((const char * ap, const char * bp));
@@ -121,13 +127,13 @@ static long oadd P((long t1, long t2));
static void outzone P((const struct zone * zp, int ntzones));
static void puttzcode P((long code, FILE * fp));
static int rcomp P((const void * leftp, const void * rightp));
-static time_t rpytime P((const struct rule * rp, int wantedy));
+static zic_t rpytime P((const struct rule * rp, int wantedy));
static void rulesub P((struct rule * rp,
const char * loyearp, const char * hiyearp,
const char * typep, const char * monthp,
const char * dayp, const char * timep));
static void setboundaries P((void));
-static time_t tadd P((time_t t1, long t2));
+static zic_t tadd P((zic_t t1, long t2));
static void usage P((void));
static void writezone P((const char * name));
static int yearistype P((int year, const char * type));
@@ -141,10 +147,10 @@ static int errors;
static const char * filename;
static int leapcnt;
static int linenum;
-static time_t max_time;
+static zic_t max_time;
static int max_year;
static int max_year_representable;
-static time_t min_time;
+static zic_t min_time;
static int min_year;
static int min_year_representable;
static int noise;
@@ -334,7 +340,7 @@ static const int len_years[2] = {
};
static struct attype {
- time_t at;
+ zic_t at;
unsigned char type;
} attypes[TZ_MAX_TIMES];
static long gmtoffs[TZ_MAX_TYPES];
@@ -343,7 +349,7 @@ static unsigned char abbrinds[TZ_MAX_TYPES];
static char ttisstds[TZ_MAX_TYPES];
static char ttisgmts[TZ_MAX_TYPES];
static char chars[TZ_MAX_CHARS];
-static time_t trans[TZ_MAX_LEAPS];
+static zic_t trans[TZ_MAX_LEAPS];
static long corr[TZ_MAX_LEAPS];
static char roll[TZ_MAX_LEAPS];
@@ -665,25 +671,36 @@ warning(_("hard link failed, symbolic link used"));
*/
#define MAX_BITS_IN_FILE 32
-#define TIME_T_BITS_IN_FILE ((TYPE_BIT(time_t) < MAX_BITS_IN_FILE) ? TYPE_BIT(time_t) : MAX_BITS_IN_FILE)
+#define TIME_T_BITS_IN_FILE ((TYPE_BIT(zic_t) < MAX_BITS_IN_FILE) ? \
+ TYPE_BIT(zic_t) : MAX_BITS_IN_FILE)
static void
setboundaries P((void))
{
- if (TYPE_SIGNED(time_t)) {
- min_time = ~ (time_t) 0;
- min_time <<= TIME_T_BITS_IN_FILE - 1;
- max_time = ~ (time_t) 0 - min_time;
+ register int i;
+
+ if (TYPE_SIGNED(zic_t)) {
+ min_time = -1;
+ for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i)
+ min_time *= 2;
+ max_time = -(min_time + 1);
if (sflag)
min_time = 0;
} else {
min_time = 0;
max_time = 2 - sflag;
- max_time <<= TIME_T_BITS_IN_FILE - 1;
+ for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i)
+ max_time *= 2;
--max_time;
}
- min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year;
- max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year;
+ {
+ time_t t;
+
+ t = (time_t) min_time;
+ min_year = TM_YEAR_BASE + gmtime(&t)->tm_year;
+ t = (time_t) max_time;
+ max_year = TM_YEAR_BASE + gmtime(&t)->tm_year;
+ }
min_year_representable = min_year;
max_year_representable = max_year;
}
@@ -1109,7 +1126,7 @@ const int nfields;
register int i, j;
int year, month, day;
long dayoff, tod;
- time_t t;
+ zic_t t;
if (nfields != LEAP_FIELDS) {
error(_("wrong number of fields on Leap line"));
@@ -1153,7 +1170,7 @@ const int nfields;
return;
}
dayoff = oadd(dayoff, eitol(day - 1));
- if (dayoff < 0 && !TYPE_SIGNED(time_t)) {
+ if (dayoff < 0 && !TYPE_SIGNED(zic_t)) {
error(_("time before zero"));
return;
}
@@ -1165,7 +1182,7 @@ const int nfields;
error(_("time too large"));
return;
}
- t = (time_t) dayoff * SECSPERDAY;
+ t = (zic_t) dayoff * SECSPERDAY;
tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE);
cp = fields[LP_CORR];
{
@@ -1427,7 +1444,7 @@ const char * const name;
register int i, j;
static char * fullname;
static struct tzhead tzh;
- time_t ats[TZ_MAX_TIMES];
+ zic_t ats[TZ_MAX_TIMES];
unsigned char types[TZ_MAX_TIMES];
/*
@@ -1592,7 +1609,7 @@ const int zonecount;
register struct rule * rp;
register int i, j;
register int usestart, useuntil;
- register time_t starttime, untiltime;
+ register zic_t starttime, untiltime;
register long gmtoff;
register long stdoff;
register int year;
@@ -1661,7 +1678,7 @@ const int zonecount;
}
for ( ; ; ) {
register int k;
- register time_t jtime, ktime;
+ register zic_t jtime, ktime;
register long offset;
char buf[BUFSIZ];
@@ -1773,7 +1790,7 @@ error(_("can't determine time zone abbreviation to use just after until time"));
static void
addtt(starttime, type)
-const time_t starttime;
+const zic_t starttime;
int type;
{
if (starttime <= min_time ||
@@ -1857,7 +1874,7 @@ const int ttisgmt;
static void
leapadd(t, positive, rolling, count)
-const time_t t;
+const zic_t t;
const int positive;
const int rolling;
int count;
@@ -2045,12 +2062,12 @@ const long t2;
return t;
}
-static time_t
+static zic_t
tadd(t1, t2)
-const time_t t1;
+const zic_t t1;
const long t2;
{
- register time_t t;
+ register zic_t t;
if (t1 == max_time && t2 > 0)
return max_time;
@@ -2069,14 +2086,14 @@ const long t2;
** 1970, 00:00 LOCAL time - in that year that the rule refers to.
*/
-static time_t
+static zic_t
rpytime(rp, wantedy)
register const struct rule * const rp;
register const int wantedy;
{
register int y, m, i;
register long dayoff; /* with a nod to Margaret O. */
- register time_t t;
+ register zic_t t;
if (wantedy == INT_MIN)
return min_time;
@@ -2143,13 +2160,13 @@ register const int wantedy;
warning(_("rule goes past start/end of month--will not work with pre-2004 versions of zic"));
}
}
- if (dayoff < 0 && !TYPE_SIGNED(time_t))
+ if (dayoff < 0 && !TYPE_SIGNED(zic_t))
return min_time;
if (dayoff < min_time / SECSPERDAY)
return min_time;
if (dayoff > max_time / SECSPERDAY)
return max_time;
- t = (time_t) dayoff * SECSPERDAY;
+ t = (zic_t) dayoff * SECSPERDAY;
return tadd(t, rp->r_tod);
}