aboutsummaryrefslogtreecommitdiff
path: root/timezone
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2017-06-16 11:09:21 +0000
committerJoseph Myers <joseph@codesourcery.com>2017-06-16 11:09:21 +0000
commit92bd70fb85bce57ac47ba5d8af008736832c955a (patch)
tree3fec830fb36ef1af2aaeb411f23dc76c3fcd7c15 /timezone
parenta448ee41e70a0b1d26557ffce8e550fe4aad2525 (diff)
downloadglibc-92bd70fb85bce57ac47ba5d8af008736832c955a.tar.xz
glibc-92bd70fb85bce57ac47ba5d8af008736832c955a.zip
Update timezone code from tzcode 2017b.
This patch updates files coming from tzcode to the versions in tzcode 2017b. A couple of changes to other glibc code are needed. time/tzset.c was using the SECSPERDAY macro from tzfile.h, which no longer defines that macro, so a local definition is added to tzset.c. Because timezone/private.h now defines the _ macro whenever HAVE_GETTEXT is true, even if it was previously defined, it is also necessary to avoid a conflict with the definition in include/libintl.h. Defining _ISOMAC is the obvious way to avoid such internal definitions being visible, together with defining TZ_DOMAIN so that zic and zdump continue to get the messages from the libc domain as desired. However, zic and zdump rely on PKGVERSION and REPORT_BUGS_TO from config.h, which is not included by default with _ISOMAC, so -include config.h needs adding to the options for these programs as well. Together those changes allow unmodified tzcode 2017b sources to work in glibc. Tested for x86_64. * timezone/private.h: Update from tzcode 2017b. * timezone/tzfile.h: Likewise. * timezone/tzselect.ksh: Likewise. * timezone/zdump.c: Likewise. * timezone/zic.c: Likewise. * timezone/Makefile (tz-cflags): Add -D_ISOMAC -DTZ_DOMAIN='"libc"' -include $(common-objpfx)config.h. * time/tzset.c (SECSPERDAY): New macro.
Diffstat (limited to 'timezone')
-rw-r--r--timezone/Makefile3
-rw-r--r--timezone/private.h182
-rw-r--r--timezone/tzfile.h52
-rwxr-xr-xtimezone/tzselect.ksh17
-rw-r--r--timezone/zdump.c541
-rw-r--r--timezone/zic.c684
6 files changed, 864 insertions, 615 deletions
diff --git a/timezone/Makefile b/timezone/Makefile
index 35e6a95e6b..d6cc7ba357 100644
--- a/timezone/Makefile
+++ b/timezone/Makefile
@@ -59,7 +59,8 @@ tz-cflags = -DTZDIR='"$(zonedir)"' \
-DTZDEFAULT='"$(localtime-file)"' \
-DTZDEFRULES='"$(posixrules-file)"' \
-DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone \
- -DHAVE_GETTEXT -DUSE_LTZ=0 -Wno-maybe-uninitialized
+ -DHAVE_GETTEXT -DUSE_LTZ=0 -D_ISOMAC -DTZ_DOMAIN='"libc"' \
+ -include $(common-objpfx)config.h -Wno-maybe-uninitialized
# The -Wno-unused-variable flag is used to prevent GCC 6
# from warning about time_t_min and time_t_max which are
diff --git a/timezone/private.h b/timezone/private.h
index 1c176e62bc..e2f23f5f40 100644
--- a/timezone/private.h
+++ b/timezone/private.h
@@ -15,6 +15,7 @@
** Thank you!
*/
+/* This string was in the Factory zone through version 2016f. */
#define GRANDPARENTED "Local time zone must be set--see zic manual page"
/*
@@ -22,6 +23,10 @@
** You can override these in your C compiler options, e.g. '-DHAVE_GETTEXT=1'.
*/
+#ifndef HAVE_DECL_ASCTIME_R
+#define HAVE_DECL_ASCTIME_R 1
+#endif
+
#ifndef HAVE_GETTEXT
#define HAVE_GETTEXT 0
#endif /* !defined HAVE_GETTEXT */
@@ -34,6 +39,10 @@
#define HAVE_LINK 1
#endif /* !defined HAVE_LINK */
+#ifndef HAVE_POSIX_DECLS
+#define HAVE_POSIX_DECLS 1
+#endif
+
#ifndef HAVE_STRDUP
#define HAVE_STRDUP 1
#endif
@@ -69,9 +78,9 @@
/* Enable tm_gmtoff and tm_zone on GNUish systems. */
#define _GNU_SOURCE 1
-/* Fix asctime_r on Solaris 10. */
+/* Fix asctime_r on Solaris 11. */
#define _POSIX_PTHREAD_SEMANTICS 1
-/* Enable strtoimax on Solaris 10. */
+/* Enable strtoimax on pre-C99 Solaris 11. */
#define __EXTENSIONS__ 1
/*
@@ -95,23 +104,26 @@
#undef tzalloc
#undef tzfree
-#include "sys/types.h" /* for time_t */
-#include "stdio.h"
-#include "string.h"
-#include "limits.h" /* for CHAR_BIT et al. */
-#include "stdlib.h"
+#include <sys/types.h> /* for time_t */
+#include <stdio.h>
+#include <string.h>
+#include <limits.h> /* for CHAR_BIT et al. */
+#include <stdlib.h>
-#include "errno.h"
+#include <errno.h>
#ifndef ENAMETOOLONG
# define ENAMETOOLONG EINVAL
#endif
+#ifndef ENOTSUP
+# define ENOTSUP EINVAL
+#endif
#ifndef EOVERFLOW
# define EOVERFLOW EINVAL
#endif
#if HAVE_GETTEXT
-#include "libintl.h"
+#include <libintl.h>
#endif /* HAVE_GETTEXT */
#if HAVE_SYS_WAIT_H
@@ -126,7 +138,7 @@
#endif /* !defined WEXITSTATUS */
#if HAVE_UNISTD_H
-#include "unistd.h" /* for F_OK, R_OK, and other POSIX goodness */
+#include <unistd.h> /* for F_OK, R_OK, and other POSIX goodness */
#endif /* HAVE_UNISTD_H */
#ifndef HAVE_STRFTIME_L
@@ -149,19 +161,19 @@
/*
** 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.)
+** start, since __GLIBC__ and INTMAX_MAX's values depend on
+** previously-included files. glibc 2.1 and Solaris 10 and later have
+** stdint.h, even with pre-C99 compilers.
*/
#ifndef HAVE_STDINT_H
#define HAVE_STDINT_H \
(199901 <= __STDC_VERSION__ \
|| 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
- || __CYGWIN__)
+ || __CYGWIN__ || INTMAX_MAX)
#endif /* !defined HAVE_STDINT_H */
#if HAVE_STDINT_H
-#include "stdint.h"
+#include <stdint.h>
#endif /* !HAVE_STDINT_H */
#ifndef HAVE_INTTYPES_H
@@ -197,14 +209,18 @@ typedef long int_fast64_t;
# endif
#endif
-#ifndef SCNdFAST64
+#ifndef PRIdFAST64
# if INT_FAST64_MAX == LLONG_MAX
-# define SCNdFAST64 "lld"
+# define PRIdFAST64 "lld"
# else
-# define SCNdFAST64 "ld"
+# define PRIdFAST64 "ld"
# endif
#endif
+#ifndef SCNdFAST64
+# define SCNdFAST64 PRIdFAST64
+#endif
+
#ifndef INT_FAST32_MAX
# if INT_MAX >> 31 == 0
typedef long int_fast32_t;
@@ -304,6 +320,13 @@ typedef unsigned long uintmax_t;
** Workarounds for compilers/systems.
*/
+#ifndef EPOCH_LOCAL
+# define EPOCH_LOCAL 0
+#endif
+#ifndef EPOCH_OFFSET
+# define EPOCH_OFFSET 0
+#endif
+
/*
** Compile with -Dtime_tz=T to build the tz package with a private
** time_t type equivalent to T rather than the system-supplied time_t.
@@ -311,7 +334,7 @@ typedef unsigned long uintmax_t;
** (e.g., time_t wider than 'long', or unsigned time_t) even on
** typical platforms.
*/
-#ifdef time_tz
+#if defined time_tz || EPOCH_LOCAL || EPOCH_OFFSET != 0
# ifdef LOCALTIME_IMPLEMENTATION
static time_t sys_time(time_t *x) { return time(x); }
# endif
@@ -379,25 +402,21 @@ time_t time(time_t *);
void tzset(void);
#endif
-/*
-** Some time.h implementations don't declare asctime_r.
-** Others might define it as a macro.
-** Fix the former without affecting the latter.
-** Similarly for timezone, daylight, and altzone.
-*/
-
-#ifndef asctime_r
-extern char * asctime_r(struct tm const *restrict, char *restrict);
+#if !HAVE_DECL_ASCTIME_R && !defined asctime_r
+extern char *asctime_r(struct tm const *restrict, char *restrict);
#endif
-#ifdef USG_COMPAT
-# ifndef timezone
+#if !HAVE_POSIX_DECLS
+# ifdef USG_COMPAT
+# ifndef timezone
extern long timezone;
-# endif
-# ifndef daylight
+# endif
+# ifndef daylight
extern int daylight;
+# endif
# endif
#endif
+
#if defined ALTZONE && !defined altzone
extern long altzone;
#endif
@@ -481,14 +500,8 @@ time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_PURE;
# include <stdbool.h>
#endif
-#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 */
-
#define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
/* Max and min values of the integer type T, of which only the bottom
@@ -500,11 +513,29 @@ time_t time2posix_z(timezone_t, time_t) ATTRIBUTE_PURE;
#define MINVAL(t, b) \
((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
-/* The minimum and maximum finite time values. This assumes no padding. */
+/* The minimum and maximum finite time values. This implementation
+ assumes no padding if time_t is signed and either the compiler is
+ pre-C11 or time_t is not one of the standard signed integer types. */
+#if 201112 <= __STDC_VERSION__
+static time_t const time_t_min
+ = (TYPE_SIGNED(time_t)
+ ? _Generic((time_t) 0,
+ signed char: SCHAR_MIN, short: SHRT_MIN,
+ int: INT_MIN, long: LONG_MIN, long long: LLONG_MIN,
+ default: MINVAL(time_t, TYPE_BIT(time_t)))
+ : 0);
+static time_t const time_t_max
+ = (TYPE_SIGNED(time_t)
+ ? _Generic((time_t) 0,
+ signed char: SCHAR_MAX, short: SHRT_MAX,
+ int: INT_MAX, long: LONG_MAX, long long: LLONG_MAX,
+ default: MAXVAL(time_t, TYPE_BIT(time_t)))
+ : -1);
+#else
static time_t const time_t_min = MINVAL(time_t, TYPE_BIT(time_t));
static time_t const time_t_max = MAXVAL(time_t, TYPE_BIT(time_t));
+#endif
-#ifndef INT_STRLEN_MAXIMUM
/*
** 302 / 1000 is log10(2.0) rounded up.
** Subtract one for the sign bit if the type is signed;
@@ -514,7 +545,6 @@ static time_t const time_t_max = MAXVAL(time_t, TYPE_BIT(time_t));
#define INT_STRLEN_MAXIMUM(type) \
((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \
1 + TYPE_SIGNED(type))
-#endif /* !defined INT_STRLEN_MAXIMUM */
/*
** INITIALIZE(x)
@@ -536,13 +566,11 @@ static time_t const time_t_max = MAXVAL(time_t, TYPE_BIT(time_t));
** The default is to use gettext if available, and use MSGID otherwise.
*/
-#ifndef _
#if HAVE_GETTEXT
#define _(msgid) gettext(msgid)
#else /* !HAVE_GETTEXT */
#define _(msgid) msgid
#endif /* !HAVE_GETTEXT */
-#endif /* !defined _ */
#if !defined TZ_DOMAIN && defined HAVE_GETTEXT
# define TZ_DOMAIN "tz"
@@ -555,24 +583,70 @@ char *asctime_r(struct tm const *, char *);
char *ctime_r(time_t const *, char *);
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
-#ifndef YEARSPERREPEAT
+/* Handy macros that are independent of tzfile implementation. */
+
#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */
-#endif /* !defined YEARSPERREPEAT */
+
+#define SECSPERMIN 60
+#define MINSPERHOUR 60
+#define HOURSPERDAY 24
+#define DAYSPERWEEK 7
+#define DAYSPERNYEAR 365
+#define DAYSPERLYEAR 366
+#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
+#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
+#define MONSPERYEAR 12
+
+#define TM_SUNDAY 0
+#define TM_MONDAY 1
+#define TM_TUESDAY 2
+#define TM_WEDNESDAY 3
+#define TM_THURSDAY 4
+#define TM_FRIDAY 5
+#define TM_SATURDAY 6
+
+#define TM_JANUARY 0
+#define TM_FEBRUARY 1
+#define TM_MARCH 2
+#define TM_APRIL 3
+#define TM_MAY 4
+#define TM_JUNE 5
+#define TM_JULY 6
+#define TM_AUGUST 7
+#define TM_SEPTEMBER 8
+#define TM_OCTOBER 9
+#define TM_NOVEMBER 10
+#define TM_DECEMBER 11
+
+#define TM_YEAR_BASE 1900
+
+#define EPOCH_YEAR 1970
+#define EPOCH_WDAY TM_THURSDAY
+
+#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
/*
-** The Gregorian year averages 365.2425 days, which is 31556952 seconds.
+** Since everything in isleap is modulo 400 (or a factor of 400), we know that
+** isleap(y) == isleap(y % 400)
+** and so
+** isleap(a + b) == isleap((a + b) % 400)
+** or
+** isleap(a + b) == isleap(a % 400 + b % 400)
+** This is true even if % means modulo rather than Fortran remainder
+** (which is allowed by C89 but not C99).
+** We use this to avoid addition overflow problems.
*/
-#ifndef AVGSECSPERYEAR
-#define AVGSECSPERYEAR 31556952L
-#endif /* !defined AVGSECSPERYEAR */
+#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
+
-#ifndef SECSPERREPEAT
-#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
-#endif /* !defined SECSPERREPEAT */
+/*
+** The Gregorian year averages 365.2425 days, which is 31556952 seconds.
+*/
-#ifndef SECSPERREPEAT_BITS
+#define AVGSECSPERYEAR 31556952L
+#define SECSPERREPEAT \
+ ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */
-#endif /* !defined SECSPERREPEAT_BITS */
#endif /* !defined PRIVATE_H */
diff --git a/timezone/tzfile.h b/timezone/tzfile.h
index ebecd68322..0e51dce1d7 100644
--- a/timezone/tzfile.h
+++ b/timezone/tzfile.h
@@ -114,56 +114,4 @@ struct tzhead {
#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
#endif /* !defined TZ_MAX_LEAPS */
-#define SECSPERMIN 60
-#define MINSPERHOUR 60
-#define HOURSPERDAY 24
-#define DAYSPERWEEK 7
-#define DAYSPERNYEAR 365
-#define DAYSPERLYEAR 366
-#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
-#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
-#define MONSPERYEAR 12
-
-#define TM_SUNDAY 0
-#define TM_MONDAY 1
-#define TM_TUESDAY 2
-#define TM_WEDNESDAY 3
-#define TM_THURSDAY 4
-#define TM_FRIDAY 5
-#define TM_SATURDAY 6
-
-#define TM_JANUARY 0
-#define TM_FEBRUARY 1
-#define TM_MARCH 2
-#define TM_APRIL 3
-#define TM_MAY 4
-#define TM_JUNE 5
-#define TM_JULY 6
-#define TM_AUGUST 7
-#define TM_SEPTEMBER 8
-#define TM_OCTOBER 9
-#define TM_NOVEMBER 10
-#define TM_DECEMBER 11
-
-#define TM_YEAR_BASE 1900
-
-#define EPOCH_YEAR 1970
-#define EPOCH_WDAY TM_THURSDAY
-
-#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
-
-/*
-** Since everything in isleap is modulo 400 (or a factor of 400), we know that
-** isleap(y) == isleap(y % 400)
-** and so
-** isleap(a + b) == isleap((a + b) % 400)
-** or
-** isleap(a + b) == isleap(a % 400 + b % 400)
-** This is true even if % means modulo rather than Fortran remainder
-** (which is allowed by C89 but not C99).
-** We use this to avoid addition overflow problems.
-*/
-
-#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
-
#endif /* !defined TZFILE_H */
diff --git a/timezone/tzselect.ksh b/timezone/tzselect.ksh
index 2c3b2f4438..d2c3a6d1dd 100755
--- a/timezone/tzselect.ksh
+++ b/timezone/tzselect.ksh
@@ -7,7 +7,7 @@ REPORT_BUGS_TO=tz@iana.org
# 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.
+# Contributed by Paul Eggert. This file is in the public domain.
# Porting notes:
#
@@ -346,11 +346,14 @@ while
'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])?)?"
+ tzname = "(<[[:alnum:]+-]{3,}>|[[:alpha:]]{3,})"
+ time = "(2[0-4]|[0-1]?[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 ")?"
+ mdate = "M([1-9]|1[0-2])\\.[1-5]\\.[0-6]"
+ jdate = "((J[1-9]|[0-9]|J?[1-9][0-9]" \
+ "|J?[1-2][0-9][0-9])|J?3[0-5][0-9]|J?36[0-5])"
+ datetime = ",(" mdate "|" jdate ")(/" time ")?"
tzpattern = "^(:.*|" tzname offset "(" tzname \
"(" offset ")?(" datetime datetime ")?)?)$"
if (TZ ~ tzpattern) exit 1
@@ -509,7 +512,7 @@ while
case $TZsec in
$UTsec)
extra_info="
-Local time is now: $TZdate.
+Selected time is now: $TZdate.
Universal Time is now: $UTdate."
break
esac
@@ -545,7 +548,7 @@ case $SHELL in
*) file=.profile line="TZ='$TZ'; export TZ"
esac
-say >&2 "
+test -t 1 && say >&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.
diff --git a/timezone/zdump.c b/timezone/zdump.c
index 063a2635ec..bf75800101 100644
--- a/timezone/zdump.c
+++ b/timezone/zdump.c
@@ -19,89 +19,7 @@
# define USE_LTZ 1
#endif
-#if USE_LTZ
-# include "private.h"
-#endif
-
-/* Enable tm_gmtoff and tm_zone on GNUish systems. */
-#define _GNU_SOURCE 1
-/* Enable strtoimax on Solaris 10. */
-#define __EXTENSIONS__ 1
-
-#include "stdio.h" /* for stdout, stderr, perror */
-#include "string.h" /* for strcpy */
-#include "sys/types.h" /* for time_t */
-#include "time.h" /* for struct tm */
-#include "stdlib.h" /* for exit, malloc, atoi */
-#include "limits.h" /* for CHAR_BIT, LLONG_MAX */
-#include <errno.h>
-
-/*
-** Substitutes for pre-C99 compilers.
-** Much of this section of code is stolen from private.h.
-*/
-
-#ifndef HAVE_STDINT_H
-# define HAVE_STDINT_H \
- (199901 <= __STDC_VERSION__ \
- || 2 < __GLIBC__ + (1 <= __GLIBC_MINOR__) \
- || __CYGWIN__)
-#endif
-#if HAVE_STDINT_H
-# include "stdint.h"
-#endif
-#ifndef HAVE_INTTYPES_H
-# define HAVE_INTTYPES_H HAVE_STDINT_H
-#endif
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-
-#ifndef INT_FAST32_MAX
-# if INT_MAX >> 31 == 0
-typedef long int_fast32_t;
-# else
-typedef int int_fast32_t;
-# endif
-#endif
-
-/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */
-#if !defined LLONG_MAX && defined __LONG_LONG_MAX__
-# define LLONG_MAX __LONG_LONG_MAX__
-#endif
-
-#ifndef INTMAX_MAX
-# ifdef LLONG_MAX
-typedef long long intmax_t;
-# define strtoimax strtoll
-# define INTMAX_MAX LLONG_MAX
-# else
-typedef long intmax_t;
-# define strtoimax strtol
-# define INTMAX_MAX LONG_MAX
-# endif
-#endif
-
-#ifndef PRIdMAX
-# if INTMAX_MAX == LLONG_MAX
-# define PRIdMAX "lld"
-# else
-# define PRIdMAX "ld"
-# endif
-#endif
-
-/* Infer TM_ZONE on systems where this information is known, but suppress
- guessing if NO_TM_ZONE is defined. Similarly for TM_GMTOFF. */
-#if (defined __GLIBC__ \
- || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ \
- || (defined __APPLE__ && defined __MACH__))
-# if !defined TM_GMTOFF && !defined NO_TM_GMTOFF
-# define TM_GMTOFF tm_gmtoff
-# endif
-# if !defined TM_ZONE && !defined NO_TM_ZONE
-# define TM_ZONE tm_zone
-# endif
-#endif
+#include "private.h"
#ifndef HAVE_LOCALTIME_R
# define HAVE_LOCALTIME_R 1
@@ -131,62 +49,6 @@ typedef long intmax_t;
#define MAX_STRING_LENGTH 1024
#endif /* !defined MAX_STRING_LENGTH */
-#if __STDC_VERSION__ < 199901
-# define true 1
-# define false 0
-# define bool int
-#else
-# include <stdbool.h>
-#endif
-
-#ifndef EXIT_SUCCESS
-#define EXIT_SUCCESS 0
-#endif /* !defined EXIT_SUCCESS */
-
-#ifndef EXIT_FAILURE
-#define EXIT_FAILURE 1
-#endif /* !defined EXIT_FAILURE */
-
-#ifndef SECSPERMIN
-#define SECSPERMIN 60
-#endif /* !defined SECSPERMIN */
-
-#ifndef MINSPERHOUR
-#define MINSPERHOUR 60
-#endif /* !defined MINSPERHOUR */
-
-#ifndef SECSPERHOUR
-#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
-#endif /* !defined SECSPERHOUR */
-
-#ifndef HOURSPERDAY
-#define HOURSPERDAY 24
-#endif /* !defined HOURSPERDAY */
-
-#ifndef EPOCH_YEAR
-#define EPOCH_YEAR 1970
-#endif /* !defined EPOCH_YEAR */
-
-#ifndef TM_YEAR_BASE
-#define TM_YEAR_BASE 1900
-#endif /* !defined TM_YEAR_BASE */
-
-#ifndef DAYSPERNYEAR
-#define DAYSPERNYEAR 365
-#endif /* !defined DAYSPERNYEAR */
-
-#ifndef isleap
-#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 ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
#define SECSPERNYEAR (SECSPERDAY * DAYSPERNYEAR)
#define SECSPERLYEAR (SECSPERNYEAR + SECSPERDAY)
#define SECSPER400YEARS (SECSPERNYEAR * (intmax_t) (300 + 3) \
@@ -201,49 +63,24 @@ typedef long intmax_t;
*/
enum { SECSPER400YEARS_FITS = SECSPERLYEAR <= INTMAX_MAX / 400 };
-#ifndef HAVE_GETTEXT
-#define HAVE_GETTEXT 0
-#endif
#if HAVE_GETTEXT
-#include "locale.h" /* for setlocale */
-#include "libintl.h"
+#include <locale.h> /* for setlocale */
#endif /* HAVE_GETTEXT */
-#if 2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)
-# define ATTRIBUTE_PURE __attribute__ ((__pure__))
-#else
-# define ATTRIBUTE_PURE /* empty */
-#endif
-
-/*
-** 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
-#define _(msgid) gettext(msgid)
-#else /* !HAVE_GETTEXT */
-#define _(msgid) msgid
-#endif /* !HAVE_GETTEXT */
-#endif /* !defined _ */
-
-#if !defined TZ_DOMAIN && defined HAVE_GETTEXT
-# define TZ_DOMAIN "tz"
-#endif
-
#if ! HAVE_LOCALTIME_RZ
# undef timezone_t
# define timezone_t char **
#endif
extern char ** environ;
+
+#if !HAVE_POSIX_DECLS
extern int getopt(int argc, char * const argv[],
const char * options);
extern char * optarg;
extern int optind;
-extern char * tzname[2];
+extern char * tzname[];
+#endif
/* The minimum and maximum finite time values. */
enum { atime_shift = CHAR_BIT * sizeof (time_t) - 2 };
@@ -266,6 +103,8 @@ static intmax_t delta(struct tm *, struct tm *) ATTRIBUTE_PURE;
static void dumptime(struct tm const *);
static time_t hunt(timezone_t, char *, time_t, time_t);
static void show(timezone_t, char *, time_t, bool);
+static void showtrans(char const *, struct tm const *, time_t, char const *,
+ char const *);
static const char *tformat(void);
static time_t yeartot(intmax_t) ATTRIBUTE_PURE;
@@ -303,6 +142,19 @@ sumsize(size_t a, size_t b)
return sum;
}
+/* Return a pointer to a newly allocated buffer of size SIZE, exiting
+ on failure. SIZE should be nonzero. */
+static void *
+xmalloc(size_t size)
+{
+ void *p = malloc(size);
+ if (!p) {
+ perror(progname);
+ exit(EXIT_FAILURE);
+ }
+