mirror of
https://frontier.innolan.net/rainlance/amiga-tz.git
synced 2026-09-19 05:14:59 +00:00
Add support for testing time_t types other than the system's.
This makes it easier to test on (say) Debian, even if we're testing the time_t type on (say) NetBSD. NetBSD uses 64-bit time_t on 32-bit hosts, and this lets us test a NetBSD-style implementation (32-bit 'long', 64-bit time_t) on a 32-bit Debian host. * Makefile: Update comments to talk about TIME_T_FLOATING and time_tz. Sort the comments. * private.h (restrict): Define to empty with older compilers. 'restrict' is now needed, to define gmtime_r and localtime_r in standard ways when time_tz is defined. Make the following changes if time_tz is defined: (sys_time, time): New static functions. The former is the system 'time' function that applies to the system time_t, the latter our function that applies to our time_t. (time_t, ctime, ctime_r, difftime, gmtime, gmtime_r, localtime) (localtime_r, mktime): Rename to tz_time_t, tz_ctime, etc., via macros. Declare the renamed versions. * zdump.8: Document new options -V, -t. * zdump.c: Include private.h if time_tz is defined. (INITIALIZE): Remove; no longer needed. (absolute_min_time, absolute_max_time): Work even if time_t is wider than intmax_t, which can be true with GCC and __int128_t. Use the new TIME_T_FLOATING macro for this. (usage): Document new flags. (main): Support them.
This commit is contained in:
@@ -109,21 +109,23 @@ LDLIBS=
|
||||
# -DHAVE_SYMLINK=0 if your system lacks the symlink function
|
||||
# -DHAVE_SYS_STAT_H=0 if your compiler lacks a "sys/stat.h"
|
||||
# -DHAVE_SYS_WAIT_H=0 if your compiler lacks a "sys/wait.h"
|
||||
# -DLOCALE_HOME=\"path\" if locales are in "path", not "/usr/lib/locale"
|
||||
# -DHAVE_UNISTD_H=0 if your compiler lacks a "unistd.h" (Microsoft C++ 7?)
|
||||
# -DHAVE_UTMPX_H=1 if your compiler has a "utmpx.h"
|
||||
# -DTZDEFRULESTRING=\",date/time,date/time\" to default to the specified
|
||||
# DST transitions if the time zone files cannot be accessed
|
||||
# -DTZ_DOMAIN=\"foo\" to use "foo" for gettext domain name; default is "tz"
|
||||
# -TTZ_DOMAINDIR=\"/path\" to use "/path" for gettext directory;
|
||||
# the default is system-supplied, typically "/usr/lib/locale"
|
||||
# $(GCC_DEBUG_FLAGS) if you are using GCC and want lots of checking
|
||||
# -DLOCALE_HOME=\"path\" if locales are in "path", not "/usr/lib/locale"
|
||||
# -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU=1
|
||||
# if you do not want run time warnings about formats that may cause
|
||||
# year 2000 grief
|
||||
# -DTIME_T_FLOATING=1 if your time_t (or time_tz) is floating point
|
||||
# -Dtime_tz=\"T\" to use T as the time_t type, rather than the system time_t
|
||||
# -DTZ_DOMAIN=\"foo\" to use "foo" for gettext domain name; default is "tz"
|
||||
# -TTZ_DOMAINDIR=\"/path\" to use "/path" for gettext directory;
|
||||
# the default is system-supplied, typically "/usr/lib/locale"
|
||||
# -DTZDEFRULESTRING=\",date/time,date/time\" to default to the specified
|
||||
# DST transitions if the time zone files cannot be accessed
|
||||
# -DZIC_MAX_ABBR_LEN_WO_WARN=3
|
||||
# (or some other number) to set the maximum time zone abbreviation length
|
||||
# that zic will accept without a warning (the default is 6)
|
||||
# $(GCC_DEBUG_FLAGS) if you are using GCC and want lots of checking
|
||||
GCC_DEBUG_FLAGS = -Dlint -g3 -O3 -fno-common -fstrict-aliasing \
|
||||
-Wall -Wextra \
|
||||
-Wbad-function-cast -Wcast-align -Wcast-qual \
|
||||
|
||||
@@ -150,6 +150,10 @@ typedef long int_fast64_t;
|
||||
# define ATTRIBUTE_PURE /* empty */
|
||||
#endif
|
||||
|
||||
#if __STDC_VERSION__ < 199901 && !defined restrict
|
||||
# define restrict /* empty */
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Workarounds for compilers/systems.
|
||||
*/
|
||||
@@ -164,6 +168,58 @@ typedef long int_fast64_t;
|
||||
extern char * asctime_r(struct tm const *, char *);
|
||||
#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.
|
||||
** This debugging feature can test unusual design decisions
|
||||
** (e.g., time_t wider than 'long', or unsigned time_t) even on
|
||||
** typical platforms.
|
||||
*/
|
||||
#ifdef time_tz
|
||||
static time_t sys_time(time_t *x) { return time(x); }
|
||||
|
||||
# undef ctime
|
||||
# define ctime tz_ctime
|
||||
# undef ctime_r
|
||||
# define ctime_r tz_ctime_r
|
||||
# undef difftime
|
||||
# define difftime tz_difftime
|
||||
# undef gmtime
|
||||
# define gmtime tz_gmtime
|
||||
# undef gmtime_r
|
||||
# define gmtime_r tz_gmtime_r
|
||||
# undef localtime
|
||||
# define localtime tz_localtime
|
||||
# undef localtime_r
|
||||
# define localtime_r tz_localtime_r
|
||||
# undef mktime
|
||||
# define mktime tz_mktime
|
||||
# undef time
|
||||
# define time tz_time
|
||||
# undef time_t
|
||||
# define time_t tz_time_t
|
||||
|
||||
typedef time_tz time_t;
|
||||
|
||||
char *ctime(time_t const *);
|
||||
char *ctime_r(time_t const *, char *);
|
||||
double difftime(time_t, time_t);
|
||||
struct tm *gmtime(time_t const *);
|
||||
struct tm *gmtime_r(time_t const *restrict, struct tm *restrict);
|
||||
struct tm *localtime(time_t const *);
|
||||
struct tm *localtime_r(time_t const *restrict, struct tm *restrict);
|
||||
time_t mktime(struct tm *);
|
||||
|
||||
static time_t
|
||||
time(time_t *p)
|
||||
{
|
||||
time_t r = sys_time(0);
|
||||
if (p)
|
||||
*p = r;
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Private function declarations.
|
||||
*/
|
||||
|
||||
@@ -37,15 +37,28 @@ Each line ends with
|
||||
if the given time is Daylight Saving Time or
|
||||
.B isdst=0
|
||||
otherwise.
|
||||
.B \-V
|
||||
Like
|
||||
.BR \-v ,
|
||||
except omit the times relative to the extreme time values.
|
||||
This generates output that is easier to compare to that of
|
||||
implementations with different time representations.
|
||||
.TP
|
||||
.BI "\-c " [loyear,]hiyear
|
||||
Cut off verbose output near the start of the given year(s).
|
||||
.TP
|
||||
.BI "\-t " [lotime,]hitime
|
||||
Cut off verbose output at the start of the given time(s),
|
||||
given in seconds since 1970-01-01 00:00:00 UTC.
|
||||
By default,
|
||||
the program cuts off verbose output near the starts of the years -500 and 2500.
|
||||
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
|
||||
and
|
||||
.B \-V
|
||||
options 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
|
||||
|
||||
@@ -9,8 +9,15 @@
|
||||
** This code has been made independent of the rest of the time
|
||||
** conversion package to increase confidence in the verification it provides.
|
||||
** You can use this code to help in verifying other implementations.
|
||||
**
|
||||
** However, include private.h when debugging, so that it overrides
|
||||
** time_t consistently with the rest of the package.
|
||||
*/
|
||||
|
||||
#ifdef time_tz
|
||||
# include "private.h"
|
||||
#endif
|
||||
|
||||
#include "stdio.h" /* for stdout, stderr, perror */
|
||||
#include "string.h" /* for strcpy */
|
||||
#include "sys/types.h" /* for time_t */
|
||||
@@ -112,14 +119,6 @@
|
||||
#endif /* !defined lint */
|
||||
#endif /* !defined GNUC_or_lint */
|
||||
|
||||
#ifndef INITIALIZE
|
||||
#ifdef GNUC_or_lint
|
||||
#define INITIALIZE(x) ((x) = 0)
|
||||
#else /* !defined GNUC_or_lint */
|
||||
#define INITIALIZE(x)
|
||||
#endif /* !defined GNUC_or_lint */
|
||||
#endif /* !defined INITIALIZE */
|
||||
|
||||
#if 2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)
|
||||
# define ATTRIBUTE_PURE __attribute__ ((__pure__))
|
||||
#else
|
||||
@@ -151,20 +150,16 @@ extern char * optarg;
|
||||
extern int optind;
|
||||
extern char * tzname[2];
|
||||
|
||||
/* The minimum and maximum finite time values. Shift 'long long' or
|
||||
'long' instead of 'time_t'; this avoids compile-time errors when
|
||||
time_t is floating-point. In practice, 'long long' is wide enough. */
|
||||
/* The minimum and maximum finite time values. */
|
||||
static time_t const absolute_min_time =
|
||||
((time_t) 0.5 == 0.5
|
||||
? (sizeof (time_t) == sizeof (float) ? (time_t) -FLT_MAX
|
||||
: sizeof (time_t) == sizeof (double) ? (time_t) -DBL_MAX
|
||||
: sizeof (time_t) == sizeof (long double) ? (time_t) -LDBL_MAX
|
||||
: 0)
|
||||
#ifndef TIME_T_FLOATING
|
||||
: (time_t) -1 < 0
|
||||
#ifdef LLONG_MAX
|
||||
? (time_t) ((long long) -1 << (CHAR_BIT * sizeof (time_t) - 1))
|
||||
#else
|
||||
? (time_t) ((long) -1 << (CHAR_BIT * sizeof (time_t) - 1))
|
||||
? (time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1)
|
||||
#endif
|
||||
: 0);
|
||||
static time_t const absolute_max_time =
|
||||
@@ -173,13 +168,11 @@ static time_t const absolute_max_time =
|
||||
: sizeof (time_t) == sizeof (double) ? (time_t) DBL_MAX
|
||||
: sizeof (time_t) == sizeof (long double) ? (time_t) LDBL_MAX
|
||||
: -1)
|
||||
#ifndef TIME_T_FLOATING
|
||||
: (time_t) -1 < 0
|
||||
#ifdef LLONG_MAX
|
||||
? (time_t) (- (~ 0 < 0) - ((long long) -1 << (CHAR_BIT * sizeof (time_t) - 1)))
|
||||
#else
|
||||
? (time_t) (- (~ 0 < 0) - ((long) -1 << (CHAR_BIT * sizeof (time_t) - 1)))
|
||||
? - (~ 0 < 0) - ((time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1))
|
||||
#endif
|
||||
: (time_t) -1);
|
||||
: -1);
|
||||
static size_t longest;
|
||||
static char * progname;
|
||||
static int warned;
|
||||
@@ -270,9 +263,9 @@ static void
|
||||
usage(FILE * const stream, const int status)
|
||||
{
|
||||
(void) fprintf(stream,
|
||||
_("%s: usage is %s [ --version ] [ --help ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n\
|
||||
\n\
|
||||
Report bugs to %s.\n"),
|
||||
_("%s: usage: %s [--version] [--help] [-{vV}] [-{ct} [lo,]hi] zonename ...\n"
|
||||
"\n"
|
||||
"Report bugs to %s.\n"),
|
||||
progname, progname, REPORT_BUGS_TO);
|
||||
exit(status);
|
||||
}
|
||||
@@ -281,11 +274,10 @@ int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
register int i;
|
||||
register int c;
|
||||
register int vflag;
|
||||
register int Vflag;
|
||||
register char * cutarg;
|
||||
register long cutloyear = ZDUMP_LO_YEAR;
|
||||
register long cuthiyear = ZDUMP_HI_YEAR;
|
||||
register char * cuttimes;
|
||||
register time_t cutlotime;
|
||||
register time_t cuthitime;
|
||||
register char ** fakeenv;
|
||||
@@ -297,8 +289,8 @@ main(int argc, char *argv[])
|
||||
register struct tm * tmp;
|
||||
register struct tm * newtmp;
|
||||
|
||||
INITIALIZE(cutlotime);
|
||||
INITIALIZE(cuthitime);
|
||||
cutlotime = absolute_min_time;
|
||||
cuthitime = absolute_max_time;
|
||||
#if HAVE_GETTEXT
|
||||
(void) setlocale(LC_ALL, "");
|
||||
#ifdef TZ_DOMAINDIR
|
||||
@@ -314,22 +306,30 @@ main(int argc, char *argv[])
|
||||
} else if (strcmp(argv[i], "--help") == 0) {
|
||||
usage(stdout, EXIT_SUCCESS);
|
||||
}
|
||||
vflag = 0;
|
||||
cutarg = NULL;
|
||||
while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v')
|
||||
if (c == 'v')
|
||||
vflag = 1;
|
||||
else cutarg = optarg;
|
||||
if ((c != EOF && c != -1) ||
|
||||
(optind == argc - 1 && strcmp(argv[optind], "=") == 0)) {
|
||||
usage(stderr, EXIT_FAILURE);
|
||||
}
|
||||
if (vflag) {
|
||||
if (cutarg != NULL) {
|
||||
long lo;
|
||||
long hi;
|
||||
char dummy;
|
||||
vflag = Vflag = 0;
|
||||
cutarg = cuttimes = NULL;
|
||||
for (;;)
|
||||
switch (getopt(argc, argv, "c:t:vV")) {
|
||||
case 'c': cutarg = optarg; break;
|
||||
case 't': cuttimes = optarg; break;
|
||||
case 'v': vflag = 1; break;
|
||||
case 'V': Vflag = 1; break;
|
||||
case -1:
|
||||
if (! (optind == argc - 1 && strcmp(argv[optind], "=") == 0))
|
||||
goto arg_processing_done;
|
||||
/* Fall through. */
|
||||
default:
|
||||
usage(stderr, EXIT_FAILURE);
|
||||
}
|
||||
arg_processing_done:;
|
||||
|
||||
if (vflag | Vflag) {
|
||||
long lo;
|
||||
long hi;
|
||||
char dummy;
|
||||
register long cutloyear = ZDUMP_LO_YEAR;
|
||||
register long cuthiyear = ZDUMP_HI_YEAR;
|
||||
if (cutarg != NULL) {
|
||||
if (sscanf(cutarg, "%ld%c", &hi, &dummy) == 1) {
|
||||
cuthiyear = hi;
|
||||
} else if (sscanf(cutarg, "%ld,%ld%c",
|
||||
@@ -343,8 +343,36 @@ main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
checkabsolutes();
|
||||
cutlotime = yeartot(cutloyear);
|
||||
cuthitime = yeartot(cuthiyear);
|
||||
if (cutarg != NULL || cuttimes == NULL) {
|
||||
cutlotime = yeartot(cutloyear);
|
||||
cuthitime = yeartot(cuthiyear);
|
||||
}
|
||||
if (cuttimes != NULL) {
|
||||
if (sscanf(cuttimes, "%ld%c", &hi, &dummy) == 1) {
|
||||
if (hi < cuthitime) {
|
||||
if (hi < absolute_min_time)
|
||||
hi = absolute_min_time;
|
||||
cuthitime = hi;
|
||||
}
|
||||
} else if (sscanf(cuttimes, "%ld,%ld%c",
|
||||
&lo, &hi, &dummy) == 2) {
|
||||
if (cutlotime < lo) {
|
||||
if (absolute_max_time < lo)
|
||||
lo = absolute_max_time;
|
||||
cutlotime = lo;
|
||||
}
|
||||
if (hi < cuthitime) {
|
||||
if (hi < absolute_min_time)
|
||||
hi = absolute_min_time;
|
||||
cuthitime = hi;
|
||||
}
|
||||
} else {
|
||||
(void) fprintf(stderr,
|
||||
_("%s: wild -t argument %s\n"),
|
||||
progname, cuttimes);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
(void) time(&now);
|
||||
longest = 0;
|
||||
@@ -375,15 +403,17 @@ main(int argc, char *argv[])
|
||||
static char buf[MAX_STRING_LENGTH];
|
||||
|
||||
(void) strcpy(&fakeenv[0][3], argv[i]);
|
||||
if (!vflag) {
|
||||
if (! (vflag | Vflag)) {
|
||||
show(argv[i], now, FALSE);
|
||||
continue;
|
||||
}
|
||||
warned = FALSE;
|
||||
t = absolute_min_time;
|
||||
show(argv[i], t, TRUE);
|
||||
t += SECSPERHOUR * HOURSPERDAY;
|
||||
show(argv[i], t, TRUE);
|
||||
if (!Vflag) {
|
||||
show(argv[i], t, TRUE);
|
||||
t += SECSPERHOUR * HOURSPERDAY;
|
||||
show(argv[i], t, TRUE);
|
||||
}
|
||||
if (t < cutlotime)
|
||||
t = cutlotime;
|
||||
tmp = my_localtime(&t);
|
||||
@@ -415,11 +445,13 @@ main(int argc, char *argv[])
|
||||
tm = newtm;
|
||||
tmp = newtmp;
|
||||
}
|
||||
t = absolute_max_time;
|
||||
t -= SECSPERHOUR * HOURSPERDAY;
|
||||
show(argv[i], t, TRUE);
|
||||
t += SECSPERHOUR * HOURSPERDAY;
|
||||
show(argv[i], t, TRUE);
|
||||
if (!Vflag) {
|
||||
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: ", progname);
|
||||
|
||||
Reference in New Issue
Block a user