welcome to 2013d

This commit is contained in:
christos 2013-07-17 20:13:04 +00:00
parent 7f55a0953f
commit a37624b5b0
13 changed files with 697 additions and 375 deletions

View File

@ -6,7 +6,7 @@
PACKAGE= tzcode
# Version numbers of the code and data distributions.
VERSION= 2013c
VERSION= 2013d
# Email address for bug reports.
BUGEMAIL= tz@iana.org
@ -53,6 +53,9 @@ TOPDIR= /usr/local
TZDIR= $(TOPDIR)/etc/zoneinfo
# Types to try, as an alternative to time_t. int64_t should be first.
TIME_T_ALTERNATIVES= int64_t int32_t uint32_t uint64_t
# The "tzselect", "zic", and "zdump" commands get installed in. . .
ETCDIR= $(TOPDIR)/etc
@ -98,9 +101,11 @@ LDLIBS=
# Add the following to the end of the "CFLAGS=" line as needed.
# -DHAVE_ADJTIME=0 if `adjtime' does not exist (SVR0?)
# -DHAVE_DOS_FILE_NAMES if file names have drive specifiers etc. (MS-DOS)
# -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_INTTYPES_H=1 if you have a pre-C99 compiler with "inttypes.h"
# -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)
@ -109,23 +114,24 @@ 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
# -DNO_ERROR_IN_DST_GAP=1
# if you want mktime() not to return an error in the DST gap.
# -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 \
@ -191,10 +197,6 @@ GCC_DEBUG_FLAGS = -Dlint -g3 -O3 -fno-common -fstrict-aliasing \
# These functions may well disappear in future releases of the time
# conversion package.
#
# If you want Source Code Control System ID's left out of object modules, add
# -DNOID
# to the end of the "CFLAGS=" line.
#
# If you'll never want to handle solar-time-based time zones, add
# -DNOSOLAR
# to the end of the "CFLAGS=" line
@ -431,9 +433,10 @@ check_tables: checktab.awk $(PRIMARY_YDATA)
check_web: $(WEB_PAGES)
$(VALIDATE_ENV) $(VALIDATE) $(VALIDATE_FLAGS) $(WEB_PAGES)
clean:
clean_misc:
rm -f core *.o *.out \
date tzselect version.h zdump zic yearistype
clean: clean_misc
rm -f -r tzpublic
maintainer-clean: clean
@ -444,7 +447,8 @@ maintainer-clean: clean
names:
@echo $(ENCHILADA)
public: check check_public set-timestamps tarballs signatures
public: check check_public check_time_t_alternatives \
set-timestamps tarballs signatures
# Set the time stamps to those of the git repository, if available,
# and if the files have not changed since then.
@ -475,6 +479,35 @@ check_public: $(ENCHILADA)
$(zic) -v -d tzpublic $(TDATA)
rm -f -r tzpublic
# Check that the code works under various alternative
# implementations of time_t.
check_time_t_alternatives:
mkdir tzpublic
zones=`$(AWK) '/^[^#]/ { print $$3 }' <zone.tab` && \
for type in $(TIME_T_ALTERNATIVES); do \
mkdir tzpublic/$$type && \
make clean_misc && \
make TOPDIR=`pwd`/tzpublic/$$type \
CFLAGS='$(CFLAGS) -Dtime_tz='"'$$type'" \
install && \
diff -qr tzpublic/int64_t/etc/zoneinfo tzpublic/$$type/etc/zoneinfo && \
case $$type in \
int32_t) range=-2147483648,2147483647;; \
uint32_t) range=0,4294967296;; \
int64_t) continue;; \
*u*) range=0,10000000000;; \
*) range=-10000000000,10000000000;; \
esac && \
echo checking $$type zones ... && \
tzpublic/int64_t/etc/zdump -V -t $$range $$zones \
>tzpublic/int64_t.out && \
tzpublic/$$type/etc/zdump -V -t $$range $$zones \
>tzpublic/$$type.out && \
diff -u tzpublic/int64_t.out tzpublic/$$type.out \
|| exit; \
done
rm -f -r tzpublic
tarballs: tzcode$(VERSION).tar.gz tzdata$(VERSION).tar.gz
tzcode$(VERSION).tar.gz: $(COMMON) $(DOCS) $(SOURCES) $(MISC)

View File

