aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2006-11-11 02:05:42 +0000
committerUlrich Drepper <drepper@redhat.com>2006-11-11 02:05:42 +0000
commit064737fb74ac2a47916b9be162a6a098cde99816 (patch)
treeb1b2838f61216fc8378445bfc8fa291d32ae7b0f
parent6decd24cc22116dea9da17c548d0ea0e9b6d5bfc (diff)
downloadglibc-064737fb74ac2a47916b9be162a6a098cde99816.tar.xz
glibc-064737fb74ac2a47916b9be162a6a098cde99816.zip
* time/tzfile.c (__tzfile_read): Extend to handle new file format
on machines with 64-bit time_t. * timezone/checktab.awk: Update from tzcode2006o. * timezone/ialloc.c: Likewise. * timezone/private.h: Likewise. * timezone/scheck.: Likewise. * timezone/tzfile.h: Likewise. * timezone/tzselect.ksh: Likewise. * timezone/zdump.c: Likewise. * timezone/zic.c: Likewise.
-rw-r--r--ChangeLog12
-rw-r--r--time/tzfile.c112
-rw-r--r--timezone/checktab.awk2
-rw-r--r--timezone/ialloc.c7
-rw-r--r--timezone/private.h83
-rw-r--r--timezone/scheck.c7
-rw-r--r--timezone/tzfile.h23
-rw-r--r--timezone/tzselect.ksh2
-rw-r--r--timezone/zdump.c39
-rw-r--r--timezone/zic.c709
10 files changed, 756 insertions, 240 deletions
diff --git a/ChangeLog b/ChangeLog
index 71207b92a5..72f7d5c11f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2006-11-10 Ulrich Drepper <drepper@redhat.com>
+ * time/tzfile.c (__tzfile_read): Extend to handle new file format
+ on machines with 64-bit time_t.
+
+ * timezone/checktab.awk: Update from tzcode2006o.
+ * timezone/ialloc.c: Likewise.
+ * timezone/private.h: Likewise.
+ * timezone/scheck.: Likewise.
+ * timezone/tzfile.h: Likewise.
+ * timezone/tzselect.ksh: Likewise.
+ * timezone/zdump.c: Likewise.
+ * timezone/zic.c: Likewise.
+
[BZ #3483]
* elf/ldconfig.c (main): Call setlocale and textdomain.
Patch mostly by Benno Schulenberg <bensberg@justemail.net>.
diff --git a/time/tzfile.c b/time/tzfile.c
index e95fd55f36..295f0aa3cb 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-1993,1995-2001,2003,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1993,1995-2001,2003,2004,2006
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -71,24 +72,34 @@ static inline int
__attribute ((always_inline))
decode (const void *ptr)
{
- if ((BYTE_ORDER == BIG_ENDIAN) && sizeof (int) == 4)
+ if (BYTE_ORDER == BIG_ENDIAN && sizeof (int) == 4)
return *(const int *) ptr;
- else if (BYTE_ORDER == LITTLE_ENDIAN && sizeof (int) == 4)
+ if (sizeof (int) == 4)
return bswap_32 (*(const int *) ptr);
- else
- {
- const unsigned char *p = ptr;
- int result = *p & (1 << (CHAR_BIT - 1)) ? ~0 : 0;
- result = (result << 8) | *p++;
- result = (result << 8) | *p++;
- result = (result << 8) | *p++;
- result = (result << 8) | *p++;
+ const unsigned char *p = ptr;
+ int result = *p & (1 << (CHAR_BIT - 1)) ? ~0 : 0;
- return result;
- }
+ result = (result << 8) | *p++;
+ result = (result << 8) | *p++;
+ result = (result << 8) | *p++;
+ result = (result << 8) | *p++;
+
+ return result;
}
+
+static inline int64_t
+__attribute ((always_inline))
+decode64 (const void *ptr)
+{
+ if ((BYTE_ORDER == BIG_ENDIAN))
+ return *(const int64_t *) ptr;
+
+ return bswap_64 (*(const int64_t *) ptr);
+}
+
+
void
__tzfile_read (const char *file, size_t extra, char **extrap)
{
@@ -102,6 +113,10 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
size_t types_idx;
size_t leaps_idx;
int was_using_tzfile = __use_tzfile;
+ int trans_width = 4;
+
+ if (sizeof (time_t) != 4 && sizeof (time_t) != 8)
+ abort ();
__use_tzfile = 0;
@@ -185,8 +200,10 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
/* No threads reading this stream. */
__fsetlocking (f, FSETLOCKING_BYCALLER);
+ read_again:
if (__builtin_expect (fread_unlocked ((void *) &tzhead, sizeof (tzhead),
- 1, f) != 1, 0))
+ 1, f) != 1, 0)
+ || memcmp (tzhead.tzh_magic, TZ_MAGIC, sizeof (tzhead.tzh_magic)) != 0)
goto lose;
num_transitions = (size_t) decode (tzhead.tzh_timecnt);
@@ -196,6 +213,26 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
num_isstd = (size_t) decode (tzhead.tzh_ttisstdcnt);
num_isgmt = (size_t) decode (tzhead.tzh_ttisgmtcnt);
+ /* For platforms with 64-bit time_t we use the new format if available. */
+ if (sizeof (time_t) == 8 && trans_width == 4
+ && tzhead.tzh_version[0] != '\0')
+ {
+ /* We use the 8-byte format. */
+ trans_width = 8;
+
+ /* Position the stream before the second header. */
+ size_t to_skip = (num_transitions * (4 + 1)
+ + num_types * 6
+ + chars
+ + num_leaps * 8
+ + num_isstd
+ + num_isgmt);
+ if (fseek (f, to_skip, SEEK_CUR) != 0)
+ goto lose;
+
+ goto read_again;
+ }
+
total_size = num_transitions * (sizeof (time_t) + 1);
total_size = ((total_size + __alignof__ (struct ttinfo) - 1)
& ~(__alignof__ (struct ttinfo) - 1));
@@ -205,10 +242,10 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
& ~(__alignof__ (struct leap) - 1));
leaps_idx = total_size;
total_size += num_leaps * sizeof (struct leap);
- /* This is for the extra memory required by the caller. */
- total_size += extra;
- transitions = (time_t *) malloc (total_size);
+ /* Allocate enough memory including the extra block requested by the
+ caller. */
+ transitions = (time_t *) malloc (total_size + extra);
if (transitions == NULL)
goto lose;
@@ -220,14 +257,11 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
if (extra > 0)
*extrap = (char *) &leaps[num_leaps];
- if (sizeof (time_t) < 4)
- abort ();
-
- if (sizeof (time_t) == 4)
+ if (sizeof (time_t) == 4 || trans_width == 8)
{
- if (__builtin_expect (fread_unlocked (transitions, 1,
- (4 + 1) * num_transitions, f)
- != (4 + 1) * num_transitions, 0))
+ if (__builtin_expect (fread_unlocked (transitions, trans_width + 1,
+ num_transitions, f)
+ != num_transitions, 0))
goto lose;
}
else
@@ -245,7 +279,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
if (__builtin_expect (type_idxs[i] >= num_types, 0))
goto lose;
- if (BYTE_ORDER != BIG_ENDIAN || sizeof (time_t) != 4)
+ if (BYTE_ORDER != BIG_ENDIAN || (sizeof (time_t) == 8 && trans_width == 4))
{
/* Decode the transition times, stored as 4-byte integers in
network (big-endian) byte order. We work from the end of
@@ -255,6 +289,13 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
while (i-- > 0)
transitions[i] = decode ((char *) transitions + i * 4);
}
+ else if (BYTE_ORDER != BIG_ENDIAN && sizeof (time_t) == 8)
+ {
+ /* Decode the transition times, stored as 8-byte integers in
+ network (big-endian) byte order. */
+ for (i = 0; i < num_transitions; ++i)
+ transitions[i] = decode64 ((char *) transitions + i * 8);
+ }
for (i = 0; i < num_types; ++i)
{
@@ -280,13 +321,16 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
for (i = 0; i < num_leaps; ++i)
{
- unsigned char x[4];
- if (__builtin_expect (fread_unlocked (x, 1, sizeof (x), f) != sizeof (x),
- 0))
+ unsigned char x[8];
+ if (__builtin_expect (fread_unlocked (x, 1, trans_width, f)
+ != trans_width, 0))
goto lose;
- leaps[i].transition = (time_t) decode (x);
- if (__builtin_expect (fread_unlocked (x, 1, sizeof (x), f) != sizeof (x),
- 0))
+ if (sizeof (time_t) == 4 || trans_width == 4)
+ leaps[i].transition = (time_t) decode (x);
+ else
+ leaps[i].transition = (time_t) decode64 (x);
+
+ if (__builtin_expect (fread_unlocked (x, 1, 4, f) != 4, 0))
goto lose;
leaps[i].change = (long int) decode (x);
}
@@ -311,6 +355,12 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
while (i < num_types)
types[i++].isgmt = 0;
+ /* XXX When a version 2 file is available it can contain a POSIX TZ-style
+ formatted string which specifies how times past the last one specified
+ are supposed to be handled. We might want to handle this at some
+ point. But it might be overhead since most/all? files have an
+ open-ended last entry. */
+
fclose (f);
/* First "register" all timezone names. */
diff --git a/timezone/checktab.awk b/timezone/checktab.awk
index 6d532141e6..80ad7d5701 100644
--- a/timezone/checktab.awk
+++ b/timezone/checktab.awk
@@ -1,6 +1,6 @@
# Check tz tables for consistency.
-# @(#)checktab.awk 1.7
+# @(#)checktab.awk 8.1
# Contributed by Paul Eggert.
diff --git a/timezone/ialloc.c b/timezone/ialloc.c
index 8a0c701578..1fc2035f45 100644
--- a/timezone/ialloc.c
+++ b/timezone/ialloc.c
@@ -1,6 +1,11 @@
+/*
+** This file is in the public domain, so clarified as of
+** 2006-07-17 by Arthur David Olson.
+*/
+
#ifndef lint
#ifndef NOID
-static char elsieid[] = "@(#)ialloc.c 8.29";
+static char elsieid[] = "@(#)ialloc.c 8.30";
#endif /* !defined NOID */
#endif /* !defined lint */
diff --git a/timezone/private.h b/timezone/private.h
index d9f232c8e3..2837b70c10 100644
--- a/timezone/private.h
+++ b/timezone/private.h
@@ -21,7 +21,7 @@
#ifndef lint
#ifndef NOID
-static char privatehid[] = "@(#)private.h 7.55";
+static char privatehid[] = "@(#)private.h 8.2";
#endif /* !defined NOID */
#endif /* !defined lint */
@@ -89,7 +89,7 @@ static char privatehid[] = "@(#)private.h 7.55";
#include "stdio.h"
#include "errno.h"
#include "string.h"
-#include "limits.h" /* for CHAR_BIT */
+#include "limits.h" /* for CHAR_BIT et al. */
#include "time.h"
#include "stdlib.h"
@@ -125,20 +125,51 @@ static char privatehid[] = "@(#)private.h 7.55";
#define is_digit(c) ((unsigned)(c) - '0' <= 9)
/*
+** Define HAVE_STDINT_H's default value here, rather than at the
+** start, since __GLIBC__'s value depends on previously-included
+** files.
+** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.)
+*/
+#ifndef HAVE_STDINT_H
+#define HAVE_STDINT_H \
+ (199901 <= __STDC_VERSION__ || \
+ 2 < (__GLIBC__ + (0 < __GLIBC_MINOR__)))
+#endif /* !defined HAVE_STDINT_H */
+
+#if HAVE_STDINT_H
+#include "stdint.h"
+#endif /* !HAVE_STDINT_H */
+
+#ifndef INT_FAST64_MAX
+/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */
+#if defined LLONG_MAX || defined __LONG_LONG_MAX__
+typedef long long int_fast64_t;
+#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
+#if (LONG_MAX >> 31) < 0xffffffff
+Please use a compiler that supports a 64-bit integer type (or wider);
+you may need to compile with "-DHAVE_STDINT_H".
+#endif /* (LONG_MAX >> 31) < 0xffffffff */
+typedef long int_fast64_t;
+#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
+#endif /* !defined INT_FAST64_MAX */
+
+#ifndef INT32_MAX
+#define INT32_MAX 0x7fffffff
+#endif /* !defined INT32_MAX */
+#ifndef INT32_MIN
+#define INT32_MIN (-1 - INT32_MAX)
+#endif /* !defined INT32_MIN */
+
+/*
** Workarounds for compilers/systems.
*/
/*
-** SunOS 4.1.1 cc lacks prototypes.
+** If your compiler lacks prototypes, "#define P(x) ()".
*/
#ifndef P
-#ifdef __STDC__
#define P(x) x
-#endif /* defined __STDC__ */
-#ifndef __STDC__
-#define P(x) ()
-#endif /* !defined __STDC__ */
#endif /* !defined P */
/*
@@ -211,14 +242,14 @@ 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));
-char * imalloc P((int n));
-void * irealloc P((void * pointer, int size));
-void icfree P((char * pointer));
-void ifree P((char * pointer));
-const char *scheck P((const char *string, const char *format));
+char * icalloc P((int nelem, int elsize));
+char * icatalloc P((char * old, const char * new));
+char * icpyalloc P((const char * string));
+char * imalloc P((int n));
+void * irealloc P((void * pointer, int size));
+void icfree P((char * pointer));
+void ifree P((char * pointer));
+const char * scheck P((const char * string, const char * format));
/*
** Finally, some convenience items.
@@ -310,6 +341,26 @@ char *asctime_r P((struct tm const *, char *));
char *ctime_r P((time_t const *, char *));
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
+#ifndef YEARSPERREPEAT
+#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */
+#endif /* !defined YEARSPERREPEAT */
+
+/*
+** The Gregorian year averages 365.2425 days, which is 31556952 seconds.
+*/
+
+#ifndef AVGSECSPERYEAR
+#define AVGSECSPERYEAR 31556952L
+#endif /* !defined AVGSECSPERYEAR */
+
+#ifndef SECSPERREPEAT
+#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
+#endif /* !defined SECSPERREPEAT */
+
+#ifndef SECSPERREPEAT_BITS
+#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */
+#endif /* !defined SECSPERREPEAT_BITS */
+
/*
** UNIX was a registered trademark of The Open Group in 2003.
*/
diff --git a/timezone/scheck.c b/timezone/scheck.c
index bc156379a0..74d9b07c14 100644
--- a/timezone/scheck.c
+++ b/timezone/scheck.c
@@ -1,6 +1,11 @@
+/*
+** This file is in the public domain, so clarified as of
+** 2006-07-17 by Arthur David Olson.
+*/
+
#ifndef lint
#ifndef NOID
-static char elsieid[] = "@(#)scheck.c 8.17";
+static char elsieid[] = "@(#)scheck.c 8.19";
#endif /* !defined lint */
#endif /* !defined NOID */
diff --git a/timezone/tzfile.h b/timezone/tzfile.h
index fb6ca9880f..3a9eee305a 100644
--- a/timezone/tzfile.h
+++ b/timezone/tzfile.h
@@ -21,7 +21,7 @@
#ifndef lint
#ifndef NOID
-static char tzfilehid[] = "@(#)tzfile.h 7.18";
+static char tzfilehid[] = "@(#)tzfile.h 8.1";
#endif /* !defined NOID */
#endif /* !defined lint */
@@ -49,7 +49,8 @@ static char tzfilehid[] = "@(#)tzfile.h 7.18";
struct tzhead {
char tzh_magic[4]; /* TZ_MAGIC */
- char tzh_reserved[16]; /* reserved for future use */
+ char tzh_version[1]; /* '\0' or '2' as of 2005 */
+ char tzh_reserved[15]; /* reserved--must be zero */
char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
char tzh_leapcnt[4]; /* coded number of leap seconds */
@@ -84,18 +85,22 @@ struct tzhead {
*/
/*
+** If tzh_version is '2' or greater, the above is followed by a second instance
+** of tzhead and a second instance of the data in which each coded transition
+** time uses 8 rather than 4 chars,
+** then a POSIX-TZ-environment-variable-style string for use in handling
+** instants after the last transition time stored in the file
+** (with nothing between the newlines if there is no POSIX representation for
+** such instants).
+*/
+
+/*
** In the current implementation, "tzset()" refuses to deal with files that
** exceed any of the limits below.
*/
#ifndef TZ_MAX_TIMES
-/*
-** The TZ_MAX_TIMES value below is enough to handle a bit more than a
-** year's worth of solar time (corrected daily to the nearest second) or
-** 138 years of Pacific Presidential Election time
-** (where there are three time zone transitions every fourth year).
-*/
-#define TZ_MAX_TIMES 370
+#define TZ_MAX_TIMES 1200
#endif /* !defined TZ_MAX_TIMES */
#ifndef TZ_MAX_TYPES
diff --git a/timezone/tzselect.ksh b/timezone/tzselect.ksh
index f6e28bfdab..b99af8273b 100644
--- a/timezone/tzselect.ksh
+++ b/timezone/tzselect.ksh
@@ -1,6 +1,6 @@
#! @KSH@
-# '@(#)tzselect.ksh 1.8'
+# '@(#)tzselect.ksh 8.1'
# Ask the user about the time zone, and output the resulting TZ value to stdout.
# Interact with the user via stderr and stdin.
diff --git a/timezone/zdump.c b/timezone/zdump.c
index d525da1bae..b5dd09b861 100644
--- a/timezone/zdump.c
+++ b/timezone/zdump.c
@@ -1,4 +1,4 @@
-static char elsieid[] = "@(#)zdump.c 7.74";
+static char elsieid[] = "@(#)zdump.c 8.2";
/*
** This code has been made independent of the rest of the time
@@ -15,7 +15,7 @@ static char elsieid[] = "@(#)zdump.c 7.74";
#include "ctype.h" /* for isalpha et al. */
#ifndef isascii
#define isascii(x) 1
-#endif
+#endif /* !defined isascii */
#ifndef ZDUMP_LO_YEAR
#define ZDUMP_LO_YEAR (-500)
@@ -130,11 +130,7 @@ static char elsieid[] = "@(#)zdump.c 7.74";
#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;
@@ -389,7 +385,7 @@ _("%s: usage is %s [ --version ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n"),
}
if (fflush(stdout) || ferror(stdout)) {
(void) fprintf(stderr, "%s: ", progname);
- (void) perror(_("Error writing to standard output"));
+ (void) perror(_("Error writing standard output"));
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
@@ -418,14 +414,21 @@ _("%s: use of -v on system with floating time_t other than float or double\n"),
}
} else if (0 > (time_t) -1) {
/*
- ** time_t is signed.
+ ** time_t is signed. Assume overflow wraps around.
*/
- register time_t hibit;
+ time_t t = 0;
+ time_t t1 = 1;
- for (hibit = 1; (hibit * 2) != 0; hibit *= 2)
- continue;
- absolute_min_time = hibit;
- absolute_max_time = -(hibit + 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.
@@ -468,10 +471,7 @@ const long y;
}
static time_t
-hunt(name, lot, hit)
-char * name;
-time_t lot;
-time_t hit;
+hunt(char *name, time_t lot, time_t hit)
{
time_t t;
long diff;
@@ -541,10 +541,7 @@ struct tm * oldp;
}
static void
-show(zone, t, v)
-char * zone;
-time_t t;
-int v;
+show(char *zone, time_t t, int v)
{
register struct tm * tmp;
diff --git a/timezone/zic.c b/timezone/zic.c
index acb76fb3ba..f7393ea7ba 100644
--- a/timezone/zic.c
+++ b/timezone/zic.c
@@ -1,15 +1,18 @@
-static char elsieid[] = "@(#)zic.c 7.128";
-
/*
-** Regardless of the type of time_t, we do our work using this type.
+** This file is in the public domain, so clarified as of
+** 2006-07-17 by Arthur David Olson.
*/
-typedef int zic_t;
+static char elsieid[] = "@(#)zic.c 8.7";
#include "private.h"
#include "locale.h"
#include "tzfile.h"
+#define ZIC_VERSION '2'
+
+typedef int_fast64_t zic_t;
+
#ifndef ZIC_MAX_ABBR_LEN_WO_WARN
#define ZIC_MAX_ABBR_LEN_WO_WARN 6
#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */
@@ -36,6 +39,11 @@ typedef int zic_t;
#define isascii(x) 1
#endif
+#define OFFSET_STRLEN_MAXIMUM (7 + INT_STRLEN_MAXIMUM(long))
+#define RULE_STRLEN_MAXIMUM 8 /* "Mdd.dd.d" */
+
+#define end(cp) (strchr((cp), '\0'))
+
struct rule {
const char * r_filename;
int r_linenum;
@@ -44,6 +52,8 @@ struct rule {
int r_loyear; /* for example, 1986 */
int r_hiyear; /* for example, 1986 */
const char * r_yrtype;
+ int r_lowasnum;
+ int r_hiwasnum;
int r_month; /* 0..11 */
@@ -103,9 +113,10 @@ static void adjleap P((void));
static void associate P((void));
static int ciequal P((const char * ap, const char * bp));
static void convert P((long val, char * buf));
+static void convert64 P((zic_t val, char * buf));
static void dolink P((const char * fromfile, const char * tofile));
static void doabbr P((char * abbr, const char * format,
- const char * letters, int isdst));
+ const char * letters, int isdst, int doquotes));
static void eat P((const char * name, int num));
static void eats P((const char * name, int num,
const char * rname, int rnum));
@@ -121,6 +132,7 @@ static void inrule P((char ** fields, int nfields));
static int inzcont P((char ** fields, int nfields));
static int inzone P((char ** fields, int nfields));
static int inzsub P((char ** fields, int nfields, int iscont));
+static int is32 P((zic_t x));
static int itsabbr P((const char * abbr, const char * word));
static int itsdir P((const char * name));
static int lowerit P((int c));
@@ -130,16 +142,22 @@ static void newabbr P((const char * abbr));
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 void puttzcode64 P((zic_t code, FILE * fp));
static int rcomp P((const void * leftp, const void * rightp));
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 int stringoffset P((char * result, long offset));
+static int stringrule P((char * result, const struct rule * rp,
+ long dstoff, long gmtoff));
+static void stringzone P((char * result,
+ const struct zone * zp, int ntzones));
static void setboundaries P((void));
static zic_t tadd P((zic_t t1, long t2));
static void usage P((void));
-static void writezone P((const char * name));
+static void writezo