updated to tzcode2007a
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19755 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
f21b85581f
commit
9481ed48de
@ -4,7 +4,7 @@
|
||||
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
|
||||
** 1996-06-05 by Arthur David Olson.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -21,7 +21,7 @@
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char privatehid[] = "@(#)private.h 7.55";
|
||||
static char privatehid[] = "@(#)private.h 8.2";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
@ -89,7 +89,7 @@ static char privatehid[] = "@(#)private.h 7.55";
|
||||
#include "stdio.h"
|
||||
#include "errno.h"
|
||||
#include "string.h"
|
||||
#include "limits.h" /* for CHAR_BIT */
|
||||
#include "limits.h" /* for CHAR_BIT et al. */
|
||||
#include "time.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
@ -124,21 +124,52 @@ static char privatehid[] = "@(#)private.h 7.55";
|
||||
/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
|
||||
#define is_digit(c) ((unsigned)(c) - '0' <= 9)
|
||||
|
||||
/*
|
||||
** Define HAVE_STDINT_H's default value here, rather than at the
|
||||
** start, since __GLIBC__'s value depends on previously-included
|
||||
** files.
|
||||
** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.)
|
||||
*/
|
||||
#ifndef HAVE_STDINT_H
|
||||
#define HAVE_STDINT_H \
|
||||
(199901 <= __STDC_VERSION__ || \
|
||||
2 < (__GLIBC__ + (0 < __GLIBC_MINOR__)))
|
||||
#endif /* !defined HAVE_STDINT_H */
|
||||
|
||||
#if HAVE_STDINT_H
|
||||
#include "stdint.h"
|
||||
#endif /* !HAVE_STDINT_H */
|
||||
|
||||
#ifndef INT_FAST64_MAX
|
||||
/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */
|
||||
#if defined LLONG_MAX || defined __LONG_LONG_MAX__
|
||||
typedef long long int_fast64_t;
|
||||
#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
|
||||
#if (LONG_MAX >> 31) < 0xffffffff
|
||||
Please use a compiler that supports a 64-bit integer type (or wider);
|
||||
you may need to compile with "-DHAVE_STDINT_H".
|
||||
#endif /* (LONG_MAX >> 31) < 0xffffffff */
|
||||
typedef long int_fast64_t;
|
||||
#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */
|
||||
#endif /* !defined INT_FAST64_MAX */
|
||||
|
||||
#ifndef INT32_MAX
|
||||
#define INT32_MAX 0x7fffffff
|
||||
#endif /* !defined INT32_MAX */
|
||||
#ifndef INT32_MIN
|
||||
#define INT32_MIN (-1 - INT32_MAX)
|
||||
#endif /* !defined INT32_MIN */
|
||||
|
||||
/*
|
||||
** Workarounds for compilers/systems.
|
||||
*/
|
||||
|
||||
/*
|
||||
** SunOS 4.1.1 cc lacks prototypes.
|
||||
** If your compiler lacks prototypes, "#define P(x) ()".
|
||||
*/
|
||||
|
||||
#ifndef P
|
||||
#ifdef __STDC__
|
||||
#define P(x) x
|
||||
#endif /* defined __STDC__ */
|
||||
#ifndef __STDC__
|
||||
#define P(x) ()
|
||||
#endif /* !defined __STDC__ */
|
||||
#endif /* !defined P */
|
||||
|
||||
/*
|
||||
@ -218,7 +249,7 @@ char * imalloc P((int n));
|
||||
void * irealloc P((void * pointer, int size));
|
||||
void icfree P((char * pointer));
|
||||
void ifree P((char * pointer));
|
||||
char * scheck P((const char *string, char *format));
|
||||
const char * scheck P((const char * string, const char * format));
|
||||
|
||||
/*
|
||||
** Finally, some convenience items.
|
||||
@ -310,6 +341,26 @@ char *asctime_r P((struct tm const *, char *));
|
||||
char *ctime_r P((time_t const *, char *));
|
||||
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
|
||||
|
||||
#ifndef YEARSPERREPEAT
|
||||
#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */
|
||||
#endif /* !defined YEARSPERREPEAT */
|
||||
|
||||
/*
|
||||
** The Gregorian year averages 365.2425 days, which is 31556952 seconds.
|
||||
*/
|
||||
|
||||
#ifndef AVGSECSPERYEAR
|
||||
#define AVGSECSPERYEAR 31556952L
|
||||
#endif /* !defined AVGSECSPERYEAR */
|
||||
|
||||
#ifndef SECSPERREPEAT
|
||||
#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
|
||||
#endif /* !defined SECSPERREPEAT */
|
||||
|
||||
#ifndef SECSPERREPEAT_BITS
|
||||
#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */
|
||||
#endif /* !defined SECSPERREPEAT_BITS */
|
||||
|
||||
/*
|
||||
** UNIX was a registered trademark of The Open Group in 2003.
|
||||
*/
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
|
||||
** 1996-06-05 by Arthur David Olson.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -21,7 +21,7 @@
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char tzfilehid[] = "@(#)tzfile.h 7.17";
|
||||
static char tzfilehid[] = "@(#)tzfile.h 8.1";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
@ -49,7 +49,8 @@ static char tzfilehid[] = "@(#)tzfile.h 7.17";
|
||||
|
||||
struct tzhead {
|
||||
char tzh_magic[4]; /* TZ_MAGIC */
|
||||
char tzh_reserved[16]; /* reserved for future use */
|
||||
char tzh_version[1]; /* '\0' or '2' as of 2005 */
|
||||
char tzh_reserved[15]; /* reserved--must be zero */
|
||||
char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
|
||||
char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
|
||||
char tzh_leapcnt[4]; /* coded number of leap seconds */
|
||||
@ -83,19 +84,23 @@ struct tzhead {
|
||||
** assumed to be local time
|
||||
*/
|
||||
|
||||
/*
|
||||
** If tzh_version is '2' or greater, the above is followed by a second instance
|
||||
** of tzhead and a second instance of the data in which each coded transition
|
||||
** time uses 8 rather than 4 chars,
|
||||
** then a POSIX-TZ-environment-variable-style string for use in handling
|
||||
** instants after the last transition time stored in the file
|
||||
** (with nothing between the newlines if there is no POSIX representation for
|
||||
** such instants).
|
||||
*/
|
||||
|
||||
/*
|
||||
** In the current implementation, "tzset()" refuses to deal with files that
|
||||
** exceed any of the limits below.
|
||||
*/
|
||||
|
||||
#ifndef TZ_MAX_TIMES
|
||||
/*
|
||||
** The TZ_MAX_TIMES value below is enough to handle a bit more than a
|
||||
** year's worth of solar time (corrected daily to the nearest second) or
|
||||
** 138 years of Pacific Presidential Election time
|
||||
** (where there are three time zone transitions every fourth year).
|
||||
*/
|
||||
#define TZ_MAX_TIMES 370
|
||||
#define TZ_MAX_TIMES 1200
|
||||
#endif /* !defined TZ_MAX_TIMES */
|
||||
|
||||
#ifndef TZ_MAX_TYPES
|
||||
@ -105,7 +110,7 @@ struct tzhead {
|
||||
#ifdef NOSOLAR
|
||||
/*
|
||||
** Must be at least 14 for Europe/Riga as of Jan 12 1995,
|
||||
** as noted by Earl Chew <earl@hpato.aus.hp.com>.
|
||||
** as noted by Earl Chew.
|
||||
*/
|
||||
#define TZ_MAX_TYPES 20 /* Maximum number of local time types */
|
||||
#endif /* !defined NOSOLAR */
|
||||
|
@ -1,6 +1,11 @@
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 2006-07-17 by Arthur David Olson.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)ialloc.c 8.29";
|
||||
static char elsieid[] = "@(#)ialloc.c 8.30";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
|
@ -1,6 +1,11 @@
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 2006-07-17 by Arthur David Olson.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)scheck.c 8.16";
|
||||
static char elsieid[] = "@(#)scheck.c 8.19";
|
||||
#endif /* !defined lint */
|
||||
#endif /* !defined NOID */
|
||||
|
||||
@ -8,20 +13,19 @@ static char elsieid[] = "@(#)scheck.c 8.16";
|
||||
|
||||
#include "private.h"
|
||||
|
||||
char *
|
||||
const char *
|
||||
scheck(string, format)
|
||||
const char * const string;
|
||||
char * const format;
|
||||
const char * const format;
|
||||
{
|
||||
register char * fbuf;
|
||||
register const char * fp;
|
||||
register char * tp;
|
||||
register int c;
|
||||
register char * result;
|
||||
register const char * result;
|
||||
char dummy;
|
||||
static char nada;
|
||||
|
||||
result = &nada;
|
||||
result = "";
|
||||
if (string == NULL || format == NULL)
|
||||
return result;
|
||||
fbuf = imalloc((int) (2 * strlen(format) + 4));
|
||||
|
@ -1,4 +1,4 @@
|
||||
static char elsieid[] = "@(#)zdump.c 7.65";
|
||||
static char elsieid[] = "@(#)zdump.c 8.3";
|
||||
|
||||
/*
|
||||
** This code has been made independent of the rest of the time
|
||||
@ -12,6 +12,10 @@ static char elsieid[] = "@(#)zdump.c 7.65";
|
||||
#include "time.h" /* for struct tm */
|
||||
#include "stdlib.h" /* for exit, malloc, atoi */
|
||||
#include "float.h" /* for FLT_MAX and DBL_MAX */
|
||||
#include "ctype.h" /* for isalpha et al. */
|
||||
#ifndef isascii
|
||||
#define isascii(x) 1
|
||||
#endif /* !defined isascii */
|
||||
|
||||
#ifndef ZDUMP_LO_YEAR
|
||||
#define ZDUMP_LO_YEAR (-500)
|
||||
@ -126,11 +130,7 @@ static char elsieid[] = "@(#)zdump.c 7.65";
|
||||
#endif /* !defined TZ_DOMAIN */
|
||||
|
||||
#ifndef P
|
||||
#ifdef __STDC__
|
||||
#define P(x) x
|
||||
#else /* !defined __STDC__ */
|
||||
#define P(x) ()
|
||||
#endif /* !defined __STDC__ */
|
||||
#endif /* !defined P */
|
||||
|
||||
extern char ** environ;
|
||||
@ -147,7 +147,7 @@ static char * progname;
|
||||
static int warned;
|
||||
|
||||
static char * abbr P((struct tm * tmp));
|
||||
static void abbrok P((const char * abbr, const char * zone));
|
||||
static void abbrok P((const char * abbrp, const char * zone));
|
||||
static long delta P((struct tm * newp, struct tm * oldp));
|
||||
static void dumptime P((const struct tm * tmp));
|
||||
static time_t hunt P((char * name, time_t lot, time_t hit));
|
||||
@ -194,40 +194,40 @@ time_t * tp;
|
||||
#endif /* !defined TYPECHECK */
|
||||
|
||||
static void
|
||||
abbrok(abbr, zone)
|
||||
const char * const abbr;
|
||||
abbrok(abbrp, zone)
|
||||
const char * const abbrp;
|
||||
const char * const zone;
|
||||
{
|
||||
register int i;
|
||||
register const char * cp;
|
||||
register char * wp;
|
||||
|
||||
if (warned)
|
||||
return;
|
||||
cp = abbr;
|
||||
cp = abbrp;
|
||||
wp = NULL;
|
||||
while (isascii(*cp) && isalpha(*cp))
|
||||
while (isascii((unsigned char) *cp) && isalpha((unsigned char) *cp))
|
||||
++cp;
|
||||
if (cp - abbr == 0)
|
||||
if (cp - abbrp == 0)
|
||||
wp = _("lacks alphabetic at start");
|
||||
if (cp - abbr < 3)
|
||||
else if (cp - abbrp < 3)
|
||||
wp = _("has fewer than 3 alphabetics");
|
||||
if (cp - abbr > 6)
|
||||
else if (cp - abbrp > 6)
|
||||
wp = _("has more than 6 alphabetics");
|
||||
if (wp == NULL && (*cp == '+' || *cp == '-')) {
|
||||
++cp;
|
||||
if (isascii(*cp) && isdigit(*cp))
|
||||
if (isascii((unsigned char) *cp) &&
|
||||
isdigit((unsigned char) *cp))
|
||||
if (*cp++ == '1' && *cp >= '0' && *cp <= '4')
|
||||
++cp;
|
||||
}
|
||||
if (*cp != '\0')
|
||||
wp = _("differs from POSIX standard");
|
||||
}
|
||||
if (wp == NULL)
|
||||
return;
|
||||
(void) fflush(stdout);
|
||||
(void) fprintf(stderr,
|
||||
"%s: warning: zone \"%s\" abbreviation \"%s\" %s\n",
|
||||
progname, zone, abbr, wp);
|
||||
_("%s: warning: zone \"%s\" abbreviation \"%s\" %s\n"),
|
||||
progname, zone, abbrp, wp);
|
||||
warned = TRUE;
|
||||
}
|
||||
|
||||
@ -266,7 +266,7 @@ char * argv[];
|
||||
for (i = 1; i < argc; ++i)
|
||||
if (strcmp(argv[i], "--version") == 0) {
|
||||
(void) printf("%s\n", elsieid);
|
||||
(void) exit(EXIT_SUCCESS);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
vflag = 0;
|
||||
cutarg = NULL;
|
||||
@ -279,7 +279,7 @@ char * argv[];
|
||||
(void) fprintf(stderr,
|
||||
_("%s: usage is %s [ --version ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n"),
|
||||
progname, progname);
|
||||
(void) exit(EXIT_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (vflag) {
|
||||
if (cutarg != NULL) {
|
||||
@ -296,7 +296,7 @@ _("%s: usage is %s [ --version ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n"),
|
||||
} else {
|
||||
(void) fprintf(stderr, _("%s: wild -c argument %s\n"),
|
||||
progname, cutarg);
|
||||
(void) exit(EXIT_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
setabsolutes();
|
||||
@ -319,7 +319,7 @@ _("%s: usage is %s [ --version ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n"),
|
||||
if (fakeenv == NULL ||
|
||||
(fakeenv[0] = (char *) malloc(longest + 4)) == NULL) {
|
||||
(void) perror(progname);
|
||||
(void) exit(EXIT_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
to = 0;
|
||||
(void) strcpy(fakeenv[to++], "TZ=");
|
||||
@ -385,8 +385,8 @@ _("%s: usage is %s [ --version ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n"),
|
||||
}
|
||||
if (fflush(stdout) || ferror(stdout)) {
|
||||
(void) fprintf(stderr, "%s: ", progname);
|
||||
(void) perror(_("Error writing standard output"));
|
||||
(void) exit(EXIT_FAILURE);
|
||||
(void) perror(_("Error writing to standard output"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
/* If exit fails to exit... */
|
||||
@ -410,18 +410,25 @@ setabsolutes()
|
||||
(void) fprintf(stderr,
|
||||
_("%s: use of -v on system with floating time_t other than float or double\n"),
|
||||
progname);
|
||||
(void) exit(EXIT_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else if (0 > (time_t) -1) {
|
||||
/*
|
||||
** time_t is signed.
|
||||
** time_t is signed. Assume overflow wraps around.
|
||||
*/
|
||||
register time_t hibit;
|
||||
time_t t = 0;
|
||||
time_t t1 = 1;
|
||||
|
||||
for (hibit = 1; (hibit * 2) != 0; hibit *= 2)
|
||||
continue;
|
||||
absolute_min_time = hibit;
|
||||
absolute_max_time = -(hibit + 1);
|
||||
while (t < t1) {
|
||||
t = t1;
|
||||
t1 = 2 * t1 + 1;
|
||||
}
|
||||
|
||||
absolute_max_time = t;
|
||||
t = -t;
|
||||
absolute_min_time = t - 1;
|
||||
if (t < absolute_min_time)
|
||||
absolute_min_time = t;
|
||||
} else {
|
||||
/*
|
||||
** time_t is unsigned.
|
||||
@ -464,10 +471,7 @@ const long y;
|
||||
}
|
||||
|
||||
static time_t
|
||||
hunt(name, lot, hit)
|
||||
char * name;
|
||||
time_t lot;
|
||||
time_t hit;
|
||||
hunt(char *name, time_t lot, time_t hit)
|
||||
{
|
||||
time_t t;
|
||||
long diff;
|
||||
@ -510,7 +514,7 @@ time_t hit;
|
||||
}
|
||||
|
||||
/*
|
||||
** Thanks to Paul Eggert (eggert@twinsun.com) for logic used in delta.
|
||||
** Thanks to Paul Eggert for logic used in delta.
|
||||
*/
|
||||
|
||||
static long
|
||||
@ -537,10 +541,7 @@ struct tm * oldp;
|
||||
}
|
||||
|
||||
static void
|
||||
show(zone, t, v)
|
||||
char * zone;
|
||||
time_t t;
|
||||
int v;
|
||||
show(char *zone, time_t t, int v)
|
||||
{
|
||||
register struct tm * tmp;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,18 +1,17 @@
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
|
||||
** 1996-06-05 by Arthur David Olson.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)localtime.c 7.95";
|
||||
static char elsieid[] = "@(#)localtime.c 8.5";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
/*
|
||||
** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu).
|
||||
** POSIX-style TZ environment variable handling from Guy Harris
|
||||
** (guy@auspex.com).
|
||||
** Leap second handling from Bradley White.
|
||||
** POSIX-style TZ environment variable handling from Guy Harris.
|
||||
*/
|
||||
|
||||
/*LINTLIBRARY*/
|
||||
@ -111,6 +110,8 @@ struct state {
|
||||
int timecnt;
|
||||
int typecnt;
|
||||
int charcnt;
|
||||
int goback;
|
||||
int goahead;
|
||||
time_t ats[TZ_MAX_TIMES];
|
||||
unsigned char types[TZ_MAX_TIMES];
|
||||
struct ttinfo ttis[TZ_MAX_TYPES];
|
||||
@ -136,8 +137,10 @@ struct rule {
|
||||
*/
|
||||
|
||||
static long detzcode P((const char * codep));
|
||||
static time_t detzcode64 P((const char * codep));
|
||||
static int differ_by_repeat P((time_t t1, time_t t0));
|
||||
static const char * getzname P((const char * strp));
|
||||
static const char * getqzname P((const char * strp, const char delim));
|
||||
static const char * getqzname P((const char * strp, const int delim));
|
||||
static const char * getnum P((const char * strp, int * nump, int min,
|
||||
int max));
|
||||
static const char * getsecs P((const char * strp, long * secsp));
|
||||
@ -174,7 +177,8 @@ static int tmcomp P((const struct tm * atmp,
|
||||
const struct tm * btmp));
|
||||
static time_t transtime P((time_t janfirst, int year,
|
||||
const struct rule * rulep, long offset));
|
||||
static int tzload P((const char * name, struct state * sp));
|
||||
static int tzload P((const char * name, struct state * sp,
|
||||
int doextend));
|
||||
static int tzparse P((const char * name, struct state * sp,
|
||||
int lastditch));
|
||||
|
||||
@ -208,7 +212,7 @@ char * tzname[2] = {
|
||||
** Except for the strftime function, these functions [asctime,
|
||||
** ctime, gmtime, localtime] return values in one of two static
|
||||
** objects: a broken-down time structure and an array of char.
|
||||
** Thanks to Paul Eggert (eggert@twinsun.com) for noting this.
|
||||
** Thanks to Paul Eggert for noting this.
|
||||
*/
|
||||
|
||||
static struct tm tm;
|
||||
@ -229,12 +233,25 @@ const char * const codep;
|
||||
register long result;
|
||||
register int i;
|
||||
|
||||
result = (codep[0] & 0x80) ? ~0L : 0L;
|
||||
result = (codep[0] & 0x80) ? ~0L : 0;
|
||||
for (i = 0; i < 4; ++i)
|
||||
result = (result << 8) | (codep[i] & 0xff);
|
||||
return result;
|
||||
}
|
||||
|
||||
static time_t
|
||||
detzcode64(codep)
|
||||
const char * const codep;
|
||||
{
|
||||
register time_t result;
|
||||
register int i;
|
||||
|
||||
result = (codep[0] & 0x80) ? (~(int_fast64_t) 0) : 0;
|
||||
for (i = 0; i < 8; ++i)
|
||||
result = result * 256 + (codep[i] & 0xff);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
settzname P((void))
|
||||
{
|
||||
@ -304,13 +321,33 @@ settzname P((void))
|
||||
}
|
||||
|
||||
static int
|
||||
tzload(name, sp)
|
||||
differ_by_repeat(t1, t0)
|
||||
const time_t t1;
|
||||
const time_t t0;
|
||||
{
|
||||
if (TYPE_INTEGRAL(time_t) &&
|
||||
TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
|
||||
return 0;
|
||||
return t1 - t0 == SECSPERREPEAT;
|
||||
}
|
||||
|
||||
static int
|
||||
tzload(name, sp, doextend)
|
||||
register const char * name;
|
||||
register struct state * const sp;
|
||||
register const int doextend;
|
||||
{
|
||||
register const char * p;
|
||||
register int i;
|
||||
register int fid;
|
||||
register int stored;
|
||||
register int nread;
|
||||
union {
|
||||
struct tzhead tzhead;
|
||||
char buf[2 * sizeof(struct tzhead) +
|
||||
2 * sizeof *sp +
|
||||
4 * TZ_MAX_TIMES];
|
||||
} u;
|
||||
|
||||
if (name == NULL && (name = TZDEFAULT) == NULL)
|
||||
return -1;
|
||||
@ -348,18 +385,13 @@ register struct state * const sp;
|
||||
if ((fid = open(name, OPEN_MODE)) == -1)
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
struct tzhead * tzhp;
|
||||
union {
|
||||
struct tzhead tzhead;
|
||||
char buf[sizeof *sp + sizeof *tzhp];
|
||||
} u;
|
||||
nread = read(fid, u.buf, sizeof u.buf);
|
||||
if (close(fid) < 0 || nread <= 0)
|
||||
return -1;
|
||||
for (stored = 4; stored <= 8; stored *= 2) {
|
||||
int ttisstdcnt;
|
||||
int ttisgmtcnt;
|
||||
|
||||
i = read(fid, u.buf, sizeof u.buf);
|
||||
if (close(fid) != 0)
|
||||
return -1;
|
||||
ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt);
|
||||
ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt);
|
||||
sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt);
|
||||
@ -374,17 +406,19 @@ register struct state * const sp;
|
||||
(ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
|
||||
(ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
|
||||
return -1;
|
||||
if (i - (p - u.buf) < sp->timecnt * 4 + /* ats */
|
||||
if (nread - (p - u.buf) <
|
||||
sp->timecnt * stored + /* ats */
|
||||
sp->timecnt + /* types */
|
||||
sp->typecnt * (4 + 2) + /* ttinfos */
|
||||
sp->typecnt * 6 + /* ttinfos */
|
||||
sp->charcnt + /* chars */
|
||||
sp->leapcnt * (4 + 4) + /* lsinfos */
|
||||
sp->leapcnt * (stored + 4) + /* lsinfos */
|
||||
ttisstdcnt + /* ttisstds */
|
||||
ttisgmtcnt) /* ttisgmts */
|
||||
return -1;
|
||||
for (i = 0; i < sp->timecnt; ++i) {
|
||||
sp->ats[i] = detzcode(p);
|
||||
p += 4;
|
||||
sp->ats[i] = (stored == 4) ?
|
||||
detzcode(p) : detzcode64(p);
|
||||
p += stored;
|
||||
}
|
||||
for (i = 0; i < sp->timecnt; ++i) {
|
||||
sp->types[i] = (unsigned char) *p++;
|
||||
@ -412,8 +446,9 @@ register struct state * const sp;
|
||||
register struct lsinfo * lsisp;
|
||||
|
||||
lsisp = &sp->lsis[i];
|
||||
lsisp->ls_trans = detzcode(p);
|
||||
p += 4;
|
||||
lsisp->ls_trans = (stored == 4) ?
|
||||
detzcode(p) : detzcode64(p);
|
||||
p += stored;
|
||||
lsisp->ls_corr = detzcode(p);
|
||||
p += 4;
|
||||
}
|
||||
@ -470,7 +505,63 @@ register struct state * const sp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/*
|
||||
** If this is an old file, we're done.
|
||||
*/
|
||||
if (u.tzhead.tzh_version[0] == '\0')
|
||||
break;
|
||||
nread -= p - u.buf;
|
||||
for (i = 0; i < nread; ++i)
|
||||
u.buf[i] = p[i];
|
||||
/*
|
||||
** If this is a narrow integer time_t system, we're done.
|
||||
*/
|
||||
if (stored >= (int) sizeof(time_t) && TYPE_INTEGRAL(time_t))
|
||||
break;
|
||||
}
|
||||
if (doextend && nread > 2 &&
|
||||
u.buf[0] == '\n' && u.buf[nread - 1] == '\n' &&
|
||||
sp->typecnt + 2 <= TZ_MAX_TYPES) {
|
||||
struct state ts;
|
||||
register int result;
|
||||
|
||||
u.buf[nread - 1] = '\0';
|
||||
result = tzparse(&u.buf[1], &ts, FALSE);
|
||||
if (result == 0 && ts.typecnt == 2 &&
|
||||
sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) {
|
||||
for (i = 0; i < 2; ++i)
|
||||
ts.ttis[i].tt_abbrind +=
|
||||
sp->charcnt;
|
||||
for (i = 0; i < ts.charcnt; ++i)
|
||||
sp->chars[sp->charcnt++] =
|
||||
ts.chars[i];
|
||||
i = 0;
|
||||
while (i < ts.timecnt &&
|
||||
ts.ats[i] <=
|
||||
sp->ats[sp->timecnt - 1])
|
||||
++i;
|
||||
while (i < ts.timecnt &&
|
||||
sp->timecnt < TZ_MAX_TIMES) {
|
||||
sp->ats[sp->timecnt] =
|
||||
ts.ats[i];
|
||||
sp->types[sp->timecnt] =
|
||||
sp->typecnt +
|
||||
ts.types[i];
|
||||
++sp->timecnt;
|
||||
++i;
|
||||
}
|
||||
sp->ttis[sp->typecnt++] = ts.ttis[0];
|
||||
sp->ttis[sp->typecnt++] = ts.ttis[1];
|
||||
}
|
||||
}
|
||||
i = 2 * YEARSPERREPEAT;
|
||||
sp->goback = sp->goahead = sp->timecnt > i;
|
||||
sp->goback = sp->goback && sp->types[i] == sp->types[0] &&
|
||||
differ_by_repeat(sp->ats[i], sp->ats[0]);
|
||||
sp->goahead = sp->goahead &&
|
||||
sp->types[sp->timecnt - 1] == sp->types[sp->timecnt - 1 - i] &&
|
||||
differ_by_repeat(sp->ats[sp->timecnt - 1],
|
||||
sp->ats[sp->timecnt - 1 - i]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -507,15 +598,13 @@ register const char * strp;
|
||||
**
|
||||
** As with getzname above, the legal character set is actually quite
|
||||
** restricted, with other characters producing undefined results.
|
||||
** We choose not to care - allowing almost anything to be in the zone abbrev.
|
||||
** We don't do any checking here; checking is done later in common-case code.
|
||||
*/
|
||||
|
||||
static const char *
|
||||
getqzname(strp, delim)
|
||||
register const char * strp;
|
||||
const char delim;
|
||||
getqzname(register const char *strp, const int delim)
|
||||
{
|
||||
register char c;
|
||||
register int c;
|
||||
|
||||
while ((c = *strp) != '\0' && c != delim)
|
||||
++strp;
|
||||
@ -824,7 +913,7 @@ const int lastditch;
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
}
|
||||
load_result = tzload(TZDEFRULES, sp);
|
||||
load_result = tzload(TZDEFRULES, sp, FALSE);
|
||||
if (load_result != 0)
|
||||
sp->leapcnt = 0; /* so, we're off a little */
|
||||
if (*name != '\0') {
|
||||
@ -866,11 +955,8 @@ const int lastditch;
|
||||
return -1;
|
||||
sp->typecnt = 2; /* standard time and DST */
|
||||
/*
|
||||
** Two transitions per year, from EPOCH_YEAR to 2037.
|
||||
** Two transitions per year, from EPOCH_YEAR forward.
|
||||
*/
|
||||
sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1);
|
||||
if (sp->timecnt > TZ_MAX_TIMES)
|
||||
return -1;
|
||||
sp->ttis[0].tt_gmtoff = -dstoffset;
|
||||
sp->ttis[0].tt_isdst = 1;
|
||||
sp->ttis[0].tt_abbrind = stdlen + 1;
|
||||
@ -880,7 +966,12 @@ const int lastditch;
|
||||
atp = sp->ats;
|
||||
typep = sp->types;
|
||||
janfirst = 0;
|
||||
for (year = EPOCH_YEAR; year <= 2037; ++year) {
|
||||
sp->timecnt = 0;
|
||||
for (year = EPOCH_YEAR;
|
||||
sp->timecnt + 2 <= TZ_MAX_TIMES;
|
||||
++year) {
|
||||
time_t newfirst;
|
||||
|
||||
starttime = transtime(janfirst, year, &start,
|
||||
stdoffset);
|
||||
endtime = transtime(janfirst, year, &end,
|
||||
@ -896,8 +987,13 @@ const int lastditch;
|
||||
*atp++ = endtime;
|
||||
*typep++ = 1; /* DST ends */
|
||||
}
|
||||
janfirst += year_lengths[isleap(year)] *
|
||||
sp->timecnt += 2;
|
||||
newfirst = janfirst;
|
||||
newfirst += year_lengths[isleap(year)] *
|
||||
SECSPERDAY;
|
||||
if (newfirst <= janfirst)
|
||||
break;
|
||||
janfirst = newfirst;
|
||||
}
|
||||
} else {
|
||||
register long theirstdoffset;
|
||||
@ -1012,7 +1108,7 @@ static void
|
||||
gmtload(sp)
|
||||
struct state * const sp;
|
||||
{
|
||||
if (tzload(gmt, sp) != 0)
|
||||
if (tzload(gmt, sp, TRUE) != 0)
|
||||
(void) tzparse(gmt, sp, TRUE);
|
||||
}
|
||||
|
||||
@ -1039,7 +1135,7 @@ tzsetwall P((void))
|
||||
}
|
||||
}
|
||||
#endif /* defined ALL_STATE */
|
||||
if (tzload((char *) NULL, lclptr) != 0)
|
||||
if (tzload((char *) NULL, lclptr, TRUE) != 0)
|
||||
gmtload(lclptr);
|
||||
settzname();
|
||||
}
|
||||
@ -1091,7 +1187,7 @@ tzset P((void))
|
||||
lclptr->ttis[0].tt_gmtoff = 0;
|
||||
lclptr->ttis[0].tt_abbrind = 0;
|
||||
(void) strcpy(lclptr->chars, gmt);
|
||||
} else if (tzload(name, lclptr) != 0)
|
||||
} else if (tzload(name, lclptr, TRUE) != 0)
|
||||
if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
|
||||
(void) gmtload(lclptr);
|
||||
settzname();
|
||||
@ -1124,6 +1220,45 @@ struct tm * const tmp;
|
||||
if (sp == NULL)
|
||||
return gmtsub(timep, offset, tmp);
|
||||
#endif /* defined ALL_STATE */
|
||||
if ((sp->goback && t < sp->ats[0]) ||
|
||||
(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
|
||||
time_t newt = t;
|
||||
register time_t seconds;
|
||||
register time_t tcycles;
|
||||
register int_fast64_t icycles;
|
||||
|
||||
if (t < sp->ats[0])
|
||||
seconds = sp->ats[0] - t;
|
||||
else seconds = t - sp->ats[sp->timecnt - 1];
|
||||
--seconds;
|
||||
tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
|
||||
++tcycles;
|
||||
icycles = tcycles;
|
||||
if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
|
||||
return NULL;
|
||||
seconds = icycles;
|
||||
seconds *= YEARSPERREPEAT;
|
||||
seconds *= AVGSECSPERYEAR;
|
||||
if (t < sp->ats[0])
|
||||
newt += seconds;
|
||||
else newt -= seconds;
|
||||
if (newt < sp->ats[0] ||
|
||||
newt > sp->ats[sp->timecnt - 1])
|
||||
return NULL; /* "cannot happen" */
|
||||
result = localsub(&newt, offset, tmp);
|
||||
if (result == tmp) {
|
||||
register time_t newy;
|
||||
|
||||
newy = tmp->tm_year;
|
||||
if (t < sp->ats[0])
|
||||
newy -= icycles * YEARSPERREPEAT;
|
||||
else newy += icycles * YEARSPERREPEAT;
|
||||
tmp->tm_year = newy;
|
||||
if (tmp->tm_year != newy)
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (sp->timecnt == 0 || t < sp->ats[0]) {
|
||||
i = 0;
|
||||
while (sp->ttis[i].tt_isdst)
|
||||
@ -1132,10 +1267,17 @@ struct tm * const tmp;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
for (i = 1; i < sp->timecnt; ++i)
|
||||
if (t < sp->ats[i])
|
||||
break;
|
||||
i = (int) sp->types[i - 1];
|
||||
register int lo = 1;
|
||||
register int hi = sp->timecnt;
|
||||
|
||||
while (lo < hi) {
|
||||
register int mid = (lo + hi) >> 1;
|
||||
|
||||
if (t < sp->ats[mid])
|
||||
hi = mid;
|
||||
else lo = mid + 1;
|
||||
}
|
||||
i = (int) sp->types[lo - 1];
|
||||
}
|
||||
ttisp = &sp->ttis[i];
|
||||
/*
|
||||
@ -1398,7 +1540,6 @@ register struct tm * const tmp;
|
||||
** Adapted from code provided by Robert Elz, who writes:
|
||||
** The "best" way to do mktime I think is based on an idea of Bob
|
||||
** Kridle's (so its said...) from a long time ago.
|
||||
** [kridle@xinet.com as of 1996-01-16.]
|
||||
** It does a binary search of the time_t space. Since time_t's are
|
||||
** just 32 bits, its a max of 32 iterations (even at 64 bits it
|
||||
** would still be very reasonable).
|
||||
@ -1409,7 +1550,7 @@ register struct tm * const tmp;
|
||||
#endif /* !defined WRONG */
|
||||
|
||||
/*
|
||||
** Simplified normalize logic courtesy Paul Eggert (eggert@twinsun.com).
|
||||
** Simplified normalize logic courtesy Paul Eggert.
|
||||
*/
|
||||
|
||||
static int
|
||||
@ -1603,9 +1744,13 @@ const int do_norm_secs;
|
||||
if (dir != 0) {
|
||||
if (t == lo) {
|
||||
++t;
|
||||
if (t <= lo)
|
||||
return WRONG;
|
||||
++lo;
|
||||
} else if (t == hi) {
|
||||
--t;
|
||||
if (t >= hi)
|
||||
return WRONG;
|
||||
--hi;
|
||||
}
|
||||
if (lo > hi)
|
||||
@ -1705,7 +1850,7 @@ const long offset;
|
||||
t = time2(tmp, funcp, offset, &okay);
|
||||
#ifdef PCTS
|
||||
/*
|
||||
** PCTS code courtesy Grant Sullivan (grant@osf.org).
|
||||
** PCTS code courtesy Grant Sullivan.
|
||||
*/
|
||||
if (okay)
|
||||
return t;
|
||||
|
@ -1,6 +1,6 @@
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)strftime.c 7.75";
|
||||
static char elsieid[] = "@(#)strftime.c 8.1";
|
||||
/*
|
||||
** Based on the UCB version with the ID appearing below.
|
||||
** This is ANSIish only when "multibyte character == plain character".
|
||||
|
Loading…
Reference in New Issue
Block a user