@ -264,12 +264,12 @@ in decreasing order of importance:
TZ strings. A file name component must not exceed 14
characters or start with `-'. E.g., prefer `Brunei'
to `Bandar_Seri_Begawan'.
Include at least one location per time zone rule set per country.
One such location is enough. Use ISO 3166 (see the file
iso3166.tab) to help decide whether something is a country.
However, uninhabited ISO 3166 regions like Bouvet Island
Do not use names that differ only in case. Although the reference
implementation is case-sensitive, some other implementations
are not, and they would mishandle names differing only in case.
Uninhabited regions like the North Pole and Bouvet Island
do not need locations, since local time is not defined there.
If all the clocks in a country's region have agreed since 1970,
If all the clocks in a region have agreed since 1970,
don't bother to include more than one location
even if subregions' clocks disagreed before 1970.
Otherwise these tables would become annoyingly large.
@ -283,7 +283,7 @@ in decreasing order of importance:
Use mainstream English spelling, e.g. prefer `Rome' to `Roma', and
prefer `Athens' to the true name (which uses Greek letters).
The POSIX file name restrictions encourage this rule.
Use the most populous among locations in a country's time zone,
Use the most populous among locations in a zone,
e.g. prefer `Shanghai' to `Beijing'. Among locations with
similar populations, pick the best-known location,
e.g. prefer `Rome' to `Milan'.
@ -302,10 +302,11 @@ in decreasing order of importance:
Milan's population has grown to be somewhat greater
than Rome's.
If a name is changed, put its old spelling in the `backward' file.
This means old spellings will continue to work.
The file `zone.tab' lists the geographical locations used to name
time zone rule files. It is intended to be an exhaustive list
of canonical names for geographic regions.
of names for geographic regions as described above.
Older versions of this package used a different naming scheme,
and these older names are still supported.
@ -359,14 +360,13 @@ in decreasing order of importance:
If this is not available or is a phrase mentioning the country
(e.g. ``Cape Verde Time''), then:
When a country has a single or principal time zone region,
When a country is identified with a single or principal zone,
append `T' to the country's ISO code, e.g. `CVT' for
Cape Verde Time. For summer time append `ST';
for double summer time append `DST'; etc.
When a country has multiple time zones, take the first three
letters of an English place name identifying each zone
and then append `T', `ST', etc. as before;
e.g. `VLAST' for VLAdivostok Summer Time.
Otherwise, take the first three letters of an English place
name identifying each zone and append 'T', 'ST', etc.
as before; e.g. 'VLAST' for VLAdivostok Summer Time.
Use UTC (with time zone abbreviation "zzz") for locations while
uninhabited. The "zzz" mnemonic is that these locations are,
@ -587,7 +587,8 @@ Sources:
Michael Allison and Robert Schmunk,
"Technical Notes on Mars Solar Time as Adopted by the Mars24 Sunclock"
<http://www.giss.nasa.gov/tools/mars24/help/notes.html> (2004-07-30).
<http://www.giss.nasa.gov/tools/mars24/help/notes.html> (2012-08-08).
Jia-Rui Chong, "Workdays Fit for a Martian", Los Angeles Times
<http://articles.latimes.com/2004/jan/14/science/sci-marstime14>
(2004-01-14), pp A1, A20-A21.

View File

@ -1,4 +1,4 @@
/* $NetBSD: difftime.c,v 1.13 2012/10/26 23:23:23 christos Exp $ */
/* $NetBSD: difftime.c,v 1.14 2013/07/17 20:13:04 christos Exp $ */
/*
** This file is in the public domain, so clarified as of
@ -10,7 +10,7 @@
#if 0
static char elsieid[] = "@(#)difftime.c 8.1";
#else
__RCSID("$NetBSD: difftime.c,v 1.13 2012/10/26 23:23:23 christos Exp $");
__RCSID("$NetBSD: difftime.c,v 1.14 2013/07/17 20:13:04 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -18,13 +18,12 @@ __RCSID("$NetBSD: difftime.c,v 1.13 2012/10/26 23:23:23 christos Exp $");
#include "private.h" /* for time_t, TYPE_INTEGRAL, and TYPE_SIGNED */
double
double ATTRIBUTE_CONST
difftime(const time_t time1, const time_t 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.
*/
/*CONSTCOND*/
if (sizeof (double) > sizeof (time_t))
@ -44,8 +43,8 @@ difftime(const time_t time1, const time_t time0)
** if the minuend is greater than or equal to the subtrahend.
*/
if (time1 >= time0)
return time1 - time0;
else return -((double) (time0 - time1));
return time1 - time0;
else return -(double) (time0 - time1);
}
/*
** time_t is integral and signed.
@ -56,17 +55,17 @@ difftime(const time_t time1, const time_t time0)
return time1 - time0;
/*
** time1 and time0 have opposite signs.
** Punt if unsigned long is too narrow.
** Punt if uintmax_t is too narrow.
** This suffers from double rounding; attempt to lessen that
** by using long double temporaries.
*/
/* CONSTCOND */
if (sizeof (unsigned long) < sizeof (time_t))
if (sizeof (uintmax_t) < sizeof (time_t))
return (double) time1 - (double) time0;
/*
** Stay calm...decent optimizers will eliminate the complexity below.
*/
if (time1 >= 0 /* && time0 < 0 */)
return (unsigned long) time1 +
(unsigned long) (-(time0 + 1)) + 1;
return -(double) ((unsigned long) time0 +
(unsigned long) (-(time1 + 1)) + 1);
return (uintmax_t) time1 + (uintmax_t) (-(time0 + 1)) + 1;
return -(double) ((uintmax_t) time0 + (uintmax_t) (-(time1 + 1)) + 1);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: localtime.c,v 1.73 2013/03/02 21:24:28 christos Exp $ */
/* $NetBSD: localtime.c,v 1.74 2013/07/17 20:13:04 christos Exp $ */
/*
** This file is in the public domain, so clarified as of
@ -10,7 +10,7 @@
#if 0
static char elsieid[] = "@(#)localtime.c 8.17";
#else
__RCSID("$NetBSD: localtime.c,v 1.73 2013/03/02 21:24:28 christos Exp $");
__RCSID("$NetBSD: localtime.c,v 1.74 2013/07/17 20:13:04 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -97,7 +97,7 @@ static const char gmt[] = "GMT";
#endif /* !defined TZDEFDST */
struct ttinfo { /* time type information */
long tt_gmtoff; /* UTC offset in seconds */
int_fast32_t tt_gmtoff; /* UTC offset in seconds */
int tt_isdst; /* used to set tm_isdst */
int tt_abbrind; /* abbreviation list index */
int tt_ttisstd; /* TRUE if transition is std time */
@ -106,7 +106,7 @@ struct ttinfo { /* time type information */
struct lsinfo { /* leap second information */
time_t ls_trans; /* transition time */
long ls_corr; /* correction to apply */
int_fast64_t ls_corr; /* correction to apply */
};
#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
@ -131,6 +131,7 @@ struct __state {
char chars[/*CONSTCOND*/BIGGEST(BIGGEST(TZ_MAX_CHARS + 1,
sizeof gmt), (2 * (MY_TZNAME_MAX + 1)))];
struct lsinfo lsis[TZ_MAX_LEAPS];
int defaulttype; /* for early times or if no transitions */
};
struct rule {
@ -138,7 +139,7 @@ struct rule {
int r_day; /* day number of rule */
int r_week; /* week number of rule */
int r_mon; /* month number of rule */
long r_time; /* transition time of rule */
int_fast32_t r_time; /* transition time of rule */
};
#define JULIAN_DAY 0 /* Jn - Julian day */
@ -146,49 +147,50 @@ struct rule {
#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
typedef struct tm *(*subfun_t)(const timezone_t sp, const time_t *timep,
long offset, struct tm *tmp);
const int_fast32_t offset, struct tm *tmp);
/*
** Prototypes for static functions.
*/
static long detzcode(const char * codep);
static int_fast32_t detzcode(const char * codep);
static time_t detzcode64(const char * codep);
static int differ_by_repeat(time_t t1, time_t t0);
static const char * getzname(const char * strp) __pure;
static const char * getqzname(const char * strp, const int delim) __pure;
static const char * getzname(const char * strp) ATTRIBUTE_PURE;
static const char * getqzname(const char * strp, const int delim) ATTRIBUTE_PURE;
static const char * getnum(const char * strp, int * nump, int min,
int max);
static const char * getsecs(const char * strp, long * secsp);
static const char * getoffset(const char * strp, long * offsetp);
static const char * getsecs(const char * strp, int_fast32_t * secsp);
static const char * getoffset(const char * strp, int_fast32_t * offsetp);
static const char * getrule(const char * strp, struct rule * rulep);
static void gmtload(timezone_t sp);
static struct tm * gmtsub(const timezone_t sp, const time_t *timep,
long offset, struct tm * tmp);
const int_fast32_t offset, struct tm * tmp);
static struct tm * localsub(const timezone_t sp, const time_t *timep,
long offset, struct tm *tmp);
const int_fast32_t offset, struct tm *tmp);
static int increment_overflow(int * number, int delta);
static int leaps_thru_end_of(int y) __pure;
static int long_increment_overflow(long * number, int delta);
static int long_normalize_overflow(long * tensptr,
static int leaps_thru_end_of(int y) ATTRIBUTE_PURE;
static int increment_overflow(int_fast32_t * number, int delta);
static int normalize_overflow(int_fast32_t * tensptr,
int * unitsptr, int base);
static int normalize_overflow(int * tensptr, int * unitsptr,
int base);
static void settzname(void);
static time_t time1(const timezone_t sp, struct tm * const tmp,
subfun_t funcp, const long offset);
subfun_t funcp, const int_fast32_t offset);
static time_t time2(const timezone_t sp, struct tm * const tmp,
subfun_t funcp,
const long offset, int *const okayp);
const int_fast32_t offset, int *const okayp);
static time_t time2sub(const timezone_t sp, struct tm * const tmp,
subfun_t funcp, const long offset,
subfun_t funcp, const int_fast32_t offset,
int *const okayp, const int do_norm_secs);
static struct tm * timesub(const timezone_t sp, const time_t * timep,
long offset, struct tm * tmp);
const int_fast32_t offset, struct tm * tmp);
static int tmcomp(const struct tm * atmp,
const struct tm * btmp);
static time_t transtime(time_t janfirst, int year,
const struct rule * rulep, long offset) __pure;
const struct rule * rulep,
const int_fast32_t offset) ATTRIBUTE_PURE;
static int typesequiv(const timezone_t sp, int a, int b);
static int tzload(timezone_t sp, const char * name,
int doextend);
@ -196,7 +198,7 @@ static int tzparse(timezone_t sp, const char * name,
int lastditch);
static void tzset_unlocked(void);
static void tzsetwall_unlocked(void);
static long leapcorr(const timezone_t sp, time_t * timep);
static int_fast64_t leapcorr(const timezone_t sp, time_t * timep);
static timezone_t lclptr;
static timezone_t gmtptr;
@ -250,13 +252,13 @@ extern long timezone __RENAME(__timezone13);
time_t altzone = 0;
#endif /* defined ALTZONE */
static long
static int_fast32_t
detzcode(const char *const codep)
{
long result;
int_fast32_t result;
int i;
result = (codep[0] & 0x80) ? ~0L : 0;
result = (codep[0] & 0x80) ? -1 : 0;
for (i = 0; i < 4; ++i)
result = (result << 8) | (codep[i] & 0xff);
return result;
@ -622,6 +624,40 @@ tzload(timezone_t sp, const char *name, const int doextend)
break;
}
}
/*
** If type 0 is is unused in transitions,
** it's the type to use for early times.
*/
for (i = 0; i < sp->typecnt; ++i)
if (sp->types[i] == 0)
break;
i = (i >= sp->typecnt) ? 0 : -1;
/*
** Absent the above,
** if there are transition times
** and the first transition is to a daylight time
** find the standard type less than and closest to
** the type of the first transition.
*/
if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst) {
i = sp->types[0];
while (--i >= 0)
if (!sp->ttis[i].tt_isdst)
break;
}
/*
** If no result yet, find the first standard type.
** If there is none, punt to type zero.
*/
if (i < 0) {
i = 0;
while (sp->ttis[i].tt_isdst)
if (++i >= sp->typecnt) {
i = 0;
break;
}
}
sp->defaulttype = i;
free(up);
return 0;
oops:
@ -739,7 +775,7 @@ getnum(const char *strp, int *const nump, const int min, const int max)
*/
static const char *
getsecs(const char *strp, long *const secsp)
getsecs(const char *strp, int_fast32_t *const secsp)
{
int num;
@ -752,7 +788,7 @@ getsecs(const char *strp, long *const secsp)
strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
if (strp == NULL)
return NULL;
*secsp = num * (long) SECSPERHOUR;
*secsp = num * (int_fast32_t) SECSPERHOUR;
if (*strp == ':') {
++strp;
strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
@ -779,7 +815,7 @@ getsecs(const char *strp, long *const secsp)
*/
static const char *
getoffset(const char *strp, long *const offsetp)
getoffset(const char *strp, int_fast32_t *const offsetp)
{
int neg = 0;
@ -857,7 +893,7 @@ getrule(const char *strp, struct rule *const rulep)
static time_t
transtime(const time_t janfirst, const int year, const struct rule *const rulep,
const long offset)
const int_fast32_t offset)
{
int leapyear;
time_t value;
@ -950,14 +986,14 @@ transtime(const time_t janfirst, const int year, const struct rule *const rulep,
static int
tzparse(timezone_t sp, const char *name, const int lastditch)
{
const char * stdname;
const char * dstname;
size_t stdlen;
size_t dstlen;
long stdoffset;
long dstoffset;
const char * stdname;
const char * dstname;
size_t stdlen;
size_t dstlen;
int_fast32_t stdoffset;
int_fast32_t dstoffset;
time_t * atp;
unsigned char * typep;
unsigned char * typep;
char * cp;
int load_result;
@ -1072,12 +1108,12 @@ tzparse(timezone_t sp, const char *name, const int lastditch)
janfirst = newfirst;
}
} else {
long theirstdoffset;
long theirdstoffset;
long theiroffset;
int isdst;
int i;
int j;
int_fast32_t theirstdoffset;
int_fast32_t theirdstoffset;
int_fast32_t theiroffset;
int isdst;
int i;
int j;
if (*name != '\0')
return -1;
@ -1314,7 +1350,7 @@ tzset(void)
/*ARGSUSED*/
static struct tm *
localsub(const timezone_t sp, const time_t * const timep, const long offset,
localsub(const timezone_t sp, const time_t * const timep, const int_fast32_t offset,
struct tm *const tmp)
{
const struct ttinfo * ttisp;
@ -1363,12 +1399,7 @@ localsub(const timezone_t sp, const time_t * const timep, const long offset,
return result;
}
if (sp->timecnt == 0 || t < sp->ats[0]) {
i = 0;
while (sp->ttis[i].tt_isdst)
if (++i >= sp->typecnt) {
i = 0;
break;
}
i = sp->defaulttype;
} else {
int lo = 1;
int hi = sp->timecnt;
@ -1423,9 +1454,9 @@ struct tm *
localtime_rz(const timezone_t sp, const time_t * __restrict timep, struct tm *tmp)
{
if (sp == NULL)
tmp = gmtsub(NULL, timep, 0L, tmp);
tmp = gmtsub(NULL, timep, 0, tmp);
else
tmp = localsub(sp, timep, 0L, tmp);
tmp = localsub(sp, timep, 0, tmp);
if (tmp == NULL)
errno = EOVERFLOW;
return tmp;
@ -1436,8 +1467,8 @@ localtime_rz(const timezone_t sp, const time_t * __restrict timep, struct tm *tm
*/
static struct tm *
gmtsub(const timezone_t sp, const time_t *const timep, const long offset,
struct tm *const tmp)
gmtsub(const timezone_t sp, const time_t *const timep,
const int_fast32_t offset, struct tm *const tmp)
{
struct tm * result;
#ifdef _REENTRANT
@ -1476,7 +1507,7 @@ gmtsub(const timezone_t sp, const time_t *const timep, const long offset,
struct tm *
gmtime(const time_t *const timep)
{
struct tm *tmp = gmtsub(NULL, timep, 0L, &tm);
struct tm *tmp = gmtsub(NULL, timep, 0, &tm);
if (tmp == NULL)
errno = EOVERFLOW;
@ -1491,7 +1522,7 @@ gmtime(const time_t *const timep)
struct tm *
gmtime_r(const time_t * const timep, struct tm *tmp)
{
tmp = gmtsub(NULL, timep, 0L, tmp);
tmp = gmtsub(NULL, timep, 0, tmp);
if (tmp == NULL)
errno = EOVERFLOW;
@ -1504,7 +1535,14 @@ gmtime_r(const time_t * const timep, struct tm *tmp)
struct tm *
offtime(const time_t *const timep, long offset)
{
struct tm *tmp = gmtsub(NULL, timep, offset, &tm);
struct tm *tmp;
if ((offset > 0 && offset > INT_FAST32_MAX) ||
(offset < 0 && offset > INT_FAST32_MIN)) {
errno = EOVERFLOW;
return NULL;
}
tmp = gmtsub(NULL, timep, (int_fast32_t)offset, &tm);
if (tmp == NULL)
errno = EOVERFLOW;
@ -1515,7 +1553,12 @@ offtime(const time_t *const timep, long offset)
struct tm *
offtime_r(const time_t *timep, long offset, struct tm *tmp)
{
tmp = gmtsub(NULL, timep, offset, tmp);
if ((offset > 0 && offset > INT_FAST32_MAX) ||
(offset < 0 && offset > INT_FAST32_MIN)) {
errno = EOVERFLOW;
return NULL;
}
tmp = gmtsub(NULL, timep, (int_fast32_t)offset, tmp);
if (tmp == NULL)
errno = EOVERFLOW;
@ -1538,16 +1581,16 @@ leaps_thru_end_of(const int y)
}
static struct tm *
timesub(const timezone_t sp, const time_t *const timep, const long offset,
struct tm *const tmp)
timesub(const timezone_t sp, const time_t *const timep,
const int_fast32_t offset, struct tm *const tmp)
{
const struct lsinfo * lp;
time_t tdays;
int idays; /* unsigned would be so 2003 */
long rem;
int_fast64_t rem;
int y;
const int * ip;
long corr;
int_fast64_t corr;
int hit;
int i;
@ -1576,7 +1619,7 @@ timesub(const timezone_t sp, const time_t *const timep, const long offset,
}
y = EPOCH_YEAR;
tdays = (time_t)(*timep / SECSPERDAY);
rem = (long) (*timep - tdays * SECSPERDAY);
rem = (int_fast64_t) (*timep - tdays * SECSPERDAY);
while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
int newy;
time_t tdelta;
@ -1599,11 +1642,12 @@ timesub(const timezone_t sp, const time_t *const timep, const long offset,
y = newy;
}
{
long seconds;
int_fast32_t seconds;
const time_t half_second = 0.5;
seconds = tdays * SECSPERDAY + 0.5;
seconds = (int_fast32_t)(tdays * SECSPERDAY + half_second);
tdays = (time_t)(seconds / SECSPERDAY);
rem += (long) (seconds - tdays * SECSPERDAY);
rem += (int_fast64_t)(seconds - tdays * SECSPERDAY);
}
/*
** Given the range, we can now fearlessly cast...
@ -1735,11 +1779,11 @@ increment_overflow(int *const ip, int j)
}
static int
long_increment_overflow(long *const lp, int m)
increment_overflow32(int_fast32_t *const lp, int const m)
{
long l = *lp;
int_fast32_t l = *lp;
if ((l >= 0) ? (m > LONG_MAX - l) : (m < LONG_MIN - l))
if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
return TRUE;
*lp += m;
return FALSE;
@ -1758,7 +1802,7 @@ normalize_overflow(int *const tensptr, int *const unitsptr, const int base)
}
static int
long_normalize_overflow(long *const tensptr, int *const unitsptr,
normalize_overflow32(int_fast32_t *const tensptr, int *const unitsptr,
const int base)
{
int tensdelta;
@ -1767,7 +1811,7 @@ long_normalize_overflow(long *const tensptr, int *const unitsptr,
(*unitsptr / base) :
(-1 - (-1 - *unitsptr) / base);
*unitsptr -= tensdelta * base;
return long_increment_overflow(tensptr, tensdelta);
return increment_overflow32(tensptr, tensdelta);
}
static int
@ -1786,21 +1830,21 @@ tmcomp(const struct tm *const atmp, const struct tm *const btmp)
static time_t
time2sub(const timezone_t sp, struct tm *const tmp, subfun_t funcp,
const long offset, int *const okayp, const int do_norm_secs)
const int_fast32_t offset, int *const okayp, const int do_norm_secs)
{
int dir;
int i, j;
int saved_seconds;
long li;
int_fast32_t li;
time_t lo;
time_t hi;
#ifdef NO_ERROR_IN_DST_GAP
time_t ilo;
#endif
long y;
time_t newt;
time_t t;
struct tm yourtm, mytm;
int_fast32_t y;
time_t newt;
time_t t;
struct tm yourtm, mytm;
*okayp = FALSE;
yourtm = *tmp;
@ -1817,16 +1861,16 @@ again:
if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
goto overflow;
y = yourtm.tm_year;
if (long_normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR))
if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR))
goto overflow;
/*
** Turn y into an actual year number for now.
** It is converted back to an offset from TM_YEAR_BASE later.
*/
if (long_increment_overflow(&y, TM_YEAR_BASE))
if (increment_overflow32(&y, TM_YEAR_BASE))
goto overflow;
while (yourtm.tm_mday <= 0) {
if (long_increment_overflow(&y, -1))
if (increment_overflow32(&y, -1))
goto overflow;
li = y + (1 < yourtm.tm_mon);
yourtm.tm_mday += year_lengths[isleap(li)];
@ -1834,7 +1878,7 @@ again:
while (yourtm.tm_mday > DAYSPERLYEAR) {
li = y + (1 < yourtm.tm_mon);
yourtm.tm_mday -= year_lengths[isleap(li)];
if (long_increment_overflow(&y, 1))
if (increment_overflow32(&y, 1))
goto overflow;
}
for ( ; ; ) {
@ -1844,11 +1888,11 @@ again:
yourtm.tm_mday -= i;
if (++yourtm.tm_mon >= MONSPERYEAR) {
yourtm.tm_mon = 0;
if (long_increment_overflow(&y, 1))
if (increment_overflow32(&y, 1))
goto overflow;
}
}
if (long_increment_overflow(&y, -TM_YEAR_BASE))
if (increment_overflow32(&y, -TM_YEAR_BASE))
goto overflow;
yourtm.tm_year = (int)y;
if (yourtm.tm_year != y)
@ -2000,7 +2044,7 @@ invalid:
static time_t
time2(const timezone_t sp, struct tm *const tmp, subfun_t funcp,
const long offset, int *const okayp)
const int_fast32_t offset, int *const okayp)
{
time_t t;
@ -2015,7 +2059,7 @@ time2(const timezone_t sp, struct tm *const tmp, subfun_t funcp,
static time_t
time1(const timezone_t sp, struct tm *const tmp, subfun_t funcp,
const long offset)
const int_fast32_t offset)
{
time_t t;
int samei, otheri;
@ -2092,9 +2136,9 @@ mktime_z(const timezone_t sp, struct tm *const tmp)
{
time_t t;
if (sp == NULL)
t = time1(NULL, tmp, gmtsub, 0L);
t = time1(NULL, tmp, gmtsub, 0);
else
t = time1(sp, tmp, localsub, 0L);
t = time1(sp, tmp, localsub, 0);
return t;
}
@ -2135,18 +2179,23 @@ timegm(struct tm *const tmp)
if (tmp != NULL)
tmp->tm_isdst = 0;
t = time1(gmtptr, tmp, gmtsub, 0L);
t = time1(gmtptr, tmp, gmtsub, 0);
return t;
}
time_t
timeoff(struct tm *const tmp, const long offset)
timeoff(struct tm *const tmp, long offset)
{
time_t t;
if ((offset > 0 && offset > INT_FAST32_MAX) ||
(offset < 0 && offset > INT_FAST32_MIN)) {
errno = EOVERFLOW;
return -1;
}
if (tmp != NULL)
tmp->tm_isdst = 0;
t = time1(gmtptr, tmp, gmtsub, offset);
t = time1(gmtptr, tmp, gmtsub, (int_fast32_t)offset);
return t;
}
@ -2159,7 +2208,7 @@ timeoff(struct tm *const tmp, const long offset)
** previous versions of the CMUCS runtime library.
*/
long
int_fast32_t
gtime(struct tm *const tmp)
{
const time_t t = mktime(tmp);
@ -2185,7 +2234,7 @@ gtime(struct tm *const tmp)
** when exchanging timestamps with POSIX conforming systems.
*/
static long
static int_fast64_t
leapcorr(const timezone_t sp, time_t *timep)
{
struct lsinfo * lp;

View File

@ -1,4 +1,4 @@
/* $NetBSD: private.h,v 1.28 2012/10/26 23:23:23 christos Exp $ */
/* $NetBSD: private.h,v 1.29 2013/07/17 20:13:04 christos Exp $ */
#ifndef PRIVATE_H
#define PRIVATE_H
@ -136,19 +136,65 @@
#include "stdint.h"
#endif /* !HAVE_STDINT_H */
#ifndef HAVE_INTTYPES_H
# define HAVE_INTTYPES_H HAVE_STDINT_H
#endif
#if HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#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;
# ifdef LLONG_MAX
# define INT_FAST64_MIN LLONG_MIN
# define INT_FAST64_MAX LLONG_MAX
# else
# define INT_FAST64_MIN __LONG_LONG_MIN__
# define INT_FAST64_MAX __LONG_LONG_MAX__
# endif
# define SCNdFAST64 "lld"
#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;
# define INT_FAST64_MIN LONG_MIN
# define INT_FAST64_MAX LONG_MAX
# define SCNdFAST64 "ld"
#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
#endif /* !defined INT_FAST64_MAX */
#ifndef INT_FAST32_MAX
# if INT_MAX >> 31 == 0
typedef long int_fast32_t;
# else
typedef int int_fast32_t;
# endif
#endif
#ifndef INTMAX_MAX
# if defined LLONG_MAX || defined __LONG_LONG_MAX__
typedef long long intmax_t;
# define PRIdMAX "lld"
# else
typedef long intmax_t;
# define PRIdMAX "ld"
# endif
#endif
#ifndef UINTMAX_MAX
# if defined ULLONG_MAX || defined __LONG_LONG_MAX__
typedef unsigned long long uintmax_t;
# define PRIuMAX "llu"
# else
typedef unsigned long uintmax_t;
# define PRIuMAX "lu"
# endif
#endif
#ifndef INT32_MAX
#define INT32_MAX 0x7fffffff
#endif /* !defined INT32_MAX */
@ -156,12 +202,24 @@ typedef long int_fast64_t;
#define INT32_MIN (-1 - INT32_MAX)
#endif /* !defined INT32_MIN */
#ifndef __pure
#if 2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)
# define __pure __attribute__ ((__pure__))
#if 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
# define ATTRIBUTE_CONST __attribute__ ((__const__))
# define ATTRIBUTE_PURE __attribute__ ((__pure__))
#else
# define __pure /* empty */
# define ATTRIBUTE_CONST /* empty */
# define ATTRIBUTE_PURE /* empty */
#endif
#if !defined _Noreturn && __STDC_VERSION__ < 201112
# if 2 < __GNUC__ + (8 <= __GNUC_MINOR__)
# define _Noreturn __attribute__ ((__noreturn__))
# else
# define _Noreturn
# endif
#endif
#if __STDC_VERSION__ < 199901 && !defined restrict
# define restrict /* empty */
#endif
/*
@ -178,6 +236,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.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: scheck.c,v 1.9 2012/10/24 00:10:03 christos Exp $ */
/* $NetBSD: scheck.c,v 1.10 2013/07/17 20:13:04 christos Exp $ */
/*
** This file is in the public domain, so clarified as of
@ -15,7 +15,7 @@
#if 0
static char elsieid[] = "@(#)scheck.c 8.19";
#else
__RCSID("$NetBSD: scheck.c,v 1.9 2012/10/24 00:10:03 christos Exp $");
__RCSID("$NetBSD: scheck.c,v 1.10 2013/07/17 20:13:04 christos Exp $");
#endif
#endif /* !defined lint */
@ -41,26 +41,35 @@ scheck(const char *const string, const char *const format)
return result;
fp = format;
tp = fbuf;
/*
** Copy directives, suppressing each conversion that is not
** already suppressed. Scansets containing '%' are not
** supported; e.g., the conversion specification "%[%]" is not
** supported. Also, multibyte characters containing a
** non-leading '%' byte are not supported.
*/
while ((*tp++ = c = *fp++) != '\0') {
if (c != '%')
continue;
if (*fp == '%') {
*tp++ = *fp++;
continue;
if (is_digit(*fp)) {
char const *f = fp;
char *t = tp;
do {
*t++ = c = *f++;
} while (is_digit(c));
if (c == '$') {
fp = f;
tp = t;
}
}
*tp++ = '*';
if (*fp == '*')
++fp;
while (is_digit(*fp))
*tp++ = *fp++;
if (*fp == 'l' || *fp == 'h')
*tp++ = *fp++;
else if (*fp == '[')
do *tp++ = *fp++;
while (*fp != '\0' && *fp != ']');
if ((*tp++ = *fp++) == '\0')
break;
}
*(tp - 1) = '%';
*tp++ = 'c';
*tp = '\0';

View File

@ -1,4 +1,4 @@
/* $NetBSD: strftime.c,v 1.26 2013/05/17 12:55:57 joerg Exp $ */
/* $NetBSD: strftime.c,v 1.27 2013/07/17 20:13:04 christos Exp $ */
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
@ -6,7 +6,7 @@
static char elsieid[] = "@(#)strftime.c 7.64";
static char elsieid[] = "@(#)strftime.c 8.3";
#else
__RCSID("$NetBSD: strftime.c,v 1.26 2013/05/17 12:55:57 joerg Exp $");
__RCSID("$NetBSD: strftime.c,v 1.27 2013/07/17 20:13:04 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -314,11 +314,10 @@ label:
mkt = mktime(&tm);
/* CONSTCOND */
if (TYPE_SIGNED(time_t))
(void) snprintf(buf, sizeof(buf),
"%lld", (long long) mkt);
else (void) snprintf(buf, sizeof(buf),
"%llu", (unsigned long long)
mkt);
(void)snprintf(buf, sizeof(buf),
"%jd", (intmax_t) mkt);
else (void)snprintf(buf, sizeof(buf),
"%ju", (uintmax_t) mkt);
pt = _add(buf, pt, ptlim);
}
continue;

View File

@ -235,7 +235,7 @@ Supernaw.</td></tr>
<tr><td><a href="http://www.allmusic.com/cg/amg.dll?p=amg&sql=10:3bftxzw0ldhe"</a>AMG Rating</a></td><td>3.5 stars</td></tr>
<tr><td>ADO Rating</td><td>2.5 stars</td></tr>
<tr><td>Notes<td>Includes the song "Fire and Wood" with the lyric
"The clocks were turned back you remeber/Think it's still November."
"The clocks were turned back you remember/Think it's still November."
</td></tr>
<tr><td>&nbsp;</td></tr>
<tr><td>Artist</td><td>Ken Nordine</td></tr>
@ -431,10 +431,10 @@ hilarity ensues.
<hr>
<ul>
<li>
"We're been using the five-cent nickle in this country since 1492.
Now that's pretty near 100 years, daylight savings [sic]."
"We've been using the five-cent nickel in this country since 1492.
Now that's pretty near 100 years, daylight saving."
(Groucho Marx as Captain Spaulding in "Animal Crackers", 1930,
as noted by Will Fitzerald)
as noted by Will Fitzgerald)
</li>
<li>
Brady: "...[Bishop Usher] determined that the Lord began the Creation

View File

@ -8,7 +8,7 @@
<meta http-equiv="Content-type" content='text/html; charset="US-ASCII"'>
<meta name="DC.Creator" content="Eggert, Paul">
<meta name="DC.Contributor" content="Olson, Arthur David">
<meta name="DC.Date" content="2013-03-11">
<meta name="DC.Date" content="2013-07-03">
<meta name="DC.Description"
content="Sources of information about time zones and daylight saving time">
<meta name="DC.Identifier"
@ -31,8 +31,7 @@ href="http://en.wikipedia.org/wiki/Coordinated_Universal_Time"><abbr
title="Coordinated Universal Time">UTC</abbr></a> offsets, and
<a href="http://en.wikipedia.org/wiki/Daylight_saving">daylight-saving</a>
rules.
This database (often called <code>zoneinfo</code> or <a
href="http://en.wikipedia.org/wiki/Tz_database"><code>tz</code></a>)
This database (often called <code>zoneinfo</code> or <code>tz</code>)
is used by several implementations,
including
<a href="http://www.gnu.org/software/libc/">the
@ -40,6 +39,8 @@ including
C Library</a> (used in
<a href="http://www.linux.org/"><abbr>GNU</abbr>/Linux</a>),
<a href="http://www.android.com/">Android</a>,
<a href="https://developer.mozilla.org/en-US/docs/Mozilla/Firefox_OS">Firefox
OS</a>,
<a href="http://www.freebsd.org/">FreeBSD</a>,
<a href="http://netbsd.org/">NetBSD</a>,
<a href="http://openbsd.org/">OpenBSD</a>,
@ -134,6 +135,17 @@ For Comments">RFC</abbr> 6557).</p>
The Web has several other sources for time zone and daylight saving time data.
Here are some links that may be of interest.
</p>
<h2>Commentary on the <code>tz</code> database</h2>
<ul>
<li>The article
<a href="http://en.wikipedia.org/wiki/Tz_database">tz database</a> is
an encyclopedic summary.</li>
<li><a href="http://www.cstdbill.com/tzdb/tz-how-to.html">How to Read the
tz Database Source Files</a> explains the tz database format.</li>
<li><a href="http://blog.jonudell.net/2009/10/23/a-literary-appreciation-of-the-olsonzoneinfotz-database/">A
literary appreciation of the Olson/Zoneinfo/tz database</a> comments on the
database's style.</li>
</ul>
<h2>Web sites using recent versions of the <code>tz</code> database</h2>
<p>
These are listed roughly in ascending order of complexity and fanciness.
@ -176,8 +188,8 @@ href="http://calconnect.org/publications/icalendartimezoneproblemsandrecommendat
TIMEZONE Problems and Recommendations</a> offers guidelines and
recommendations for the use of VTIMEZONE and <code>tz</code>.</li>
<li><a href="http://calconnect.org/dstlinks.shtml">Extended Daylight
Saving Time Links, Advisories and Changes</a> lists vendor material on recent
daylight saving time changes.</li>
Saving Time Links, Advisories and Changes</a> lists vendor material on 2007
U.S. daylight saving time changes.</li>
<li><a
href="http://calconnect.org/publications/timezoneregistryandservicerecommendationsv1.0.pdf">Timezone
Registry and Service Recommendations</a> discusses a
@ -235,16 +247,16 @@ contains a class
<code>org.joda.time.tz.ZoneInfoCompiler</code> that compiles
<code>tz</code> source into a Joda-specific binary format. Joda Time
is freely available under a <abbr>BSD</abbr>-style license.</li>
<li><a href="http://pytz.sourceforge.net">PyTZ - Python Time
Zone Library</a> compiles <code>tz</code> source into
<li><a href="http://pytz.sourceforge.net">pytz - World Timezone
Definitions for Python</a> compiles <code>tz</code> source into
<a href="http://python.org/">Python</a>.
It is freely available under a <abbr>BSD</abbr>-style license.</li>
<li><a href="http://tzinfo.rubyforge.org/">TZInfo - Ruby Timezone Library</a>
compiles <code>tz</code> source into
<a href="http://ruby-lang.org">Ruby</a>.
<a href="http://www.ruby-lang.org/en/">Ruby</a>.
It is freely available under the <abbr
title="Massachusetts Institute of Technology">MIT</abbr> license.</li>
<li>The <a href="http://chronos-st.org/">Chronos Date/Time
<li>The <a href="http://www.squeaksource.com/Chronos/">Chronos Date/Time
Library</a> is
a <a href="http://en.wikipedia.org/wiki/Smalltalk">Smalltalk</a> class
library that compiles <code>tz</code> source into a time zone repository whose format
@ -331,7 +343,7 @@ time zone history atlases published in both <a
href="http://astrocom.com/astrology-products/software/acs-atlas-software">computer</a>
and book form (<a
href="http://www.astrocom.com/astrology/books/american-atlas">one volume
for the USA</a>, and <a
for the U.S.</a>, and <a
href="http://www.astrocom.com/astrology/books/international-atlas">one for
other locations</a>) by <a
href="http://astrocom.com/">Astro Computing Services</a>.</li>
@ -353,7 +365,7 @@ gives current time zone rules for airports served by commercial aviation.</li>
<li>Some Microsoft Windows versions contain time zone information in
an undocumented format, with IDs that can be mapped to <code>TZ</code>
values using the <a
href="http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html">Zone
href="http://unicode.org/cldr/charts/supplemental/zone_tzid.html">Zone
&rarr; Tzid table</a> maintained by the <abbr
title="Common Locale Data Repository">CLDR</abbr> data mentioned
below.</li>
@ -421,6 +433,9 @@ surveys the evolution of timekeeping.</li>
<li><a href="http://webexhibits.org/daylightsaving/">About Daylight
Saving Time - History, rationale, laws &amp; dates</a>
is an overall history of <abbr>DST</abbr>.</li>
<li><a href="http://www.w3.org/TR/timezone/">Working with Time Zones</a>
contains guidelines and best practices for software applications that
deal with civil time.</li>
<li><a href="http://energy.ca.gov/daylightsaving.html">Saving Time,
Saving Energy</a> discusses a primary justification for <abbr>DST</abbr>.</li>
<li><a href="http://seizethedaylight.com/dst/">A Brief
@ -499,7 +514,7 @@ href="http://www.polyomino.org.uk/british-time/">History of
legal time in Britain</a> discusses in detail the country
with perhaps the best-documented history of clock adjustments.
The National Physical Laboratory also maintains an <a
href="http://www.npl.co.uk/educate-explore/what-is-the-time/archive-of-summer-time-dates-1916-2006">Archive
href="http://www.npl.co.uk/educate-explore/what-is-time/archive-of-summer-time-dates-1916-2006">Archive
of Summer time dates</a>.</dd>
</dl>
<h2>Precision timekeeping</h2>
@ -578,8 +593,8 @@ contentious issue.</li>
<h2>Time notation</h2>
<ul>
<li>
<a href="http://www.cl.cam.ac.uk/~mgk25/iso-time.html">A Summary of
the International Standard Date and Time Notation</a> is a good
<a href="http://www.cl.cam.ac.uk/~mgk25/iso-time.html">A summary of
the international standard date and time notation</a> is a good
summary of
<a
href="http://www.iso.org/iso/catalogue_detail?csnumber=40874"><abbr

View File

@ -1,4 +1,4 @@
/* $NetBSD: tzfile.h,v 1.10 2012/08/09 12:38:25 christos Exp $ */
/* $NetBSD: tzfile.h,v 1.11 2013/07/17 20:13:04 christos Exp $ */
#ifndef TZFILE_H
#define TZFILE_H
@ -123,7 +123,7 @@ struct tzhead {
#define DAYSPERNYEAR 365
#define DAYSPERLYEAR 366
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
#define MONSPERYEAR 12
#define TM_SUNDAY 0

View File

@ -1,5 +1,5 @@
.\" $NetBSD: zdump.8,v 1.9 2012/08/09 12:38:26 christos Exp $
.Dd October 29, 2003
.\" $NetBSD: zdump.8,v 1.10 2013/07/17 20:13:04 christos Exp $
.Dd July 17, 2013
.Dt ZDUMP 8
.Os
.Sh NAME
@ -9,8 +9,13 @@
.Nm zdump
.Op Fl \-version
.Op Fl v
.Op Fl V
.Op Fl c Ar [loyear,]highyear
.Op Ar zonename ...
.Nm zdump
.Fl t
.Ar [loyear,]highyear
.Op Ar zonename ...
.Sh DESCRIPTION
.Nm
prints the current time in each
@ -39,12 +44,23 @@ otherwise.
.It Fl c Ar [loyear,]highyear
Cut off the 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.
the program cuts off verbose output near the starts of the years \-500 and 2500.
.It Fl t Ar [loyear,]highyear
Cut off verbose output at the start of the given time(s),
given in decimal seconds since 1970-01-01 00:00:00 UTC.
.It Fl V
Like
.Fl 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.
.El
.Sh LIMITATIONS
The
.Fl v
option may not be used on systems with floating-point time_t values
and
.Fl 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

View File

@ -1,4 +1,4 @@
/* $NetBSD: zdump.c,v 1.28 2013/03/02 21:24:28 christos Exp $ */
/* $NetBSD: zdump.c,v 1.29 2013/07/17 20:13:04 christos Exp $ */
/*
** This file is in the public domain, so clarified as of
** 2009-05-17 by Arthur David Olson.
@ -6,7 +6,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: zdump.c,v 1.28 2013/03/02 21:24:28 christos Exp $");
__RCSID("$NetBSD: zdump.c,v 1.29 2013/07/17 20:13:04 christos Exp $");
#endif /* !defined lint */
#include "version.h"
@ -14,8 +14,13 @@ __RCSID("$NetBSD: zdump.c,v 1.28 2013/03/02 21:24:28 christos Exp $");
** 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.
*/
#include "private.h"
#include "stdio.h" /* for stdout, stderr */
#include "string.h" /* for strcpy */
#include "sys/types.h" /* for time_t */
@ -28,7 +33,46 @@ __RCSID("$NetBSD: zdump.c,v 1.28 2013/03/02 21:24:28 christos Exp $");
#define isascii(x) 1
#endif /* !defined isascii */
#include "private.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__ + (0 < __GLIBC_MINOR__)))
#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
#ifndef INTMAX_MAX
# if defined LLONG_MAX || defined __LONG_LONG_MAX__
typedef long long intmax_t;
# define PRIdMAX "lld"
# else
typedef long intmax_t;
# define PRIdMAX "ld"
# endif
#endif
#ifndef SCNdMAX
# define SCNdMAX PRIdMAX
#endif
#ifndef ZDUMP_LO_YEAR
#define ZDUMP_LO_YEAR (-500)
@ -97,7 +141,7 @@ __RCSID("$NetBSD: zdump.c,v 1.28 2013/03/02 21:24:28 christos Exp $");
#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
#endif /* !defined isleap_sum */
#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
#define SECSPERNYEAR (SECSPERDAY * DAYSPERNYEAR)
#define SECSPERLYEAR (SECSPERNYEAR + SECSPERDAY)
@ -119,11 +163,11 @@ __RCSID("$NetBSD: zdump.c,v 1.28 2013/03/02 21:24:28 christos Exp $");
#endif /* !defined lint */
#endif /* !defined GNUC_or_lint */
#ifndef __pure
#ifndef ATTRIBUTE_PURE
#if 2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)
# define __pure __attribute__ ((__pure__))
# define ATTRIBUTE_PURE __attribute__ ((ATTRIBUTE_PURE__))
#else
# define __pure /* empty */
# define ATTRIBUTE_PURE /* empty */
#endif
#endif
@ -159,22 +203,42 @@ extern int getopt(int argc, char * const argv[],
extern char * optarg;
extern int optind;
static time_t absolute_min_time;
static time_t absolute_max_time;
/* The minimum and maximum finite time values. */
static time_t 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
? (time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1)
#endif
: 0);
static time_t absolute_max_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
: -1)
#ifndef TIME_T_FLOATING
: (time_t) -1 < 0
? - (~ 0 < 0) - ((time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1))
#endif
: -1);
static size_t longest;
static char * progname;
static int warned;
static const char * abbr(struct tm * tmp);
static void abbrok(const char * abbrp, const char * zone);
static long delta(struct tm * newp, struct tm * oldp) __pure;
static intmax_t delta(struct tm * newp, struct tm * oldp) ATTRIBUTE_PURE;
static void dumptime(const struct tm * tmp);
static time_t hunt(char * name, time_t lot, time_t hit);
int main(int, char **);
static void setabsolutes(void);
static void checkabsolutes(void);
static void show(char * zone, time_t t, int v);
static const char * tformat(void);
static time_t yeartot(long y) __pure;
static time_t yeartot(long y) ATTRIBUTE_PURE;
#ifndef TYPECHECK
#define my_localtime localtime
@ -252,9 +316,9 @@ __dead 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);
}
@ -263,11 +327,10 @@ int
main(int argc, char *argv[])
{
int i;
int c;
int vflag;
int Vflag;
char * cutarg;
long cutloyear = ZDUMP_LO_YEAR;
long cuthiyear = ZDUMP_HI_YEAR;
char * cuttimes;
time_t cutlotime;
time_t cuthitime;
char ** fakeenv;
@ -279,8 +342,8 @@ main(int argc, char *argv[])
struct tm * tmp;
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
@ -296,25 +359,33 @@ 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 (sscanf(cutarg, "%ld%c", &hi, &dummy) == 1) {
if (vflag | Vflag) {
intmax_t lo;
intmax_t hi;
char dummy;
register intmax_t cutloyear = ZDUMP_LO_YEAR;
register intmax_t cuthiyear = ZDUMP_HI_YEAR;
if (cutarg != NULL) {
if (sscanf(cutarg, "%"SCNdMAX"%c", &hi, &dummy) == 1) {
cuthiyear = hi;
} else if (sscanf(cutarg, "%ld,%ld%c",
} else if (sscanf(cutarg, "%"SCNdMAX",%"SCNdMAX"%c",
&lo, &hi, &dummy) == 2) {
cutloyear = lo;
cuthiyear = hi;
@ -324,9 +395,37 @@ main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
}
setabsolutes();
cutlotime = yeartot(cutloyear);
cuthitime = yeartot(cuthiyear);
checkabsolutes();
if (cutarg != NULL || cuttimes == NULL) {
cutlotime = yeartot(cutloyear);
cuthitime = yeartot(cuthiyear);
}
if (cuttimes != NULL) {
if (sscanf(cuttimes, "%"SCNdMAX"%c", &hi, &dummy) == 1) {
if (hi < cuthitime) {
if (hi < absolute_min_time)
hi = absolute_min_time;
cuthitime = hi;
}
} else if (sscanf(cuttimes, "%"SCNdMAX",%"SCNdMAX"%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;
@ -357,15 +456,17 @@ main(int argc, char *argv[])
static char buf[MAX_STRING_LENGTH];
(void) strcpy(&fakeenv[0][3], argv[i]); /* XXX strcpy is safe */
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);
@ -397,11 +498,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)) {
err(EXIT_FAILURE, _("Error writing standard output"));
@ -411,64 +514,23 @@ main(int argc, char *argv[])
return EXIT_FAILURE;
}
static time_t
ovfl_check(time_t t)
{
if (t < 0 && t - 1 >= 0)
return t;
else
return t - 1;
}
static void
setabsolutes(void)
checkabsolutes(void)
{
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,
if (absolute_max_time < absolute_min_time) {
(void) fprintf(stderr,
_("%s: use of -v on system with floating time_t other than float or double\n"),
progname);
exit(EXIT_FAILURE);
}
} else if (0 > (time_t) -1) {
/*
** time_t is signed. Assume overflow wraps around.
*/
time_t t = 0;
time_t t1 = 1;
while (t < t1) {
t = t1;
t1 = 2 * t1 + 1;
}
absolute_max_time = t;
t = -t;
absolute_min_time = ovfl_check(t);
} else {
/*
** time_t is unsigned.
*/
absolute_min_time = 0;
absolute_max_time = absolute_min_time - 1;
progname);
exit(EXIT_FAILURE);
}
}
static time_t
yeartot(const long y)
{
long myy;
long seconds;
time_t t;
intmax_t myy;
int_fast32_t seconds;
time_t t;
myy = EPOCH_YEAR;
t = 0;
@ -498,7 +560,6 @@ static time_t
hunt(char *name, time_t lot, time_t hit)
{
time_t t;
long diff;
struct tm lotm;
struct tm * lotmp;
struct tm tm;
@ -511,7 +572,7 @@ hunt(char *name, time_t lot, time_t hit)
(void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1);
}
for ( ; ; ) {
diff = (long) (hit - lot);
time_t diff = hit - lot;
if (diff < 2)
break;
t = lot;
@ -541,11 +602,11 @@ hunt(char *name, time_t lot, time_t hit)
** Thanks to Paul Eggert for logic used in delta.
*/
static long
static intmax_t
delta(struct tm *newp, struct tm *oldp)
{
long result;
int tmy;
intmax_t result;
int tmy;
if (newp->tm_year < oldp->tm_year)
return -delta(oldp, newp);
@ -621,12 +682,18 @@ tformat(void)
return "%g";
}
if (0 > (time_t) -1) { /* signed */
if (sizeof (time_t) == sizeof (intmax_t))
return "%"PRIdMAX;
if (sizeof (time_t) > sizeof (long))
return "%lld";
if (sizeof (time_t) > sizeof (int))
return "%ld";
return "%d";
}
#ifdef PRIuMAX
if (sizeof (time_t) == sizeof (uintmax_t))
return "%"PRIuMAX;
#endif
if (sizeof (time_t) > sizeof (unsigned long))
return "%llu";
if (sizeof (time_t) > sizeof (unsigned int))

View File

@ -1,4 +1,4 @@
/* $NetBSD: zic.c,v 1.40 2013/03/06 18:40:19 christos Exp $ */
/* $NetBSD: zic.c,v 1.41 2013/07/17 20:13:04 christos Exp $ */
/*
** This file is in the public domain, so clarified as of
** 2006-07-17 by Arthur David Olson.
@ -10,7 +10,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: zic.c,v 1.40 2013/03/06 18:40:19 christos Exp $");
__RCSID("$NetBSD: zic.c,v 1.41 2013/07/17 20:13:04 christos Exp $");
#endif /* !defined lint */
#include "version.h"
@ -20,11 +20,10 @@ __RCSID("$NetBSD: zic.c,v 1.40 2013/03/06 18:40:19 christos Exp $");
#define ZIC_VERSION '2'
typedef intmax_t zic_t;
#define TIME_T_BITS_IN_FILE 64
static const zic_t min_time = INTMAX_MIN;
static const zic_t max_time = INTMAX_MAX;
typedef int_fast64_t zic_t;
#define ZIC_MIN INT_FAST64_MIN
#define ZIC_MAX INT_FAST64_MAX
#define SCNdZIC SCNdFAST64
#ifndef ZIC_MAX_ABBR_LEN_WO_WARN
#define ZIC_MAX_ABBR_LEN_WO_WARN 6
@ -61,8 +60,8 @@ struct rule {
int r_linenum;
const char * r_name;
int r_loyear; /* for example, 1986 */
int r_hiyear; /* for example, 1986 */
zic_t r_loyear; /* for example, 1986 */
zic_t r_hiyear; /* for example, 1986 */
const char * r_yrtype;
int r_lowasnum;
int r_hiwasnum;
@ -124,7 +123,6 @@ static void leapadd(zic_t t, int positive, int rolling, int count);
static void adjleap(void);
static void associate(void);
static void dolink(const char * fromfield, const char * tofield);
static zic_t eitol(int i);
static char ** getfields(char * buf);
static zic_t gethms(const char * string, const char * errstrng,
int signable);
@ -143,7 +141,7 @@ static void newabbr(const char * abbr);
static zic_t oadd(zic_t t1, zic_t t2);
static void outzone(const struct zone * zp, int ntzones);
static int rcomp(const void * leftp, const void * rightp);
static zic_t rpytime(const struct rule * rp, int wantedy);
static zic_t rpytime(const struct rule * rp, zic_t wantedy);
static void rulesub(struct rule * rp,
const char * loyearp, const char * hiyearp,
const char * typep, const char * monthp,
@ -151,20 +149,20 @@ static void rulesub(struct rule * rp,
static zic_t tadd(zic_t t1, zic_t t2);
static int yearistype(int year, const char * type);
static int atcomp(const void *avp, const void *bvp);
static void updateminmax(int x);
static void updateminmax(zic_t x);
static int charcnt;
static int errors;
static const char * filename;
static int leapcnt;
static int leapseen;
static int leapminyear;
static int leapmaxyear;
static zic_t leapminyear;
static zic_t leapmaxyear;
static int linenum;
static size_t max_abbrvar_len;
static size_t max_format_len;
static int max_year;
static int min_year;
static zic_t max_year;
static zic_t min_year;
static int noise;
static const char * rfilename;
static int rlinenum;
@ -369,7 +367,7 @@ static char roll[TZ_MAX_LEAPS];
** Memory allocation.
*/
static __pure void *
static ATTRIBUTE_PURE void *
memcheck(void *const ptr)
{
if (ptr == NULL) {
@ -436,7 +434,7 @@ warning(const char *const string)
--errors;
}
__dead static void
static _Noreturn void
usage(FILE *stream, int status)
{
(void) fprintf(stream, _("%s: usage is %s \
@ -461,9 +459,9 @@ main(int argc, char *argv[])
int j;
int c;
#ifdef _POSIX_VERSION
#ifdef S_IWGRP
(void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH));
#endif /* defined _POSIX_VERSION */
#endif
#if HAVE_GETTEXT - 0
(void) setlocale(LC_MESSAGES, "");
#ifdef TZ_DOMAINDIR
@ -660,6 +658,11 @@ warning(_("hard link failed, symbolic link used"));
free(toname);
}
#define TIME_T_BITS_IN_FILE 64
static const zic_t min_time = (zic_t) -1 << (TIME_T_BITS_IN_FILE - 1);
static const zic_t max_time = -1 - ((zic_t) -1 << (TIME_T_BITS_IN_FILE - 1));
static int
itsdir(const char *const name)
{
@ -880,11 +883,11 @@ gethms(const char *string, const char *const errstring, const int signable)
sign = -1;
++string;
} else sign = 1;
if (sscanf(string, scheck(string, "%jd"), &hh) == 1)
if (sscanf(string, scheck(string, "%"SCNdZIC), &hh) == 1)
mm = ss = 0;
else if (sscanf(string, scheck(string, "%jd:%d"), &hh, &mm) == 2)
else if (sscanf(string, scheck(string, "%"SCNdZIC":%d"), &hh, &mm) == 2)
ss = 0;
else if (sscanf(string, scheck(string, "%jd:%d:%d"),
else if (sscanf(string, scheck(string, "%"SCNdZIC":%d:%d"),
&hh, &mm, &ss) != 3) {
error(errstring);
return 0;
@ -895,7 +898,7 @@ gethms(const char *string, const char *const errstring, const int signable)
error(errstring);
return 0;
}
if (LONG_MAX / SECSPERHOUR < hh) {
if (ZIC_MAX / SECSPERHOUR < hh) {
error(_("time overflow"));
return 0;
}
@ -904,8 +907,8 @@ gethms(const char *string, const char *const errstring, const int signable)
if (noise && (hh > HOURSPERDAY ||
(hh == HOURSPERDAY && (mm != 0 || ss != 0))))
warning(_("values over 24 hours not handled by pre-2007 versions of zic"));
return oadd(eitol(sign) * hh * eitol(SECSPERHOUR),
eitol(sign) * (eitol(mm) * eitol(SECSPERMIN) + eitol(ss)));
return oadd(sign * hh * SECSPERHOUR,
sign * (mm * SECSPERMIN + ss));
}
static void
@ -1070,9 +1073,10 @@ inleap(char **const fields, const int nfields)
const char * cp;
const struct lookup * lp;
int i, j;
int year, month, day;
zic_t dayoff, tod;
zic_t t;
zic_t year;
int month, day;
zic_t dayoff, tod;
zic_t t;
if (nfields != LEAP_FIELDS) {
error(_("wrong number of fields on Leap line"));
@ -1080,7 +1084,7 @@ inleap(char **const fields, const int nfields)
}
dayoff = 0;
cp = fields[LP_YEAR];
if (sscanf(cp, scheck(cp, "%d"), &year) != 1) {
if (sscanf(cp, scheck(cp, "%"SCNdZIC), &year) != 1) {
/*
** Leapin' Lizards!
*/
@ -1101,7 +1105,7 @@ inleap(char **const fields, const int nfields)
--j;
i = -len_years[isleap(j)];
}
dayoff = oadd(dayoff, eitol(i));
dayoff = oadd(dayoff, i);
}
if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL) {
error(_("invalid month name"));
@ -1111,7 +1115,7 @@ inleap(char **const fields, const int nfields)
j = TM_JANUARY;
while (j != month) {
i = len_months[isleap(year)][j];
dayoff = oadd(dayoff, eitol(i));
dayoff = oadd(dayoff, i);
++j;
}
cp = fields[LP_DAY];
@ -1120,7 +1124,7 @@ inleap(char **const fields, const int nfields)
error(_("invalid day of month"));
return;
}
dayoff = oadd(dayoff, eitol(day - 1));
dayoff = oadd(dayoff, day - 1);
if (dayoff < 0 && !TYPE_SIGNED(zic_t)) {
error(_("time before zero"));
return;
@ -1241,17 +1245,17 @@ rulesub(struct rule *const rp, const char *const loyearp,
rp->r_lowasnum = lp == NULL;
if (!rp->r_lowasnum) switch ((int) lp->l_value) {
case YR_MINIMUM:
rp->r_loyear = INT_MIN;
rp->r_loyear = ZIC_MIN;
break;
case YR_MAXIMUM:
rp->r_loyear = INT_MAX;
rp->r_loyear = ZIC_MAX;
break;
default: /* "cannot happen" */
(void) fprintf(stderr,
_("%s: panic: Invalid l_value %d\n"),
progname, lp->l_value);
exit(EXIT_FAILURE);
} else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) {
} else if (sscanf(cp, scheck(cp, "%"SCNdZIC), &rp->r_loyear) != 1) {
error(_("invalid starting year"));
return;
}
@ -1260,10 +1264,10 @@ rulesub(struct rule *const rp, const char *const loyearp,
rp->r_hiwasnum = lp == NULL;
if (!rp->r_hiwasnum) switch ((int) lp->l_value) {
case YR_MINIMUM:
rp->r_hiyear = INT_MIN;
rp->r_hiyear = ZIC_MIN;
break;
case YR_MAXIMUM:
rp->r_hiyear = INT_MAX;
rp->r_hiyear = ZIC_MAX;
break;
case YR_ONLY:
rp->r_hiyear = rp->r_loyear;
@ -1273,7 +1277,7 @@ rulesub(struct rule *const rp, const char *const loyearp,
_("%s: panic: Invalid l_value %d\n"),
progname, lp->l_value);
exit(EXIT_FAILURE);
} else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) {
} else if (sscanf(cp, scheck(cp, "%"SCNdZIC), &rp->r_hiyear) != 1) {
error(_("invalid ending year"));
return;
}
@ -1423,8 +1427,11 @@ writezone(const char *const name, const char *const string)
fromi = 0;
while (fromi < timecnt && attypes[fromi].at < min_time)
++fromi;
if (isdsts[0] == 0)
while (fromi < timecnt && attypes[fromi].type == 0)
/*
** Remember that type 0 is reserved.
*/
if (isdsts[1] == 0)
while (fromi < timecnt && attypes[fromi].type == 1)
++fromi; /* handled by default rule */
for ( ; fromi < timecnt; ++fromi) {
if (toi != 0 && ((attypes[fromi].at +
@ -1526,7 +1533,11 @@ writezone(const char *const name, const char *const string)
}
thistimelim = thistimei + thistimecnt;
thisleaplim = thisleapi + thisleapcnt;
for (i = 0; i < typecnt; ++i)
/*
** Remember that type 0 is reserved.
*/
writetype[0] = FALSE;
for (i = 1; i < typecnt; ++i)
writetype[i] = thistimecnt == timecnt;
if (thistimecnt == 0) {
/*
@ -1542,8 +1553,11 @@ writezone(const char *const name, const char *const string)
/*
** For America/Godthab and Antarctica/Palmer
*/
/*
** Remember that type 0 is reserved.
*/
if (thistimei == 0)
writetype[0] = TRUE;
writetype[1] = TRUE;
}
#ifndef LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH
/*
@ -1593,8 +1607,26 @@ writezone(const char *const name, const char *const string)
}
#endif /* !defined LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH */
thistypecnt = 0;
/*
** Potentially, set type 0 to that of lowest-valued time.
*/
if (thistimei > 0) {
for (i = 1; i < typecnt; ++i)
if (writetype[i] && !isdsts[i])
break;
if (i != types[thistimei - 1]) {
i = types[thistimei - 1];
gmtoffs[0] = gmtoffs[i];
isdsts[0] = isdsts[i];
ttisstds[0] = ttisstds[i];
ttisgmts[0] = ttisgmts[i];
abbrinds[0] = abbrinds[i];
writetype[0] = TRUE;
writetype[i] = FALSE;
}
}
for (i = 0; i < typecnt; ++i)
typemap[i] = writetype[i] ? thistypecnt++ : -1;
typemap[i] = writetype[i] ? thistypecnt++ : 0;
for (i = 0; i < (int)(sizeof indmap / sizeof indmap[0]); ++i)
indmap[i] = -1;
thischarcnt = 0;
@ -1621,12 +1653,12 @@ writezone(const char *const name, const char *const string)
tzh = tzh0;
(void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic);
tzh.tzh_version[0] = ZIC_VERSION;
convert(eitol(thistypecnt), tzh.tzh_ttisgmtcnt);
convert(eitol(thistypecnt), tzh.tzh_ttisstdcnt);
convert(eitol(thisleapcnt), tzh.tzh_leapcnt);
convert(eitol(thistimecnt), tzh.tzh_timecnt);
convert(eitol(thistypecnt), tzh.tzh_typecnt);
convert(eitol(thischarcnt), tzh.tzh_charcnt);
convert(thistypecnt, tzh.tzh_ttisgmtcnt);
convert(thistypecnt, tzh.tzh_ttisstdcnt);
convert(thisleapcnt, tzh.tzh_leapcnt);
convert(thistimecnt, tzh.tzh_timecnt);
convert(thistypecnt, tzh.tzh_typecnt);
convert(thischarcnt, tzh.tzh_charcnt);
DO(tzh_magic);
DO(tzh_version);
DO(tzh_reserved);
@ -1677,7 +1709,7 @@ writezone(const char *const name, const char *const string)
todo = tadd(trans[i], -gmtoffs[j]);
} else todo = trans[i];
if (pass == 1)
puttzcode((zic_t) todo, fp);
puttzcode(todo, fp);
else puttzcode64(todo, fp);
puttzcode(corr[i], fp);
}
@ -1733,7 +1765,7 @@ doabbr(char *const abbr, const int abbrlen, const char *const format,
}
static void
updateminmax(const int x)
updateminmax(const zic_t x)
{
if (min_year > x)
min_year = x;
@ -1839,7 +1871,7 @@ stringzone(char *result, const int resultlen, const struct zone *const zpfirst,
stdrp = dstrp = NULL;
for (i = 0; i < zp->z_nrules; ++i) {
rp = &zp->z_rules[i];
if (rp->r_hiwasnum || rp->r_hiyear != INT_MAX)
if (rp->r_hiwasnum || rp->r_hiyear != ZIC_MAX)
continue;
if (rp->r_yrtype != NULL)
continue;
@ -1917,7 +1949,7 @@ outzone(const struct zone *const zpfirst, const int zonecount)
zic_t starttime, untiltime;
zic_t gmtoff;
zic_t stdoff;
int year;
zic_t year;
zic_t startoff;
int startttisstd;
int startttisgmt;
@ -1952,8 +1984,13 @@ outzone(const struct zone *const zpfirst, const int zonecount)
min_year = max_year = EPOCH_YEAR;
if (leapseen) {
updateminmax(leapminyear);
updateminmax(leapmaxyear + (leapmaxyear < INT_MAX));
updateminmax(leapmaxyear + (leapmaxyear < ZIC_MAX));
}
/*
** Reserve type 0.
*/
gmtoffs[0] = isdsts[0] = ttisstds[0] = ttisgmts[0] = abbrinds[0] = -1;
typecnt = 1;
for (i = 0; i < zonecount; ++i) {
zp = &zpfirst[i];
if (i < zonecount - 1)
@ -1964,6 +2001,8 @@ outzone(const struct zone *const zpfirst, const int zonecount)
updateminmax(rp->r_loyear);
if (rp->r_hiwasnum)
updateminmax(rp->r_hiyear);
if (rp->r_lowasnum || rp->r_hiwasnum)
prodstic = FALSE;
}
}
/*
@ -1980,12 +2019,12 @@ outzone(const struct zone *const zpfirst, const int zonecount)
free(wp);
}
if (envvar[0] == '\0') {
if (min_year >= INT_MIN + YEARSPERREPEAT)
if (min_year >= ZIC_MIN + YEARSPERREPEAT)
min_year -= YEARSPERREPEAT;
else min_year = INT_MIN;
if (max_year <= INT_MAX - YEARSPERREPEAT)
else min_year = ZIC_MIN;
if (max_year <= ZIC_MAX - YEARSPERREPEAT)
max_year += YEARSPERREPEAT;
else max_year = INT_MAX;
else max_year = ZIC_MAX;
/*
** Regardless of any of the above,
** for a "proDSTic" zone which specifies that its rules
@ -2276,7 +2315,7 @@ leapadd(const zic_t t, const int positive, const int rolling, int count)
roll[j] = roll[j - 1];
}
trans[i] = t;
corr[i] = positive ? 1L : eitol(-count);
corr[i] = positive ? 1 : -count;
roll[i] = rolling;
++leapcnt;
} while (positive && --count != 0);
@ -2329,7 +2368,7 @@ lowerit(int a)
}
/* case-insensitive equality */
static __pure int
static ATTRIBUTE_PURE int
ciequal(const char *ap, const char *bp)
{
while (lowerit(*ap) == lowerit(*bp++))
@ -2338,7 +2377,7 @@ ciequal(const char *ap, const char *bp)
return FALSE;
}
static __pure int
static ATTRIBUTE_PURE int
itsabbr(const char *abbr, const char *word)
{
if (lowerit(*abbr) != lowerit(*word))
@ -2352,7 +2391,7 @@ itsabbr(const char *abbr, const char *word)
return TRUE;
}
static __pure const struct lookup *
static ATTRIBUTE_PURE const struct lookup *
byword(const char *const word, const struct lookup *const table)
{
const struct lookup * foundlp;
@ -2419,10 +2458,10 @@ getfields(char *cp)
return array;
}
static __pure zic_t
static ATTRIBUTE_PURE zic_t
oadd(const zic_t t1, const zic_t t2)
{
if (t1 < 0 ? t2 < LONG_MIN - t1 : LONG_MAX - t1 < t2) {
if (t1 < 0 ? t2 < ZIC_MIN - t1 : ZIC_MAX - t1 < t2) {
error(_("time overflow"));
exit(EXIT_FAILURE);
}
@ -2449,15 +2488,15 @@ tadd(const zic_t t1, const zic_t t2)
*/
static zic_t
rpytime(const struct rule *const rp, const int wantedy)
rpytime(const struct rule *const rp, const zic_t wantedy)
{
int y, m, i;
int m, i;
zic_t dayoff; /* with a nod to Margaret O. */
zic_t t;
zic_t t, y;
if (wantedy == INT_MIN)
if (wantedy == ZIC_MIN)
return min_time;
if (wantedy == INT_MAX)
if (wantedy == ZIC_MAX)
return max_time;
dayoff = 0;
m = TM_JANUARY;
@ -2470,11 +2509,11 @@ rpytime(const struct rule *const rp, const int wantedy)
--y;
i = -len_years[isleap(y)];
}
dayoff = oadd(dayoff, eitol(i));
dayoff = oadd(dayoff, i);
}
while (m != rp->r_month) {
i = len_months[isleap(y)][m];
dayoff = oadd(dayoff, eitol(i));
dayoff = oadd(dayoff, i);
++m;
}
i = rp->r_dayofmonth;
@ -2487,12 +2526,12 @@ rpytime(const struct rule *const rp, const int wantedy)
}
}
--i;
dayoff = oadd(dayoff, eitol(i));
dayoff = oadd(dayoff, i);
if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ) {
zic_t wday;
#define LDAYSPERWEEK ((zic_t) DAYSPERWEEK)
wday = eitol(EPOCH_WDAY);
wday = EPOCH_WDAY;
/*
** Don't trust mod of negative numbers.
*/
@ -2503,7 +2542,7 @@ rpytime(const struct rule *const rp, const int wantedy)
if (wday < 0)
wday += LDAYSPERWEEK;
}
while (wday != eitol(rp->r_wday))
while (wday != rp->r_wday)
if (rp->r_dycode == DC_DOWGEQ) {
dayoff = oadd(dayoff, (zic_t) 1);
if (++wday >= LDAYSPERWEEK)
@ -2578,7 +2617,7 @@ mp = _("time zone abbreviation differs from POSIX standard");
exit(EXIT_FAILURE);
}
(void)strncpy(&chars[charcnt], string, sizeof(chars) - charcnt - 1);
charcnt += eitol(i);
charcnt += i;
}
static int
@ -2592,7 +2631,7 @@ mkdirs(char *argname)
cp = name = ecpyalloc(argname);
while ((cp = strchr(cp + 1, '/')) != 0) {
*cp = '\0';
#ifndef __NetBSD__
#ifdef HAVE_DOS_FILE_NAMES
/*
** DOS drive specifier?
*/
@ -2601,7 +2640,7 @@ mkdirs(char *argname)
*cp = '/';
continue;
}
#endif /* !defined __NetBSD__ */
#endif
if (!itsdir(name)) {
/*
** It doesn't seem to exist, so we try to create it.
@ -2627,21 +2666,6 @@ _("%s: Can't create directory %s: %s\n"),
return 0;
}
static zic_t
eitol(const int i)
{
zic_t l;
l = i;
if ((i < 0 && l >= 0) || (i == 0 && l != 0) || (i > 0 && l <= 0)) {
(void) fprintf(stderr,
_("%s: %d did not sign extend correctly\n"),
progname, i);
exit(EXIT_FAILURE);
}
return l;
}
/*
** UNIX was a registered trademark of The Open Group in 2003.
*/