mirror of
https://github.com/postgres/postgres.git
synced 2025-06-25 01:02:05 +03:00
Integrate src/timezone library for all platforms. There is more we can
and should do now that we control our own destiny for timezone handling, but this commit gets the bulk of the picayune diffs in place. Magnus Hagander and Tom Lane.
This commit is contained in:
@ -4,7 +4,7 @@
|
||||
# Makefile for the timezone library
|
||||
|
||||
# IDENTIFICATION
|
||||
# $PostgreSQL: pgsql/src/timezone/Makefile,v 1.9 2004/05/18 04:10:33 momjian Exp $
|
||||
# $PostgreSQL: pgsql/src/timezone/Makefile,v 1.10 2004/05/21 05:08:06 tgl Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@ -12,13 +12,17 @@ subdir = src/timezone
|
||||
top_builddir = ../..
|
||||
include $(top_builddir)/src/Makefile.global
|
||||
|
||||
OBJS= asctime.o difftime.o localtime.o pgtz.o
|
||||
ZICOBJS= zic.o ialloc.o scheck.o localtime.o asctime.o pgtz.o
|
||||
# files to build into backend
|
||||
OBJS= localtime.o strftime.o pgtz.o
|
||||
|
||||
TZDATA := africa antarctica asia australasia europe northamerica southamerica pacificnew etcetera factory backward systemv solar87 solar88 solar89
|
||||
# files needed to build zic utility program
|
||||
ZICOBJS= zic.o ialloc.o scheck.o localtime.o
|
||||
|
||||
# timezone data files
|
||||
TZDATA := africa antarctica asia australasia europe northamerica southamerica \
|
||||
pacificnew etcetera factory backward systemv solar87 solar88 solar89
|
||||
TZDATAFILES := $(TZDATA:%=data/%)
|
||||
|
||||
ifeq ($(USE_PGTZ), yes)
|
||||
all: SUBSYS.o submake-libpgport zic
|
||||
|
||||
SUBSYS.o: $(OBJS)
|
||||
@ -31,6 +35,4 @@ install: all installdirs
|
||||
./zic -d $(DESTDIR)$(datadir)/timezone $(TZDATAFILES)
|
||||
|
||||
clean distclean maintainer-clean:
|
||||
rm -f SUBSYS.o $(OBJS) $(ZICOBJS)
|
||||
endif
|
||||
|
||||
rm -f SUBSYS.o zic $(OBJS) $(ZICOBJS)
|
||||
|
@ -3,15 +3,3 @@ from:
|
||||
|
||||
ftp://elsie.nci.nih.gov/pub/tz*.tar.gz
|
||||
|
||||
The interface is used when USE_PGTZ is defined at the top level. This
|
||||
will cause the following functions to be redefined:
|
||||
localtime pg_localtime
|
||||
gmtime pg_gmtime
|
||||
asctime pg_asctime
|
||||
ctime pg_ctime
|
||||
difftime pg_difftime
|
||||
mktime pg_mktime
|
||||
tzset pg_tzset
|
||||
|
||||
and the TIMEZONE_GLOBAL define in c.h is redefined to pg_timezone.
|
||||
|
||||
|
@ -1,75 +0,0 @@
|
||||
#include "pgtz.h"
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)asctime.c 7.9";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
/*LINTLIBRARY*/
|
||||
|
||||
#include "private.h"
|
||||
#include "tzfile.h"
|
||||
|
||||
/*
|
||||
** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, Second Edition, 1996-07-12.
|
||||
*/
|
||||
|
||||
char *
|
||||
asctime_r(timeptr, buf)
|
||||
register const struct tm * timeptr;
|
||||
char * buf;
|
||||
{
|
||||
static const char wday_name[][3] = {
|
||||
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
||||
};
|
||||
static const char mon_name[][3] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
register const char * wn;
|
||||
register const char * mn;
|
||||
|
||||
if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)
|
||||
wn = "???";
|
||||
else wn = wday_name[timeptr->tm_wday];
|
||||
if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR)
|
||||
mn = "???";
|
||||
else mn = mon_name[timeptr->tm_mon];
|
||||
/*
|
||||
** The X3J11-suggested format is
|
||||
** "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n"
|
||||
** Since the .2 in 02.2d is ignored, we drop it.
|
||||
*/
|
||||
(void) sprintf(buf, "%.3s %.3s%3d %02d:%02d:%02d %d\n",
|
||||
wn, mn,
|
||||
timeptr->tm_mday, timeptr->tm_hour,
|
||||
timeptr->tm_min, timeptr->tm_sec,
|
||||
TM_YEAR_BASE + timeptr->tm_year);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
** A la X3J11, with core dump avoidance.
|
||||
*/
|
||||
|
||||
char *
|
||||
asctime(timeptr)
|
||||
register const struct tm * timeptr;
|
||||
{
|
||||
/*
|
||||
** Big enough for something such as
|
||||
** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n
|
||||
** (two three-character abbreviations, five strings denoting integers,
|
||||
** three explicit spaces, two explicit colons, a newline,
|
||||
** and a trailing ASCII nul).
|
||||
*/
|
||||
static char result[3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) +
|
||||
3 + 2 + 1 + 1];
|
||||
|
||||
return asctime_r(timeptr, result);
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
#include "pgtz.h"
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)difftime.c 7.9";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
/*LINTLIBRARY*/
|
||||
|
||||
#include "private.h"
|
||||
|
||||
/*
|
||||
** Algorithm courtesy Paul Eggert (eggert@twinsun.com).
|
||||
*/
|
||||
|
||||
#ifdef HAVE_LONG_DOUBLE
|
||||
#define long_double long double
|
||||
#endif /* defined HAVE_LONG_DOUBLE */
|
||||
#ifndef HAVE_LONG_DOUBLE
|
||||
#define long_double double
|
||||
#endif /* !defined HAVE_LONG_DOUBLE */
|
||||
|
||||
double
|
||||
difftime(time1, time0)
|
||||
const time_t time1;
|
||||
const time_t time0;
|
||||
{
|
||||
time_t delta;
|
||||
time_t hibit;
|
||||
|
||||
{
|
||||
time_t tt;
|
||||
double d;
|
||||
long_double ld;
|
||||
|
||||
if (sizeof tt < sizeof d)
|
||||
return (double) time1 - (double) time0;
|
||||
if (sizeof tt < sizeof ld)
|
||||
return (long_double) time1 - (long_double) time0;
|
||||
}
|
||||
if (time1 < time0)
|
||||
return -difftime(time0, time1);
|
||||
/*
|
||||
** As much as possible, avoid loss of precision
|
||||
** by computing the difference before converting to double.
|
||||
*/
|
||||
delta = time1 - time0;
|
||||
if (delta >= 0)
|
||||
return delta;
|
||||
/*
|
||||
** Repair delta overflow.
|
||||
*/
|
||||
hibit = (~ (time_t) 0) << (TYPE_BIT(time_t) - 1);
|
||||
/*
|
||||
** The following expression rounds twice, which means
|
||||
** the result may not be the closest to the true answer.
|
||||
** For example, suppose time_t is 64-bit signed int,
|
||||
** long_double is IEEE 754 double with default rounding,
|
||||
** time1 = 9223372036854775807 and time0 = -1536.
|
||||
** Then the true difference is 9223372036854777343,
|
||||
** which rounds to 9223372036854777856
|
||||
** with a total error of 513.
|
||||
** But delta overflows to -9223372036854774273,
|
||||
** which rounds to -9223372036854774784, and correcting
|
||||
** this by subtracting 2 * (long_double) hibit
|
||||
** (i.e. by adding 2**64 = 18446744073709551616)
|
||||
** yields 9223372036854776832, which
|
||||
** rounds to 9223372036854775808
|
||||
** with a total error of 1535 instead.
|
||||
** This problem occurs only with very large differences.
|
||||
** It's too painful to fix this portably.
|
||||
** We are not alone in this problem;
|
||||
** some C compilers round twice when converting
|
||||
** large unsigned types to small floating types,
|
||||
** so if time_t is unsigned the "return delta" above
|
||||
** has the same double-rounding problem with those compilers.
|
||||
*/
|
||||
return delta - 2 * (long_double) hibit;
|
||||
}
|
@ -1,46 +1,30 @@
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)ialloc.c 8.29";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
/*LINTLIBRARY*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "private.h"
|
||||
|
||||
|
||||
#define nonzero(n) (((n) == 0) ? 1 : (n))
|
||||
|
||||
char *
|
||||
imalloc(n)
|
||||
const int n;
|
||||
char *imalloc(const int n)
|
||||
{
|
||||
return malloc((size_t) nonzero(n));
|
||||
}
|
||||
|
||||
char *
|
||||
icalloc(nelem, elsize)
|
||||
int nelem;
|
||||
int elsize;
|
||||
char *icalloc(int nelem, int elsize)
|
||||
{
|
||||
if (nelem == 0 || elsize == 0)
|
||||
nelem = elsize = 1;
|
||||
return calloc((size_t) nelem, (size_t) elsize);
|
||||
}
|
||||
|
||||
void *
|
||||
irealloc(pointer, size)
|
||||
void * const pointer;
|
||||
const int size;
|
||||
void *irealloc(void *pointer, const int size)
|
||||
{
|
||||
if (pointer == NULL)
|
||||
return imalloc(size);
|
||||
return realloc((void *) pointer, (size_t) nonzero(size));
|
||||
}
|
||||
|
||||
char *
|
||||
icatalloc(old, new)
|
||||
char * const old;
|
||||
const char * const new;
|
||||
char *icatalloc(char *old, const char *new)
|
||||
{
|
||||
register char * result;
|
||||
register int oldsize, newsize;
|
||||
@ -57,24 +41,18 @@ const char * const new;
|
||||
return result;
|
||||
}
|
||||
|
||||
char *
|
||||
icpyalloc(string)
|
||||
const char * const string;
|
||||
char *icpyalloc(const char *string)
|
||||
{
|
||||
return icatalloc((char *) NULL, string);
|
||||
}
|
||||
|
||||
void
|
||||
ifree(p)
|
||||
char * const p;
|
||||
void ifree(char *p)
|
||||
{
|
||||
if (p != NULL)
|
||||
(void) free(p);
|
||||
}
|
||||
|
||||
void
|
||||
icfree(p)
|
||||
char * const p;
|
||||
void icfree(char *p)
|
||||
{
|
||||
if (p != NULL)
|
||||
(void) free(p);
|
||||
|
@ -1,41 +1,22 @@
|
||||
#include "pgtz.h"
|
||||
#undef open
|
||||
#define timezone pg_timezone
|
||||
#define USG_COMPAT
|
||||
extern time_t pg_timezone;
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)localtime.c 7.78";
|
||||
#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).
|
||||
*/
|
||||
|
||||
/*LINTLIBRARY*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "pgtz.h"
|
||||
#include "private.h"
|
||||
#include "tzfile.h"
|
||||
#include "fcntl.h"
|
||||
|
||||
/*
|
||||
** SunOS 4.1.1 headers lack O_BINARY.
|
||||
*/
|
||||
|
||||
#ifdef O_BINARY
|
||||
#define OPEN_MODE (O_RDONLY | O_BINARY)
|
||||
#endif /* defined O_BINARY */
|
||||
#ifndef O_BINARY
|
||||
#define OPEN_MODE O_RDONLY
|
||||
#endif /* !defined O_BINARY */
|
||||
|
||||
#ifndef WILDABBR
|
||||
/*
|
||||
@ -71,9 +52,7 @@ static const char gmt[] = "GMT";
|
||||
** implementation dependent; for historical reasons, US rules are a
|
||||
** common default.
|
||||
*/
|
||||
#ifndef TZDEFRULESTRING
|
||||
#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
|
||||
#endif /* !defined TZDEFDST */
|
||||
|
||||
struct ttinfo { /* time type information */
|
||||
long tt_gmtoff; /* UTC offset in seconds */
|
||||
@ -90,13 +69,6 @@ struct lsinfo { /* leap second information */
|
||||
|
||||
#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#ifdef TZNAME_MAX
|
||||
#define MY_TZNAME_MAX TZNAME_MAX
|
||||
#endif /* defined TZNAME_MAX */
|
||||
#ifndef TZNAME_MAX
|
||||
#define MY_TZNAME_MAX 255
|
||||
#endif /* !defined TZNAME_MAX */
|
||||
|
||||
struct state {
|
||||
int leapcnt;
|
||||
int timecnt;
|
||||
@ -106,7 +78,7 @@ struct state {
|
||||
unsigned char types[TZ_MAX_TIMES];
|
||||
struct ttinfo ttis[TZ_MAX_TYPES];
|
||||
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
|
||||
(2 * (MY_TZNAME_MAX + 1)))];
|
||||
(2 * (TZ_STRLEN_MAX + 1)))];
|
||||
struct lsinfo lsis[TZ_MAX_LEAPS];
|
||||
};
|
||||
|
||||
@ -126,68 +98,34 @@ struct rule {
|
||||
** Prototypes for static functions.
|
||||
*/
|
||||
|
||||
static long detzcode P((const char * codep));
|
||||
static const char * getzname P((const char * strp));
|
||||
static const char * getnum P((const char * strp, int * nump, int min,
|
||||
int max));
|
||||
static const char * getsecs P((const char * strp, long * secsp));
|
||||
static const char * getoffset P((const char * strp, long * offsetp));
|
||||
static const char * getrule P((const char * strp, struct rule * rulep));
|
||||
static void gmtload P((struct state * sp));
|
||||
static void gmtsub P((const time_t * timep, long offset,
|
||||
struct tm * tmp));
|
||||
static void localsub P((const time_t * timep, long offset,
|
||||
struct tm * tmp));
|
||||
static int increment_overflow P((int * number, int delta));
|
||||
static int normalize_overflow P((int * tensptr, int * unitsptr,
|
||||
int base));
|
||||
static void settzname P((void));
|
||||
static time_t time1 P((struct tm * tmp,
|
||||
void(*funcp) P((const time_t *,
|
||||
long, struct tm *)),
|
||||
long offset));
|
||||
static time_t time2 P((struct tm *tmp,
|
||||
void(*funcp) P((const time_t *,
|
||||
long, struct tm*)),
|
||||
long offset, int * okayp));
|
||||
static time_t time2sub P((struct tm *tmp,
|
||||
void(*funcp) P((const time_t *,
|
||||
long, struct tm*)),
|
||||
long offset, int * okayp, int do_norm_secs));
|
||||
static void timesub P((const time_t * timep, long offset,
|
||||
const struct state * sp, struct tm * tmp));
|
||||
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 tzparse P((const char * name, struct state * sp,
|
||||
int lastditch));
|
||||
static long detzcode(const char *codep);
|
||||
static const char *getzname(const char *strp);
|
||||
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 *getrule(const char *strp, struct rule *rulep);
|
||||
static void gmtload(struct state *sp);
|
||||
static void gmtsub(const time_t *timep, long offset, struct pg_tm *tmp);
|
||||
static void localsub(const time_t *timep, long offset, struct pg_tm *tmp);
|
||||
static int increment_overflow(int *number, int delta);
|
||||
static int normalize_overflow(int *tensptr, int *unitsptr, int base);
|
||||
static time_t time1(struct pg_tm *tmp, void(*funcp)(const time_t *, long, struct pg_tm *), long offset);
|
||||
static time_t time2(struct pg_tm *tmp, void(*funcp)(const time_t *, long, struct pg_tm *), long offset, int *okayp);
|
||||
static time_t time2sub(struct pg_tm *tmp, void(*funcp)(const time_t *, long, struct pg_tm *), long offset, int *okayp, int do_norm_secs);
|
||||
static void timesub(const time_t *timep, long offset, const struct state *sp, struct pg_tm *tmp);
|
||||
static int tmcomp(const struct pg_tm *atmp, const struct pg_tm *btmp);
|
||||
static time_t transtime(time_t janfirst, int year, const struct rule *rulep, long offset);
|
||||
static int tzload(const char *name, struct state *sp);
|
||||
static int tzparse(const char *name, struct state *sp, int lastditch);
|
||||
|
||||
#ifdef ALL_STATE
|
||||
static struct state * lclptr;
|
||||
static struct state * gmtptr;
|
||||
#endif /* defined ALL_STATE */
|
||||
|
||||
#ifndef ALL_STATE
|
||||
static struct state lclmem;
|
||||
static struct state gmtmem;
|
||||
#define lclptr (&lclmem)
|
||||
#define gmtptr (&gmtmem)
|
||||
#endif /* State Farm */
|
||||
|
||||
#ifndef TZ_STRLEN_MAX
|
||||
#define TZ_STRLEN_MAX 255
|
||||
#endif /* !defined TZ_STRLEN_MAX */
|
||||
|
||||
static char lcl_TZname[TZ_STRLEN_MAX + 1];
|
||||
static int lcl_is_set;
|
||||
static int gmt_is_set;
|
||||
|
||||
char * tzname[2] = {
|
||||
wildabbr,
|
||||
wildabbr
|
||||
};
|
||||
static int lcl_is_set=0;
|
||||
static int gmt_is_set=0;
|
||||
|
||||
/*
|
||||
** Section 4.12.3 of X3.159-1989 requires that
|
||||
@ -197,20 +135,10 @@ char * tzname[2] = {
|
||||
** Thanks to Paul Eggert (eggert@twinsun.com) for noting this.
|
||||
*/
|
||||
|
||||
static struct tm tm;
|
||||
static struct pg_tm tm;
|
||||
|
||||
#ifdef USG_COMPAT
|
||||
time_t timezone = 0;
|
||||
int daylight = 0;
|
||||
#endif /* defined USG_COMPAT */
|
||||
|
||||
#ifdef ALTZONE
|
||||
time_t altzone = 0;
|
||||
#endif /* defined ALTZONE */
|
||||
|
||||
static long
|
||||
detzcode(codep)
|
||||
const char * const codep;
|
||||
static long detzcode(const char *codep)
|
||||
{
|
||||
register long result;
|
||||
register int i;
|
||||
@ -221,60 +149,7 @@ const char * const codep;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
settzname P((void))
|
||||
{
|
||||
register struct state * const sp = lclptr;
|
||||
register int i;
|
||||
|
||||
tzname[0] = wildabbr;
|
||||
tzname[1] = wildabbr;
|
||||
#ifdef USG_COMPAT
|
||||
daylight = 0;
|
||||
timezone = 0;
|
||||
#endif /* defined USG_COMPAT */
|
||||
#ifdef ALTZONE
|
||||
altzone = 0;
|
||||
#endif /* defined ALTZONE */
|
||||
#ifdef ALL_STATE
|
||||
if (sp == NULL) {
|
||||
tzname[0] = tzname[1] = gmt;
|
||||
return;
|
||||
}
|
||||
#endif /* defined ALL_STATE */
|
||||
for (i = 0; i < sp->typecnt; ++i) {
|
||||
register const struct ttinfo * const ttisp = &sp->ttis[i];
|
||||
|
||||
tzname[ttisp->tt_isdst] =
|
||||
&sp->chars[ttisp->tt_abbrind];
|
||||
#ifdef USG_COMPAT
|
||||
if (ttisp->tt_isdst)
|
||||
daylight = 1;
|
||||
if (i == 0 || !ttisp->tt_isdst)
|
||||
timezone = -(ttisp->tt_gmtoff);
|
||||
#endif /* defined USG_COMPAT */
|
||||
#ifdef ALTZONE
|
||||
if (i == 0 || ttisp->tt_isdst)
|
||||
altzone = -(ttisp->tt_gmtoff);
|
||||
#endif /* defined ALTZONE */
|
||||
}
|
||||
/*
|
||||
** And to get the latest zone names into tzname. . .
|
||||
*/
|
||||
for (i = 0; i < sp->timecnt; ++i) {
|
||||
register const struct ttinfo * const ttisp =
|
||||
&sp->ttis[
|
||||
sp->types[i]];
|
||||
|
||||
tzname[ttisp->tt_isdst] =
|
||||
&sp->chars[ttisp->tt_abbrind];
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
tzload(name, sp)
|
||||
register const char * name;
|
||||
register struct state * const sp;
|
||||
static int tzload(register const char *name, register struct state *sp)
|
||||
{
|
||||
register const char * p;
|
||||
register int i;
|
||||
@ -284,20 +159,14 @@ register struct state * const sp;
|
||||
return -1;
|
||||
{
|
||||
register int doaccess;
|
||||
/*
|
||||
** Section 4.9.1 of the C standard says that
|
||||
** "FILENAME_MAX expands to an integral constant expression
|
||||
** that is the size needed for an array of char large enough
|
||||
** to hold the longest file name string that the implementation
|
||||
** guarantees can be opened."
|
||||
*/
|
||||
char fullname[FILENAME_MAX + 1];
|
||||
char fullname[MAXPGPATH];
|
||||
|
||||
if (name[0] == ':')
|
||||
++name;
|
||||
doaccess = name[0] == '/';
|
||||
if (!doaccess) {
|
||||
if ((p = TZDIR) == NULL)
|
||||
p = pg_TZDIR();
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
|
||||
return -1;
|
||||
@ -313,7 +182,7 @@ register struct state * const sp;
|
||||
}
|
||||
if (doaccess && access(name, R_OK) != 0)
|
||||
return -1;
|
||||
if ((fid = open(name, OPEN_MODE)) == -1)
|
||||
if ((fid = open(name, O_RDONLY | PG_BINARY)) == -1)
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
@ -430,9 +299,7 @@ static const int year_lengths[2] = {
|
||||
** character.
|
||||
*/
|
||||
|
||||
static const char *
|
||||
getzname(strp)
|
||||
register const char * strp;
|
||||
static const char *getzname(register const char *strp)
|
||||
{
|
||||
register char c;
|
||||
|
||||
@ -449,12 +316,7 @@ register const char * strp;
|
||||
** Otherwise, return a pointer to the first character not part of the number.
|
||||
*/
|
||||
|
||||
static const char *
|
||||
getnum(strp, nump, min, max)
|
||||
register const char * strp;
|
||||
int * const nump;
|
||||
const int min;
|
||||
const int max;
|
||||
static const char *getnum(register const char *strp, int *nump, const int min, const int max)
|
||||
{
|
||||
register char c;
|
||||
register int num;
|
||||
@ -482,10 +344,7 @@ const int max;
|
||||
** of seconds.
|
||||
*/
|
||||
|
||||
static const char *
|
||||
getsecs(strp, secsp)
|
||||
register const char * strp;
|
||||
long * const secsp;
|
||||
static const char *getsecs(register const char *strp, long *secsp)
|
||||
{
|
||||
int num;
|
||||
|
||||
@ -524,10 +383,7 @@ long * const secsp;
|
||||
** Otherwise, return a pointer to the first character not part of the time.
|
||||
*/
|
||||
|
||||
static const char *
|
||||
getoffset(strp, offsetp)
|
||||
register const char * strp;
|
||||
long * const offsetp;
|
||||
static const char *getoffset(register const char *strp, long *offsetp)
|
||||
{
|
||||
register int neg = 0;
|
||||
|
||||
@ -551,10 +407,7 @@ long * const offsetp;
|
||||
** Otherwise, return a pointer to the first character not part of the rule.
|
||||
*/
|
||||
|
||||
static const char *
|
||||
getrule(strp, rulep)
|
||||
const char * strp;
|
||||
register struct rule * const rulep;
|
||||
static const char *getrule(const char *strp, register struct rule *rulep)
|
||||
{
|
||||
if (*strp == 'J') {
|
||||
/*
|
||||
@ -605,19 +458,13 @@ register struct rule * const rulep;
|
||||
** calculate the Epoch-relative time that rule takes effect.
|
||||
*/
|
||||
|
||||
static time_t
|
||||
transtime(janfirst, year, rulep, offset)
|
||||
const time_t janfirst;
|
||||
const int year;
|
||||
register const struct rule * const rulep;
|
||||
const long offset;
|
||||
static time_t transtime(const time_t janfirst, const int year, register const struct rule *rulep, const long offset)
|
||||
{
|
||||
register int leapyear;
|
||||
register time_t value;
|
||||
register time_t value = 0;
|
||||
register int i;
|
||||
int d, m1, yy0, yy1, yy2, dow;
|
||||
|
||||
INITIALIZE(value);
|
||||
leapyear = isleap(year);
|
||||
switch (rulep->r_type) {
|
||||
|
||||
@ -700,14 +547,10 @@ const long offset;
|
||||
** appropriate.
|
||||
*/
|
||||
|
||||
static int
|
||||
tzparse(name, sp, lastditch)
|
||||
const char * name;
|
||||
register struct state * const sp;
|
||||
const int lastditch;
|
||||
static int tzparse(const char *name, register struct state *sp, const int lastditch)
|
||||
{
|
||||
const char * stdname;
|
||||
const char * dstname;
|
||||
const char * dstname = NULL;
|
||||
size_t stdlen;
|
||||
size_t dstlen;
|
||||
long stdoffset;
|
||||
@ -717,7 +560,6 @@ const int lastditch;
|
||||
register char * cp;
|
||||
register int load_result;
|
||||
|
||||
INITIALIZE(dstname);
|
||||
stdname = name;
|
||||
if (lastditch) {
|
||||
stdlen = strlen(name); /* length of standard zone name */
|
||||
@ -913,83 +755,33 @@ const int lastditch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gmtload(sp)
|
||||
struct state * const sp;
|
||||
static void gmtload(struct state *sp)
|
||||
{
|
||||
if (tzload(gmt, sp) != 0)
|
||||
(void) tzparse(gmt, sp, TRUE);
|
||||
}
|
||||
|
||||
#ifndef STD_INSPIRED
|
||||
/*
|
||||
** A non-static declaration of tzsetwall in a system header file
|
||||
** may cause a warning about this upcoming static declaration...
|
||||
*/
|
||||
static
|
||||
#endif /* !defined STD_INSPIRED */
|
||||
void
|
||||
tzsetwall P((void))
|
||||
|
||||
bool pg_tzset(const char *name)
|
||||
{
|
||||
if (lcl_is_set < 0)
|
||||
return;
|
||||
lcl_is_set = -1;
|
||||
if (lcl_is_set && strcmp(lcl_TZname, name) == 0)
|
||||
return true; /* no change */
|
||||
|
||||
#ifdef ALL_STATE
|
||||
if (lclptr == NULL) {
|
||||
lclptr = (struct state *) malloc(sizeof *lclptr);
|
||||
if (lclptr == NULL) {
|
||||
settzname(); /* all we can do */
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif /* defined ALL_STATE */
|
||||
if (tzload((char *) NULL, lclptr) != 0)
|
||||
gmtload(lclptr);
|
||||
settzname();
|
||||
}
|
||||
if (strlen(name) >= sizeof(lcl_TZname))
|
||||
return false; /* not gonna fit */
|
||||
|
||||
void
|
||||
tzset P((void))
|
||||
{
|
||||
register const char * name;
|
||||
|
||||
name = getenv("TZ");
|
||||
if (name == NULL) {
|
||||
tzsetwall();
|
||||
return;
|
||||
}
|
||||
|
||||
if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0)
|
||||
return;
|
||||
lcl_is_set = strlen(name) < sizeof lcl_TZname;
|
||||
if (lcl_is_set)
|
||||
(void) strcpy(lcl_TZname, name);
|
||||
|
||||
#ifdef ALL_STATE
|
||||
if (lclptr == NULL) {
|
||||
lclptr = (struct state *) malloc(sizeof *lclptr);
|
||||
if (lclptr == NULL) {
|
||||
settzname(); /* all we can do */
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif /* defined ALL_STATE */
|
||||
if (*name == '\0') {
|
||||
/*
|
||||
** User wants it fast rather than right.
|
||||
*/
|
||||
lclptr->leapcnt = 0; /* so, we're off a little */
|
||||
lclptr->timecnt = 0;
|
||||
lclptr->typecnt = 0;
|
||||
lclptr->ttis[0].tt_isdst = 0;
|
||||
lclptr->ttis[0].tt_gmtoff = 0;
|
||||
lclptr->ttis[0].tt_abbrind = 0;
|
||||
(void) strcpy(lclptr->chars, gmt);
|
||||
} else if (tzload(name, lclptr) != 0)
|
||||
if (tzload(name, lclptr) != 0) {
|
||||
if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
|
||||
(void) gmtload(lclptr);
|
||||
settzname();
|
||||
{
|
||||
/* Unknown timezone. Fail our call instead of loading GMT! */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(lcl_TZname, name);
|
||||
lcl_is_set = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1001,12 +793,7 @@ tzset P((void))
|
||||
** The unused offset argument is for the benefit of mktime variants.
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
localsub(timep, offset, tmp)
|
||||
const time_t * const timep;
|
||||
const long offset;
|
||||
struct tm * const tmp;
|
||||
static void localsub(const time_t *timep, const long offset, struct pg_tm *tmp)
|
||||
{
|
||||
register struct state * sp;
|
||||
register const struct ttinfo * ttisp;
|
||||
@ -1014,12 +801,6 @@ struct tm * const tmp;
|
||||
const time_t t = *timep;
|
||||
|
||||
sp = lclptr;
|
||||
#ifdef ALL_STATE
|
||||
if (sp == NULL) {
|
||||
gmtsub(timep, offset, tmp);
|
||||
return;
|
||||
}
|
||||
#endif /* defined ALL_STATE */
|
||||
if (sp->timecnt == 0 || t < sp->ats[0]) {
|
||||
i = 0;
|
||||
while (sp->ttis[i].tt_isdst)
|
||||
@ -1029,7 +810,7 @@ struct tm * const tmp;
|
||||
}
|
||||
} else {
|
||||
for (i = 1; i < sp->timecnt; ++i)
|
||||
if (t < sp->ats[i])
|
||||
if (t < sp->ats[i])
|
||||
break;
|
||||
i = sp->types[i - 1];
|
||||
}
|
||||
@ -1042,114 +823,47 @@ struct tm * const tmp;
|
||||
*/
|
||||
timesub(&t, ttisp->tt_gmtoff, sp, tmp);
|
||||
tmp->tm_isdst = ttisp->tt_isdst;
|
||||
tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
|
||||
#ifdef TM_ZONE
|
||||
tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
|
||||
#endif /* defined TM_ZONE */
|
||||
tmp->tm_zone = &sp->chars[ttisp->tt_abbrind];
|
||||
}
|
||||
|
||||
struct tm *
|
||||
localtime(timep)
|
||||
const time_t * const timep;
|
||||
struct pg_tm *pg_localtime(const time_t *timep)
|
||||
{
|
||||
tzset();
|
||||
localsub(timep, 0L, &tm);
|
||||
return &tm;
|
||||
}
|
||||
|
||||
/*
|
||||
** Re-entrant version of localtime.
|
||||
*/
|
||||
|
||||
struct tm *
|
||||
localtime_r(timep, tm)
|
||||
const time_t * const timep;
|
||||
struct tm * tm;
|
||||
{
|
||||
localsub(timep, 0L, tm);
|
||||
return tm;
|
||||
}
|
||||
|
||||
/*
|
||||
** gmtsub is to gmtime as localsub is to localtime.
|
||||
*/
|
||||
|
||||
static void
|
||||
gmtsub(timep, offset, tmp)
|
||||
const time_t * const timep;
|
||||
const long offset;
|
||||
struct tm * const tmp;
|
||||
static void gmtsub(const time_t *timep, const long offset, struct pg_tm *tmp)
|
||||
{
|
||||
if (!gmt_is_set) {
|
||||
gmt_is_set = TRUE;
|
||||
#ifdef ALL_STATE
|
||||
gmtptr = (struct state *) malloc(sizeof *gmtptr);
|
||||
if (gmtptr != NULL)
|
||||
#endif /* defined ALL_STATE */
|
||||
gmtload(gmtptr);
|
||||
gmtload(gmtptr);
|
||||
}
|
||||
timesub(timep, offset, gmtptr, tmp);
|
||||
#ifdef TM_ZONE
|
||||
/*
|
||||
** Could get fancy here and deliver something such as
|
||||
** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,
|
||||
** but this is no time for a treasure hunt.
|
||||
*/
|
||||
if (offset != 0)
|
||||
tmp->TM_ZONE = wildabbr;
|
||||
tmp->tm_zone = wildabbr;
|
||||
else {
|
||||
#ifdef ALL_STATE
|
||||
if (gmtptr == NULL)
|
||||
tmp->TM_ZONE = gmt;
|
||||
else tmp->TM_ZONE = gmtptr->chars;
|
||||
#endif /* defined ALL_STATE */
|
||||
#ifndef ALL_STATE
|
||||
tmp->TM_ZONE = gmtptr->chars;
|
||||
#endif /* State Farm */
|
||||
tmp->tm_zone = gmtptr->chars;
|
||||
}
|
||||
#endif /* defined TM_ZONE */
|
||||
}
|
||||
|
||||
struct tm *
|
||||
gmtime(timep)
|
||||
const time_t * const timep;
|
||||
struct pg_tm *pg_gmtime(const time_t *timep)
|
||||
{
|
||||
gmtsub(timep, 0L, &tm);
|
||||
return &tm;
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-entrant version of gmtime.
|
||||
*/
|
||||
|
||||
struct tm *
|
||||
gmtime_r(timep, tm)
|
||||
const time_t * const timep;
|
||||
struct tm * tm;
|
||||
{
|
||||
gmtsub(timep, 0L, tm);
|
||||
return tm;
|
||||
}
|
||||
|
||||
#ifdef STD_INSPIRED
|
||||
|
||||
struct tm *
|
||||
offtime(timep, offset)
|
||||
const time_t * const timep;
|
||||
const long offset;
|
||||
{
|
||||
gmtsub(timep, offset, &tm);
|
||||
return &tm;
|
||||
}
|
||||
|
||||
#endif /* defined STD_INSPIRED */
|
||||
|
||||
static void
|
||||
timesub(timep, offset, sp, tmp)
|
||||
const time_t * const timep;
|
||||
const long offset;
|
||||
register const struct state * const sp;
|
||||
register struct tm * const tmp;
|
||||
static void timesub(const time_t *timep, const long offset, register const struct state *sp, register struct pg_tm *tmp)
|
||||
{
|
||||
register const struct lsinfo * lp;
|
||||
register long days;
|
||||
@ -1163,12 +877,7 @@ register struct tm * const tmp;
|
||||
|
||||
corr = 0;
|
||||
hit = 0;
|
||||
#ifdef ALL_STATE
|
||||
i = (sp == NULL) ? 0 : sp->leapcnt;
|
||||
#endif /* defined ALL_STATE */
|
||||
#ifndef ALL_STATE
|
||||
i = sp->leapcnt;
|
||||
#endif /* State Farm */
|
||||
while (--i >= 0) {
|
||||
lp = &sp->lsis[i];
|
||||
if (*timep >= lp->ls_trans) {
|
||||
@ -1240,32 +949,7 @@ register struct tm * const tmp;
|
||||
days = days - (long) ip[tmp->tm_mon];
|
||||
tmp->tm_mday = (int) (days + 1);
|
||||
tmp->tm_isdst = 0;
|
||||
#ifdef TM_GMTOFF
|
||||
tmp->TM_GMTOFF = offset;
|
||||
#endif /* defined TM_GMTOFF */
|
||||
}
|
||||
|
||||
char *
|
||||
ctime(timep)
|
||||
const time_t * const timep;
|
||||
{
|
||||
/*
|
||||
** Section 4.12.3.2 of X3.159-1989 requires that
|
||||
** The ctime function converts the calendar time pointed to by timer
|
||||
** to local time in the form of a string. It is equivalent to
|
||||
** asctime(localtime(timer))
|
||||
*/
|
||||
return asctime(localtime(timep));
|
||||
}
|
||||
|
||||
char *
|
||||
ctime_r(timep, buf)
|
||||
const time_t * const timep;
|
||||
char * buf;
|
||||
{
|
||||
struct tm tm;
|
||||
|
||||
return asctime_r(localtime_r(timep, &tm), buf);
|
||||
tmp->tm_gmtoff = offset;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1278,18 +962,13 @@ char * buf;
|
||||
** would still be very reasonable).
|
||||
*/
|
||||
|
||||
#ifndef WRONG
|
||||
#define WRONG (-1)
|
||||
#endif /* !defined WRONG */
|
||||
|
||||
/*
|
||||
** Simplified normalize logic courtesy Paul Eggert (eggert@twinsun.com).
|
||||
*/
|
||||
|
||||
static int
|
||||
increment_overflow(number, delta)
|
||||
int * number;
|
||||
int delta;
|
||||
static int increment_overflow(int *number, int delta)
|
||||
{
|
||||
int number0;
|
||||
|
||||
@ -1298,11 +977,7 @@ int delta;
|
||||
return (*number < number0) != (delta < 0);
|
||||
}
|
||||
|
||||
static int
|
||||
normalize_overflow(tensptr, unitsptr, base)
|
||||
int * const tensptr;
|
||||
int * const unitsptr;
|
||||
const int base;
|
||||
static int normalize_overflow(int *tensptr, int *unitsptr, const int base)
|
||||
{
|
||||
register int tensdelta;
|
||||
|
||||
@ -1313,10 +988,7 @@ const int base;
|
||||
return increment_overflow(tensptr, tensdelta);
|
||||
}
|
||||
|
||||
static int
|
||||
tmcomp(atmp, btmp)
|
||||
register const struct tm * const atmp;
|
||||
register const struct tm * const btmp;
|
||||
static int tmcomp(register const struct pg_tm *atmp, register const struct pg_tm *btmp)
|
||||
{
|
||||
register int result;
|
||||
|
||||
@ -1329,13 +1001,7 @@ register const struct tm * const btmp;
|
||||
return result;
|
||||
}
|
||||
|
||||
static time_t
|
||||
time2sub(tmp, funcp, offset, okayp, do_norm_secs)
|
||||
struct tm * const tmp;
|
||||
void (* const funcp) P((const time_t*, long, struct tm*));
|
||||
const long offset;
|
||||
int * const okayp;
|
||||
const int do_norm_secs;
|
||||
static time_t time2sub(struct pg_tm *tmp, void(*funcp)(const time_t *, long, struct pg_tm *), const long offset, int *okayp, const int do_norm_secs)
|
||||
{
|
||||
register const struct state * sp;
|
||||
register int dir;
|
||||
@ -1344,7 +1010,7 @@ const int do_norm_secs;
|
||||
register int saved_seconds;
|
||||
time_t newt;
|
||||
time_t t;
|
||||
struct tm yourtm, mytm;
|
||||
struct pg_tm yourtm, mytm;
|
||||
|
||||
*okayp = FALSE;
|
||||
yourtm = *tmp;
|
||||
@ -1447,10 +1113,6 @@ const int do_norm_secs;
|
||||
sp = (const struct state *)
|
||||
(((void *) funcp == (void *) localsub) ?
|
||||
lclptr : gmtptr);
|
||||
#ifdef ALL_STATE
|
||||
if (sp == NULL)
|
||||
return WRONG;
|
||||
#endif /* defined ALL_STATE */
|
||||
for (i = sp->typecnt - 1; i >= 0; --i) {
|
||||
if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
|
||||
continue;
|
||||
@ -1483,12 +1145,7 @@ label:
|
||||
return t;
|
||||
}
|
||||
|
||||
static time_t
|
||||
time2(tmp, funcp, offset, okayp)
|
||||
struct tm * const tmp;
|
||||
void (* const funcp) P((const time_t*, long, struct tm*));
|
||||
const long offset;
|
||||
int * const okayp;
|
||||
static time_t time2(struct pg_tm *tmp, void(*funcp)(const time_t*, long, struct pg_tm*), const long offset, int *okayp)
|
||||
{
|
||||
time_t t;
|
||||
|
||||
@ -1501,11 +1158,7 @@ int * const okayp;
|
||||
return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
|
||||
}
|
||||
|
||||
static time_t
|
||||
time1(tmp, funcp, offset)
|
||||
struct tm * const tmp;
|
||||
void (* const funcp) P((const time_t *, long, struct tm *));
|
||||
const long offset;
|
||||
static time_t time1(struct pg_tm *tmp, void (*funcp)(const time_t *, long, struct pg_tm *), const long offset)
|
||||
{
|
||||
register time_t t;
|
||||
register const struct state * sp;
|
||||
@ -1520,22 +1173,11 @@ const long offset;
|
||||
if (tmp->tm_isdst > 1)
|
||||
tmp->tm_isdst = 1;
|
||||
t = time2(tmp, funcp, offset, &okay);
|
||||
#ifdef PCTS
|
||||
/*
|
||||
** PCTS code courtesy Grant Sullivan (grant@osf.org).
|
||||
*/
|
||||
if (okay)
|
||||
return t;
|
||||
if (tmp->tm_isdst < 0)
|
||||
tmp->tm_isdst = 0; /* reset to std and try again */
|
||||
#endif /* defined PCTS */
|
||||
#ifndef PCTS
|
||||
if (okay || tmp->tm_isdst < 0)
|
||||
return t;
|
||||
#endif /* !defined PCTS */
|
||||
/*
|
||||
** We're supposed to assume that somebody took a time of one type
|
||||
** and did some math on it that yielded a "struct tm" that's bad.
|
||||
** and did some math on it that yielded a "struct pg_tm" that's bad.
|
||||
** We try to divine the type they started from and adjust to the
|
||||
** type they need.
|
||||
*/
|
||||
@ -1544,10 +1186,6 @@ const long offset;
|
||||
*/
|
||||
sp = (const struct state *) (((void *) funcp == (void *) localsub) ?
|
||||
lclptr : gmtptr);
|
||||
#ifdef ALL_STATE
|
||||
if (sp == NULL)
|
||||
return WRONG;
|
||||
#endif /* defined ALL_STATE */
|
||||
for (i = 0; i < sp->typecnt; ++i)
|
||||
seen[i] = FALSE;
|
||||
nseen = 0;
|
||||
@ -1578,135 +1216,17 @@ const long offset;
|
||||
return WRONG;
|
||||
}
|
||||
|
||||
time_t
|
||||
mktime(tmp)
|
||||
struct tm * const tmp;
|
||||
time_t pg_mktime(struct pg_tm *tmp)
|
||||
{
|
||||
tzset();
|
||||
return time1(tmp, localsub, 0L);
|
||||
}
|
||||
|
||||
#ifdef STD_INSPIRED
|
||||
|
||||
time_t
|
||||
timelocal(tmp)
|
||||
struct tm * const tmp;
|
||||
{
|
||||
tmp->tm_isdst = -1; /* in case it wasn't initialized */
|
||||
return mktime(tmp);
|
||||
}
|
||||
|
||||
time_t
|
||||
timegm(tmp)
|
||||
struct tm * const tmp;
|
||||
{
|
||||
tmp->tm_isdst = 0;
|
||||
return time1(tmp, gmtsub, 0L);
|
||||
}
|
||||
|
||||
time_t
|
||||
timeoff(tmp, offset)
|
||||
struct tm * const tmp;
|
||||
const long offset;
|
||||
{
|
||||
tmp->tm_isdst = 0;
|
||||
return time1(tmp, gmtsub, offset);
|
||||
}
|
||||
|
||||
#endif /* defined STD_INSPIRED */
|
||||
|
||||
#ifdef CMUCS
|
||||
|
||||
/*
|
||||
** The following is supplied for compatibility with
|
||||
** previous versions of the CMUCS runtime library.
|
||||
*/
|
||||
|
||||
long
|
||||
gtime(tmp)
|
||||
struct tm * const tmp;
|
||||
{
|
||||
const time_t t = mktime(tmp);
|
||||
|
||||
if (t == WRONG)
|
||||
return -1;
|
||||
return t;
|
||||
* Return the name of the current timezone
|
||||
*/
|
||||
const char *
|
||||
pg_get_current_timezone(void) {
|
||||
if (lcl_is_set)
|
||||
return lcl_TZname;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* defined CMUCS */
|
||||
|
||||
/*
|
||||
** XXX--is the below the right way to conditionalize??
|
||||
*/
|
||||
|
||||
#ifdef STD_INSPIRED
|
||||
|
||||
/*
|
||||
** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599
|
||||
** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
|
||||
** is not the case if we are accounting for leap seconds.
|
||||
** So, we provide the following conversion routines for use
|
||||
** when exchanging timestamps with POSIX conforming systems.
|
||||
*/
|
||||
|
||||
static long
|
||||
leapcorr(timep)
|
||||
time_t * timep;
|
||||
{
|
||||
register struct state * sp;
|
||||
register struct lsinfo * lp;
|
||||
register int i;
|
||||
|
||||
sp = lclptr;
|
||||
i = sp->leapcnt;
|
||||
while (--i >= 0) {
|
||||
lp = &sp->lsis[i];
|
||||
if (*timep >= lp->ls_trans)
|
||||
return lp->ls_corr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
time_t
|
||||
time2posix(t)
|
||||
time_t t;
|
||||
{
|
||||
tzset();
|
||||
return t - leapcorr(&t);
|
||||
}
|
||||
|
||||
time_t
|
||||
posix2time(t)
|
||||
time_t t;
|
||||
{
|
||||
time_t x;
|
||||
time_t y;
|
||||
|
||||
tzset();
|
||||
/*
|
||||
** For a positive leap second hit, the result
|
||||
** is not unique. For a negative leap second
|
||||
** hit, the corresponding time doesn't exist,
|
||||
** so we return an adjacent second.
|
||||
*/
|
||||
x = t + leapcorr(&t);
|
||||
y = x - leapcorr(&x);
|
||||
if (y < t) {
|
||||
do {
|
||||
x++;
|
||||
y = x - leapcorr(&x);
|
||||
} while (y < t);
|
||||
if (t != y)
|
||||
return x - 1;
|
||||
} else if (y > t) {
|
||||
do {
|
||||
--x;
|
||||
y = x - leapcorr(&x);
|
||||
} while (y > t);
|
||||
if (t != y)
|
||||
return x + 1;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
#endif /* defined STD_INSPIRED */
|
||||
|
@ -6,13 +6,22 @@
|
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.9 2004/05/18 03:36:45 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.10 2004/05/21 05:08:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#define NO_REDEFINE_TIMEFUNCS
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "miscadmin.h"
|
||||
#include "pgtime.h"
|
||||
#include "pgtz.h"
|
||||
#include "tzfile.h"
|
||||
#include "utils/elog.h"
|
||||
#include "utils/guc.h"
|
||||
|
||||
|
||||
static char tzdir[MAXPGPATH];
|
||||
@ -30,3 +39,255 @@ pg_TZDIR(void)
|
||||
done_tzdir = 1;
|
||||
return tzdir;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to determine the system timezone (as opposed to the timezone
|
||||
* set in our own library).
|
||||
*/
|
||||
#define T_YEAR (60*60*24*365)
|
||||
#define T_MONTH (60*60*24*30)
|
||||
|
||||
struct tztry {
|
||||
time_t std_t,dst_t;
|
||||
char std_time[TZ_STRLEN_MAX+1],dst_time[TZ_STRLEN_MAX+1];
|
||||
int std_ofs,dst_ofs;
|
||||
struct tm std_tm, dst_tm;
|
||||
};
|
||||
|
||||
|
||||
static bool compare_tm(struct tm *s, struct pg_tm *p) {
|
||||
if (s->tm_sec != p->tm_sec ||
|
||||
s->tm_min != p->tm_min ||
|
||||
s->tm_hour != p->tm_hour ||
|
||||
s->tm_mday != p->tm_mday ||
|
||||
s->tm_mon != p->tm_mon ||
|
||||
s->tm_year != p->tm_year ||
|
||||
s->tm_wday != p->tm_wday ||
|
||||
s->tm_yday != p->tm_yday ||
|
||||
s->tm_isdst != p->tm_isdst)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool try_timezone(char *tzname, struct tztry *tt, bool checkdst) {
|
||||
struct pg_tm *pgtm;
|
||||
|
||||
if (!pg_tzset(tzname))
|
||||
return false; /* If this timezone couldn't be picked at all */
|
||||
|
||||
/* Verify standard time */
|
||||
pgtm = pg_localtime(&(tt->std_t));
|
||||
if (!pgtm)
|
||||
return false;
|
||||
if (!compare_tm(&(tt->std_tm), pgtm))
|
||||
return false;
|
||||
|
||||
if (!checkdst)
|
||||
return true;
|
||||
|
||||
/* Now check daylight time */
|
||||
pgtm = pg_localtime(&(tt->dst_t));
|
||||
if (!pgtm)
|
||||
return false;
|
||||
if (!compare_tm(&(tt->dst_tm), pgtm))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int get_timezone_offset(struct tm *tm) {
|
||||
#if defined(HAVE_STRUCT_TM_TM_ZONE)
|
||||
return tm->tm_gmtoff;
|
||||
#elif defined(HAVE_INT_TIMEZONE)
|
||||
#ifdef HAVE_UNDERSCORE_TIMEZONE
|
||||
return -_timezone;
|
||||
#else
|
||||
return -timezone;
|
||||
#endif
|
||||
#else
|
||||
#error No way to determine TZ? Can this happen?
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#define TZABBREV(tz) win32_get_timezone_abbrev(tz)
|
||||
|
||||
static char *win32_get_timezone_abbrev(char *tz) {
|
||||
static char w32tzabbr[TZ_STRLEN_MAX+1];
|
||||
int l = 0;
|
||||
char *c;
|
||||
|
||||
for (c = tz; *c; c++) {
|
||||
if (isupper(*c))
|
||||
w32tzabbr[l++] = *c;
|
||||
}
|
||||
w32tzabbr[l] = '\0';
|
||||
return w32tzabbr;
|
||||
}
|
||||
|
||||
#else
|
||||
#define TZABBREV(tz) tz
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Try to identify a timezone name (in our terminology) that matches the
|
||||
* observed behavior of the system timezone library. We cannot assume that
|
||||
* the system TZ environment setting (if indeed there is one) matches our
|
||||
* terminology, so ignore it and just look at what localtime() returns.
|
||||
*/
|
||||
static char *
|
||||
identify_system_timezone(void)
|
||||
{
|
||||
static char __tzbuf[TZ_STRLEN_MAX+1];
|
||||
bool std_found=false,
|
||||
dst_found=false;
|
||||
time_t tnow = time(NULL);
|
||||
time_t t;
|
||||
struct tztry tt;
|
||||
char cbuf[TZ_STRLEN_MAX+1];
|
||||
|
||||
/* Initialize OS timezone library */
|
||||
tzset();
|
||||
|
||||
memset(&tt, 0, sizeof(tt));
|
||||
|
||||
for (t = tnow; t < tnow+T_YEAR; t += T_MONTH) {
|
||||
struct tm *tm = localtime(&t);
|
||||
|
||||
if (tm->tm_isdst == 0 && !std_found) {
|
||||
/* Standard time */
|
||||
memcpy(&tt.std_tm, tm, sizeof(struct tm));
|
||||
memset(cbuf,0,sizeof(cbuf));
|
||||
strftime(cbuf, sizeof(cbuf)-1, "%Z", tm); /* zone abbr */
|
||||
strcpy(tt.std_time, TZABBREV(cbuf));
|
||||
tt.std_ofs = get_timezone_offset(tm);
|
||||
tt.std_t = t;
|
||||
std_found = true;
|
||||
}
|
||||
else if (tm->tm_isdst == 1 && !dst_found) {
|
||||
/* Daylight time */
|
||||
memcpy(&tt.dst_tm, tm, sizeof(struct tm));
|
||||
memset(cbuf,0,sizeof(cbuf));
|
||||
strftime(cbuf, sizeof(cbuf)-1, "%Z", tm); /* zone abbr */
|
||||
strcpy(tt.dst_time, TZABBREV(cbuf));
|
||||
tt.dst_ofs = get_timezone_offset(tm);
|
||||
tt.dst_t = t;
|
||||
dst_found = true;
|
||||
}
|
||||
if (std_found && dst_found)
|
||||
break; /* Got both standard and daylight */
|
||||
}
|
||||
|
||||
if (!std_found)
|
||||
{
|
||||
/* Failed to determine TZ! */
|
||||
ereport(LOG,
|
||||
(errmsg("unable to determine system timezone, defaulting to \"%s\"", "GMT"),
|
||||
errhint("You can specify the correct timezone in postgresql.conf.")));
|
||||
return NULL; /* go to GMT */
|
||||
}
|
||||
|
||||
if (dst_found) {
|
||||
/* Try STD<ofs>DST */
|
||||
sprintf(__tzbuf,"%s%d%s",tt.std_time,-tt.std_ofs/3600,tt.dst_time);
|
||||
if (try_timezone(__tzbuf, &tt, dst_found))
|
||||
return __tzbuf;
|
||||
}
|
||||
/* Try just the STD timezone */
|
||||
strcpy(__tzbuf,tt.std_time);
|
||||
if (try_timezone(__tzbuf, &tt, dst_found))
|
||||
return __tzbuf;
|
||||
|
||||
/* Did not find the timezone. Fallback to try a GMT zone. */
|
||||
sprintf(__tzbuf,"Etc/GMT%s%d",
|
||||
(-tt.std_ofs<0)?"+":"",tt.std_ofs/3600);
|
||||
ereport(LOG,
|
||||
(errmsg("could not recognize system timezone, defaulting to \"%s\"",
|
||||
__tzbuf),
|
||||
errhint("You can specify the correct timezone in postgresql.conf.")));
|
||||
return __tzbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether timezone is acceptable.
|
||||
*
|
||||
* What we are doing here is checking for leap-second-aware timekeeping.
|
||||
* We need to reject such TZ settings because they'll wreak havoc with our
|
||||
* date/time arithmetic.
|
||||
*
|
||||
* NB: this must NOT ereport(ERROR). The caller must get control back so that
|
||||
* it can restore the old value of TZ if we don't like the new one.
|
||||
*/
|
||||
bool
|
||||
tz_acceptable(void)
|
||||
{
|
||||
struct pg_tm tt;
|
||||
time_t time2000;
|
||||
|
||||
/*
|
||||
* To detect leap-second timekeeping, compute the time_t value for
|
||||
* local midnight, 2000-01-01. Insist that this be a multiple of 60;
|
||||
* any partial-minute offset has to be due to leap seconds.
|
||||
*/
|
||||
MemSet(&tt, 0, sizeof(tt));
|
||||
tt.tm_year = 100;
|
||||
tt.tm_mon = 0;
|
||||
tt.tm_mday = 1;
|
||||
tt.tm_isdst = -1;
|
||||
time2000 = pg_mktime(&tt);
|
||||
if ((time2000 % 60) != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Identify a suitable default timezone setting based on the environment,
|
||||
* and make it active.
|
||||
*
|
||||
* We first look to the TZ environment variable. If not found or not
|
||||
* recognized by our own code, we see if we can identify the timezone
|
||||
* from the behavior of the system timezone library. When all else fails,
|
||||
* fall back to GMT.
|
||||
*/
|
||||
const char *
|
||||
select_default_timezone(void)
|
||||
{
|
||||
char *def_tz;
|
||||
|
||||
def_tz = getenv("TZ");
|
||||
if (def_tz && pg_tzset(def_tz) && tz_acceptable())
|
||||
return def_tz;
|
||||
|
||||
def_tz = identify_system_timezone();
|
||||
if (def_tz && pg_tzset(def_tz) && tz_acceptable())
|
||||
return def_tz;
|
||||
|
||||
if (pg_tzset("GMT") && tz_acceptable())
|
||||
return "GMT";
|
||||
|
||||
ereport(FATAL,
|
||||
(errmsg("could not select a suitable default timezone"),
|
||||
errdetail("It appears that your GMT time zone uses leap seconds. PostgreSQL does not support leap seconds.")));
|
||||
return NULL; /* keep compiler quiet */
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize timezone library
|
||||
*
|
||||
* This is called after initial loading of postgresql.conf. If no TimeZone
|
||||
* setting was found therein, we try to derive one from the environment.
|
||||
*/
|
||||
void pg_timezone_initialize(void) {
|
||||
/* Do we need to try to figure the timezone? */
|
||||
if (strcmp(GetConfigOption("timezone"), "UNKNOWN") == 0) {
|
||||
const char *def_tz;
|
||||
|
||||
/* Select setting */
|
||||
def_tz = select_default_timezone();
|
||||
/* Tell GUC about the value. Will redundantly call pg_tzset() */
|
||||
SetConfigOption("timezone", def_tz, PGC_POSTMASTER, PGC_S_ENV_VAR);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,23 @@
|
||||
#include "postgres.h"
|
||||
#include "miscadmin.h"
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* pgtz.h
|
||||
* Timezone Library Integration Functions
|
||||
*
|
||||
* Note: this file contains only definitions that are private to the
|
||||
* timezone library. Public definitions are in pgtime.h.
|
||||
*
|
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/timezone/pgtz.h,v 1.7 2004/05/21 05:08:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef _PGTZ_H
|
||||
#define _PGTZ_H
|
||||
|
||||
#ifndef HAVE_SYMLINK
|
||||
#define HAVE_SYMLINK 0
|
||||
#endif
|
||||
#define TZ_STRLEN_MAX 255
|
||||
|
||||
extern char *pg_TZDIR(void);
|
||||
|
||||
#define NOID
|
||||
#define TZDIR pg_TZDIR()
|
||||
|
||||
char *pg_TZDIR(void);
|
||||
#endif /* _PGTZ_H */
|
||||
|
@ -1,5 +1,4 @@
|
||||
#ifndef PRIVATE_H
|
||||
|
||||
#define PRIVATE_H
|
||||
|
||||
/*
|
||||
@ -15,94 +14,12 @@
|
||||
** Thank you!
|
||||
*/
|
||||
|
||||
/*
|
||||
** ID
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char privatehid[] = "@(#)private.h 7.53";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
/*
|
||||
** Defaults for preprocessor symbols.
|
||||
** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_ADJTIME
|
||||
#define HAVE_ADJTIME 1
|
||||
#endif /* !defined HAVE_ADJTIME */
|
||||
|
||||
#ifndef HAVE_GETTEXT
|
||||
#define HAVE_GETTEXT 0
|
||||
#endif /* !defined HAVE_GETTEXT */
|
||||
|
||||
#ifndef HAVE_INCOMPATIBLE_CTIME_R
|
||||
#define HAVE_INCOMPATIBLE_CTIME_R 0
|
||||
#endif /* !defined INCOMPATIBLE_CTIME_R */
|
||||
|
||||
#ifndef HAVE_SETTIMEOFDAY
|
||||
#define HAVE_SETTIMEOFDAY 3
|
||||
#endif /* !defined HAVE_SETTIMEOFDAY */
|
||||
|
||||
#ifndef HAVE_STRERROR
|
||||
#define HAVE_STRERROR 1
|
||||
#endif /* !defined HAVE_STRERROR */
|
||||
|
||||
#ifndef HAVE_SYMLINK
|
||||
#define HAVE_SYMLINK 1
|
||||
#endif /* !defined HAVE_SYMLINK */
|
||||
|
||||
#ifndef HAVE_SYS_STAT_H
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
#endif /* !defined HAVE_SYS_STAT_H */
|
||||
|
||||
#ifndef HAVE_SYS_WAIT_H
|
||||
#define HAVE_SYS_WAIT_H 1
|
||||
#endif /* !defined HAVE_SYS_WAIT_H */
|
||||
|
||||
#ifndef HAVE_UNISTD_H
|
||||
#define HAVE_UNISTD_H 1
|
||||
#endif /* !defined HAVE_UNISTD_H */
|
||||
|
||||
#ifndef HAVE_UTMPX_H
|
||||
#define HAVE_UTMPX_H 0
|
||||
#endif /* !defined HAVE_UTMPX_H */
|
||||
|
||||
#ifndef LOCALE_HOME
|
||||
#define LOCALE_HOME "/usr/lib/locale"
|
||||
#endif /* !defined LOCALE_HOME */
|
||||
|
||||
#if HAVE_INCOMPATIBLE_CTIME_R
|
||||
#define asctime_r _incompatible_asctime_r
|
||||
#define ctime_r _incompatible_ctime_r
|
||||
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
|
||||
|
||||
/*
|
||||
** Nested includes
|
||||
*/
|
||||
|
||||
#include "sys/types.h" /* for time_t */
|
||||
#include "stdio.h"
|
||||
#include "errno.h"
|
||||
#include "string.h"
|
||||
#include "limits.h" /* for CHAR_BIT */
|
||||
|
||||
#define save_timezone pg_timezone
|
||||
#undef timezone
|
||||
#include "time.h"
|
||||
#define timezone save_timezone
|
||||
|
||||
#include "stdlib.h"
|
||||
|
||||
#if HAVE_GETTEXT - 0
|
||||
#include "libintl.h"
|
||||
#endif /* HAVE_GETTEXT - 0 */
|
||||
|
||||
#if HAVE_SYS_WAIT_H - 0
|
||||
#include <limits.h> /* for CHAR_BIT */
|
||||
#include <sys/wait.h> /* for WIFEXITED and WEXITSTATUS */
|
||||
#endif /* HAVE_SYS_WAIT_H - 0 */
|
||||
#include <unistd.h> /* for F_OK and R_OK */
|
||||
|
||||
#include "pgtime.h"
|
||||
|
||||
|
||||
#ifndef WIFEXITED
|
||||
#define WIFEXITED(status) (((status) & 0xff) == 0)
|
||||
@ -111,39 +28,9 @@ static char privatehid[] = "@(#)private.h 7.53";
|
||||
#define WEXITSTATUS(status) (((status) >> 8) & 0xff)
|
||||
#endif /* !defined WEXITSTATUS */
|
||||
|
||||
#if HAVE_UNISTD_H - 0
|
||||
#include "unistd.h" /* for F_OK and R_OK */
|
||||
#endif /* HAVE_UNISTD_H - 0 */
|
||||
|
||||
#if !(HAVE_UNISTD_H - 0)
|
||||
#ifndef F_OK
|
||||
#define F_OK 0
|
||||
#endif /* !defined F_OK */
|
||||
#ifndef R_OK
|
||||
#define R_OK 4
|
||||
#endif /* !defined R_OK */
|
||||
#endif /* !(HAVE_UNISTD_H - 0) */
|
||||
|
||||
/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
|
||||
#define is_digit(c) ((unsigned)(c) - '0' <= 9)
|
||||
|
||||
/*
|
||||
** Workarounds for compilers/systems.
|
||||
*/
|
||||
|
||||
/*
|
||||
** SunOS 4.1.1 cc lacks prototypes.
|
||||
*/
|
||||
|
||||
#ifndef P
|
||||
#ifdef __STDC__
|
||||
#define P(x) x
|
||||
#endif /* defined __STDC__ */
|
||||
#ifndef __STDC__
|
||||
#define P(x) ()
|
||||
#endif /* !defined __STDC__ */
|
||||
#endif /* !defined P */
|
||||
|
||||
/*
|
||||
** SunOS 4.1.1 headers lack EXIT_SUCCESS.
|
||||
*/
|
||||
@ -160,61 +47,31 @@ static char privatehid[] = "@(#)private.h 7.53";
|
||||
#define EXIT_FAILURE 1
|
||||
#endif /* !defined EXIT_FAILURE */
|
||||
|
||||
/*
|
||||
** SunOS 4.1.1 headers lack FILENAME_MAX.
|
||||
*/
|
||||
|
||||
#ifndef FILENAME_MAX
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
#ifdef unix
|
||||
#include "sys/param.h"
|
||||
#endif /* defined unix */
|
||||
#endif /* !defined MAXPATHLEN */
|
||||
|
||||
#ifdef MAXPATHLEN
|
||||
#define FILENAME_MAX MAXPATHLEN
|
||||
#endif /* defined MAXPATHLEN */
|
||||
#ifndef MAXPATHLEN
|
||||
#define FILENAME_MAX 1024 /* Pure guesswork */
|
||||
#endif /* !defined MAXPATHLEN */
|
||||
|
||||
#endif /* !defined FILENAME_MAX */
|
||||
|
||||
/*
|
||||
** SunOS 4.1.1 libraries lack remove.
|
||||
*/
|
||||
|
||||
#ifndef remove
|
||||
extern int unlink P((const char * filename));
|
||||
extern int unlink (const char * filename);
|
||||
#define remove unlink
|
||||
#endif /* !defined remove */
|
||||
|
||||
/*
|
||||
** Some ancient errno.h implementations don't declare errno.
|
||||
** But some newer errno.h implementations define it as a macro.
|
||||
** Fix the former without affecting the latter.
|
||||
*/
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif /* !defined errno */
|
||||
|
||||
/*
|
||||
** Private function declarations.
|
||||
*/
|
||||
char * icalloc P((int nelem, int elsize));
|
||||
char * icatalloc P((char * old, const char * new));
|
||||
char * icpyalloc P((const char * string));
|
||||
char * imalloc P((int n));
|
||||
void * irealloc P((void * pointer, int size));
|
||||
void icfree P((char * pointer));
|
||||
void ifree P((char * pointer));
|
||||
char * scheck P((const char *string, const char *format));
|
||||
* Private function declarations.
|
||||
*/
|
||||
extern char *icalloc (int nelem, int elsize);
|
||||
extern char *icatalloc (char *old, const char *new);
|
||||
extern char *icpyalloc (const char *string);
|
||||
extern char *imalloc (int n);
|
||||
extern void *irealloc (void *pointer, int size);
|
||||
extern void icfree (char *pointer);
|
||||
extern void ifree (char *pointer);
|
||||
extern char *scheck (const char *string, const char *format);
|
||||
|
||||
|
||||
/*
|
||||
** Finally, some convenience items.
|
||||
*/
|
||||
* Finally, some convenience items.
|
||||
*/
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
@ -243,54 +100,7 @@ char * scheck P((const char *string, const char *format));
|
||||
((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + 1 + TYPE_SIGNED(type))
|
||||
#endif /* !defined INT_STRLEN_MAXIMUM */
|
||||
|
||||
/*
|
||||
** INITIALIZE(x)
|
||||
*/
|
||||
|
||||
#ifndef GNUC_or_lint
|
||||
#ifdef lint
|
||||
#define GNUC_or_lint
|
||||
#endif /* defined lint */
|
||||
#ifndef lint
|
||||
#ifdef __GNUC__
|
||||
#define GNUC_or_lint
|
||||
#endif /* defined __GNUC__ */
|
||||
#endif /* !defined lint */
|
||||
#endif /* !defined GNUC_or_lint */
|
||||
|
||||
#ifndef INITIALIZE
|
||||
#ifdef GNUC_or_lint
|
||||
#define INITIALIZE(x) ((x) = 0)
|
||||
#endif /* defined GNUC_or_lint */
|
||||
#ifndef GNUC_or_lint
|
||||
#define INITIALIZE(x)
|
||||
#endif /* !defined GNUC_or_lint */
|
||||
#endif /* !defined INITIALIZE */
|
||||
|
||||
/*
|
||||
** For the benefit of GNU folk...
|
||||
** `_(MSGID)' uses the current locale's message library string for MSGID.
|
||||
** The default is to use gettext if available, and use MSGID otherwise.
|
||||
*/
|
||||
|
||||
#ifndef _
|
||||
#if HAVE_GETTEXT - 0
|
||||
#define _(msgid) gettext(msgid)
|
||||
#else /* !(HAVE_GETTEXT - 0) */
|
||||
#define _(msgid) msgid
|
||||
#endif /* !(HAVE_GETTEXT - 0) */
|
||||
#endif /* !defined _ */
|
||||
|
||||
#ifndef TZ_DOMAIN
|
||||
#define TZ_DOMAIN "tz"
|
||||
#endif /* !defined TZ_DOMAIN */
|
||||
|
||||
#if HAVE_INCOMPATIBLE_CTIME_R
|
||||
#undef asctime_r
|
||||
#undef ctime_r
|
||||
char *asctime_r P((struct tm const *, char *));
|
||||
char *ctime_r P((time_t const *, char *));
|
||||
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
|
||||
#define _(msgid) (msgid)
|
||||
|
||||
/*
|
||||
** UNIX was a registered trademark of The Open Group in 2003.
|
||||
|
@ -1,17 +1,9 @@
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char elsieid[] = "@(#)scheck.c 8.15";
|
||||
#endif /* !defined lint */
|
||||
#endif /* !defined NOID */
|
||||
|
||||
/*LINTLIBRARY*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "private.h"
|
||||
|
||||
char *
|
||||
scheck(string, format)
|
||||
const char * const string;
|
||||
const char * const format;
|
||||
|
||||
char *scheck(const char *string, const char *format)
|
||||
{
|
||||
register char * fbuf;
|
||||
register const char * fp;
|
||||
|
480
src/timezone/strftime.c
Normal file
480
src/timezone/strftime.c
Normal file
@ -0,0 +1,480 @@
|
||||
/*
|
||||
** Copyright (c) 1989 The Regents of the University of California.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms are permitted
|
||||
** provided that the above copyright notice and this paragraph are
|
||||
** duplicated in all such forms and that any documentation,
|
||||
** advertising materials, and other materials related to such
|
||||
** distribution and use acknowledge that the software was developed
|
||||
** by the University of California, Berkeley. The name of the
|
||||
** University may not be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include "pgtz.h"
|
||||
#include "private.h"
|
||||
#include "tzfile.h"
|
||||
|
||||
|
||||
struct lc_time_T {
|
||||
const char * mon[MONSPERYEAR];
|
||||
const char * month[MONSPERYEAR];
|
||||
const char * wday[DAYSPERWEEK];
|
||||
const char * weekday[DAYSPERWEEK];
|
||||
const char * X_fmt;
|
||||
const char * x_fmt;
|
||||
const char * c_fmt;
|
||||
const char * am;
|
||||
const char * pm;
|
||||
const char * date_fmt;
|
||||
};
|
||||
|
||||
#define Locale (&C_time_locale)
|
||||
|
||||
static const struct lc_time_T C_time_locale = {
|
||||
{
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
}, {
|
||||
"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"
|
||||
}, {
|
||||
"Sun", "Mon", "Tue", "Wed",
|
||||
"Thu", "Fri", "Sat"
|
||||
}, {
|
||||
"Sunday", "Monday", "Tuesday", "Wednesday",
|
||||
"Thursday", "Friday", "Saturday"
|
||||
},
|
||||
|
||||
/* X_fmt */
|
||||
"%H:%M:%S",
|
||||
|
||||
/*
|
||||
** x_fmt
|
||||
** C99 requires this format.
|
||||
** Using just numbers (as here) makes Quakers happier;
|
||||
** it's also compatible with SVR4.
|
||||
*/
|
||||
"%m/%d/%y",
|
||||
|
||||
/*
|
||||
** c_fmt
|
||||
** C99 requires this format.
|
||||
** Previously this code used "%D %X", but we now conform to C99.
|
||||
** Note that
|
||||
** "%a %b %d %H:%M:%S %Y"
|
||||
** is used by Solaris 2.3.
|
||||
*/
|
||||
"%a %b %e %T %Y",
|
||||
|
||||
/* am */
|
||||
"AM",
|
||||
|
||||
/* pm */
|
||||
"PM",
|
||||
|
||||
/* date_fmt */
|
||||
"%a %b %e %H:%M:%S %Z %Y"
|
||||
};
|
||||
|
||||
static char * _add (const char *, char *, const char *);
|
||||
static char * _conv (int, const char *, char *, const char *);
|
||||
static char * _fmt (const char *, const struct pg_tm *, char *, const char *, int *);
|
||||
|
||||
#define IN_NONE 0
|
||||
#define IN_SOME 1
|
||||
#define IN_THIS 2
|
||||
#define IN_ALL 3
|
||||
|
||||
|
||||
size_t pg_strftime(char *s, size_t maxsize, const char *format, const struct pg_tm *t)
|
||||
{
|
||||
char * p;
|
||||
int warn;
|
||||
|
||||
warn = IN_NONE;
|
||||
p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn);
|
||||
if (p == s + maxsize)
|
||||
return 0;
|
||||
*p = '\0';
|
||||
return p - s;
|
||||
}
|
||||
|
||||
static char * _fmt(const char *format, const struct pg_tm *t, char *pt, const char *ptlim, int *warnp)
|
||||
{
|
||||
for ( ; *format; ++format) {
|
||||
if (*format == '%') {
|
||||
label:
|
||||
switch (*++format) {
|
||||
case '\0':
|
||||
--format;
|
||||
break;
|
||||
case 'A':
|
||||
pt = _add((t->tm_wday < 0 ||
|
||||
t->tm_wday >= DAYSPERWEEK) ?
|
||||
"?" : Locale->weekday[t->tm_wday],
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'a':
|
||||
pt = _add((t->tm_wday < 0 ||
|
||||
t->tm_wday >= DAYSPERWEEK) ?
|
||||
"?" : Locale->wday[t->tm_wday],
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'B':
|
||||
pt = _add((t->tm_mon < 0 ||
|
||||
t->tm_mon >= MONSPERYEAR) ?
|
||||
"?" : Locale->month[t->tm_mon],
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'b':
|
||||
case 'h':
|
||||
pt = _add((t->tm_mon < 0 ||
|
||||
t->tm_mon >= MONSPERYEAR) ?
|
||||
"?" : Locale->mon[t->tm_mon],
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'C':
|
||||
/*
|
||||
** %C used to do a...
|
||||
** _fmt("%a %b %e %X %Y", t);
|
||||
** ...whereas now POSIX 1003.2 calls for
|
||||
** something completely different.
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _conv((t->tm_year + TM_YEAR_BASE) / 100,
|
||||
"%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'c':
|
||||
{
|
||||
int warn2 = IN_SOME;
|
||||
|
||||
pt = _fmt(Locale->c_fmt, t, pt, ptlim, warnp);
|
||||
if (warn2 == IN_ALL)
|
||||
warn2 = IN_THIS;
|
||||
if (warn2 > *warnp)
|
||||
*warnp = warn2;
|
||||
}
|
||||
continue;
|
||||
case 'D':
|
||||
pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'd':
|
||||
pt = _conv(t->tm_mday, "%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'E':
|
||||
case 'O':
|
||||
/*
|
||||
** C99 locale modifiers.
|
||||
** The sequences
|
||||
** %Ec %EC %Ex %EX %Ey %EY
|
||||
** %Od %oe %OH %OI %Om %OM
|
||||
** %OS %Ou %OU %OV %Ow %OW %Oy
|
||||
** are supposed to provide alternate
|
||||
** representations.
|
||||
*/
|
||||
goto label;
|
||||
case 'e':
|
||||
pt = _conv(t->tm_mday, "%2d", pt, ptlim);
|
||||
continue;
|
||||
case 'F':
|
||||
pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'H':
|
||||
pt = _conv(t->tm_hour, "%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'I':
|
||||
pt = _conv((t->tm_hour % 12) ?
|
||||
(t->tm_hour % 12) : 12,
|
||||
"%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'j':
|
||||
pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim);
|
||||
continue;
|
||||
case 'k':
|
||||
/*
|
||||
** This used to be...
|
||||
** _conv(t->tm_hour % 12 ?
|
||||
** t->tm_hour % 12 : 12, 2, ' ');
|
||||
** ...and has been changed to the below to
|
||||
** match SunOS 4.1.1 and Arnold Robbins'
|
||||
** strftime version 3.0. That is, "%k" and
|
||||
** "%l" have been swapped.
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _conv(t->tm_hour, "%2d", pt, ptlim);
|
||||
continue;
|
||||
#ifdef KITCHEN_SINK
|
||||
case 'K':
|
||||
/*
|
||||
** After all this time, still unclaimed!
|
||||
*/
|
||||
pt = _add("kitchen sink", pt, ptlim);
|
||||
continue;
|
||||
#endif /* defined KITCHEN_SINK */
|
||||
case 'l':
|
||||
/*
|
||||
** This used to be...
|
||||
** _conv(t->tm_hour, 2, ' ');
|
||||
** ...and has been changed to the below to
|
||||
** match SunOS 4.1.1 and Arnold Robbin's
|
||||
** strftime version 3.0. That is, "%k" and
|
||||
** "%l" have been swapped.
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _conv((t->tm_hour % 12) ?
|
||||
(t->tm_hour % 12) : 12,
|
||||
"%2d", pt, ptlim);
|
||||
continue;
|
||||
case 'M':
|
||||
pt = _conv(t->tm_min, "%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'm':
|
||||
pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'n':
|
||||
pt = _add("\n", pt, ptlim);
|
||||
continue;
|
||||
case 'p':
|
||||
pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
|
||||
Locale->pm :
|
||||
Locale->am,
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'R':
|
||||
pt = _fmt("%H:%M", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'r':
|
||||
pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'S':
|
||||
pt = _conv(t->tm_sec, "%02d", pt, ptlim);
|
||||
continue;
|
||||
case 's':
|
||||
{
|
||||
struct pg_tm tm;
|
||||
char buf[INT_STRLEN_MAXIMUM(time_t) + 1];
|
||||
time_t mkt;
|
||||
|
||||
tm = *t;
|
||||
mkt = pg_mktime(&tm);
|
||||
if (TYPE_SIGNED(time_t))
|
||||
(void) sprintf(buf, "%ld", (long) mkt);
|
||||
else
|
||||
(void) sprintf(buf, "%lu", (unsigned long) mkt);
|
||||
pt = _add(buf, pt, ptlim);
|
||||
}
|
||||
continue;
|
||||
case 'T':
|
||||
pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 't':
|
||||
pt = _add("\t", pt, ptlim);
|
||||
continue;
|
||||
case 'U':
|
||||
pt = _conv((t->tm_yday + DAYSPERWEEK -
|
||||
t->tm_wday) / DAYSPERWEEK,
|
||||
"%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'u':
|
||||
/*
|
||||
** From Arnold Robbins' strftime version 3.0:
|
||||
** "ISO 8601: Weekday as a decimal number
|
||||
** [1 (Monday) - 7]"
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _conv((t->tm_wday == 0) ?
|
||||
DAYSPERWEEK : t->tm_wday,
|
||||
"%d", pt, ptlim);
|
||||
continue;
|
||||
case 'V': /* ISO 8601 week number */
|
||||
case 'G': /* ISO 8601 year (four digits) */
|
||||
case 'g': /* ISO 8601 year (two digits) */
|
||||
/*
|
||||
** From Arnold Robbins' strftime version 3.0: "the week number of the
|
||||
** year (the first Monday as the first day of week 1) as a decimal number
|
||||
** (01-53)."
|
||||
** (ado, 1993-05-24)
|
||||
**
|
||||
** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn:
|
||||
** "Week 01 of a year is per definition the first week which has the
|
||||
** Thursday in this year, which is equivalent to the week which contains
|
||||
** the fourth day of January. In other words, the first week of a new year
|
||||
** is the week which has the majority of its days in the new year. Week 01
|
||||
** might also contain days from the previous year and the week before week
|
||||
** 01 of a year is the last week (52 or 53) of the previous year even if
|
||||
** it contains days from the new year. A week starts with Monday (day 1)
|
||||
** and ends with Sunday (day 7). For example, the first week of the year
|
||||
** 1997 lasts from 1996-12-30 to 1997-01-05..."
|
||||
** (ado, 1996-01-02)
|
||||
*/
|
||||
{
|
||||
int year;
|
||||
int yday;
|
||||
int wday;
|
||||
int w;
|
||||
|
||||
year = t->tm_year + TM_YEAR_BASE;
|
||||
yday = t->tm_yday;
|
||||
wday = t->tm_wday;
|
||||
for ( ; ; ) {
|
||||
int len;
|
||||
int bot;
|
||||
int top;
|
||||
|
||||
len = isleap(year) ?
|
||||
DAYSPERLYEAR :
|
||||
DAYSPERNYEAR;
|
||||
/*
|
||||
** What yday (-3 ... 3) does
|
||||
** the ISO year begin on?
|
||||
*/
|
||||
bot = ((yday + 11 - wday) %
|
||||
DAYSPERWEEK) - 3;
|
||||
/*
|
||||
** What yday does the NEXT
|
||||
** ISO year begin on?
|
||||
*/
|
||||
top = bot -
|
||||
(len % DAYSPERWEEK);
|
||||
if (top < -3)
|
||||
top += DAYSPERWEEK;
|
||||
top += len;
|
||||
if (yday >= top) {
|
||||
++year;
|
||||
w = 1;
|
||||
break;
|
||||
}
|
||||
if (yday >= bot) {
|
||||
w = 1 + ((yday - bot) /
|
||||
DAYSPERWEEK);
|
||||
break;
|
||||
}
|
||||
--year;
|
||||
yday += isleap(year) ?
|
||||
DAYSPERLYEAR :
|
||||
DAYSPERNYEAR;
|
||||
}
|
||||
if (*format == 'V')
|
||||
pt = _conv(w, "%02d",
|
||||
pt, ptlim);
|
||||
else if (*format == 'g') {
|
||||
*warnp = IN_ALL;
|
||||
pt = _conv(year % 100, "%02d",
|
||||
pt, ptlim);
|
||||
} else pt = _conv(year, "%04d",
|
||||
pt, ptlim);
|
||||
}
|
||||
continue;
|
||||
case 'v':
|
||||
/*
|
||||
** From Arnold Robbins' strftime version 3.0:
|
||||
** "date as dd-bbb-YYYY"
|
||||
** (ado, 1993-05-24)
|
||||
*/
|
||||
pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'W':
|
||||
pt = _conv((t->tm_yday + DAYSPERWEEK -
|
||||
(t->tm_wday ?
|
||||
(t->tm_wday - 1) :
|
||||
(DAYSPERWEEK - 1))) / DAYSPERWEEK,
|
||||
"%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'w':
|
||||
pt = _conv(t->tm_wday, "%d", pt, ptlim);
|
||||
continue;
|
||||
case 'X':
|
||||
pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp);
|
||||
continue;
|
||||
case 'x':
|
||||
{
|
||||
int warn2 = IN_SOME;
|
||||
|
||||
pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2);
|
||||
if (warn2 == IN_ALL)
|
||||
warn2 = IN_THIS;
|
||||
if (warn2 > *warnp)
|
||||
*warnp = warn2;
|
||||
}
|
||||
continue;
|
||||
case 'y':
|
||||
*warnp = IN_ALL;
|
||||
pt = _conv((t->tm_year + TM_YEAR_BASE) % 100,
|
||||
"%02d", pt, ptlim);
|
||||
continue;
|
||||
case 'Y':
|
||||
pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d",
|
||||
pt, ptlim);
|
||||
continue;
|
||||
case 'Z':
|
||||
if (t->tm_zone != NULL)
|
||||
pt = _add(t->tm_zone, pt, ptlim);
|
||||
/*
|
||||
** C99 says that %Z must be replaced by the
|
||||
** empty string if the time zone is not
|
||||
** determinable.
|
||||
*/
|
||||
continue;
|
||||
case 'z':
|
||||
{
|
||||
int diff;
|
||||
char const * sign;
|
||||
|
||||
if (t->tm_isdst < 0)
|
||||
continue;
|
||||
diff = t->tm_gmtoff;
|
||||
if (diff < 0) {
|
||||
sign = "-";
|
||||
diff = -diff;
|
||||
} else sign = "+";
|
||||
pt = _add(sign, pt, ptlim);
|
||||
diff /= 60;
|
||||
pt = _conv((diff/60)*100 + diff%60,
|
||||
"%04d", pt, ptlim);
|
||||
}
|
||||
continue;
|
||||
case '+':
|
||||
pt = _fmt(Locale->date_fmt, t, pt, ptlim,
|
||||
warnp);
|
||||
continue;
|
||||
case '%':
|
||||
/*
|
||||
** X311J/88-090 (4.12.3.5): if conversion char is
|
||||
** undefined, behavior is undefined. Print out the
|
||||
** character itself as printf(3) also does.
|
||||
*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pt == ptlim)
|
||||
break;
|
||||
*pt++ = *format;
|
||||
}
|
||||
return pt;
|
||||
}
|
||||
|
||||
static char * _conv(const int n, const char *format, char *pt, const char *ptlim)
|
||||
{
|
||||
char buf[INT_STRLEN_MAXIMUM(int) + 1];
|
||||
|
||||
(void) sprintf(buf, format, n);
|
||||
return _add(buf, pt, ptlim);
|
||||
}
|
||||
|
||||
static char *_add(const char *str, char *pt, const char *ptlim)
|
||||
{
|
||||
while (pt < ptlim && (*pt = *str++) != '\0')
|
||||
++pt;
|
||||
return pt;
|
||||
}
|
@ -15,31 +15,12 @@
|
||||
** Thank you!
|
||||
*/
|
||||
|
||||
/*
|
||||
** ID
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
#ifndef NOID
|
||||
static char tzfilehid[] = "@(#)tzfile.h 7.14";
|
||||
#endif /* !defined NOID */
|
||||
#endif /* !defined lint */
|
||||
|
||||
/*
|
||||
** Information about time zone files.
|
||||
*/
|
||||
|
||||
#ifndef TZDIR
|
||||
#define TZDIR "/usr/local/etc/zoneinfo" /* Time zone object file directory */
|
||||
#endif /* !defined TZDIR */
|
||||
|
||||
#ifndef TZDEFAULT
|
||||
#define TZDEFAULT "localtime"
|
||||
#endif /* !defined TZDEFAULT */
|
||||
|
||||
#ifndef TZDEFRULES
|
||||
#define TZDEFRULES "posixrules"
|
||||
#endif /* !defined TZDEFRULES */
|
||||
|
||||
/*
|
||||
** Each file begins with. . .
|
||||
@ -88,7 +69,6 @@ struct tzhead {
|
||||
** 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
|
||||
@ -96,29 +76,13 @@ struct tzhead {
|
||||
** (where there are three time zone transitions every fourth year).
|
||||
*/
|
||||
#define TZ_MAX_TIMES 370
|
||||
#endif /* !defined TZ_MAX_TIMES */
|
||||
|
||||
#ifndef TZ_MAX_TYPES
|
||||
#ifndef NOSOLAR
|
||||
#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
|
||||
#endif /* !defined NOSOLAR */
|
||||
#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>.
|
||||
*/
|
||||
#define TZ_MAX_TYPES 20 /* Maximum number of local time types */
|
||||
#endif /* !defined NOSOLAR */
|
||||
#endif /* !defined TZ_MAX_TYPES */
|
||||
|
||||
#ifndef TZ_MAX_CHARS
|
||||
#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
|
||||
/* (limited by what unsigned chars can hold) */
|
||||
#endif /* !defined TZ_MAX_CHARS */
|
||||
|
||||
#ifndef TZ_MAX_LEAPS
|
||||
#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
|
||||
#endif /* !defined TZ_MAX_LEAPS */
|
||||
|
||||
#define SECSPERMIN 60
|
||||
#define MINSPERHOUR 60
|
||||
@ -163,26 +127,4 @@ struct tzhead {
|
||||
|
||||
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
|
||||
|
||||
#ifndef USG
|
||||
|
||||
/*
|
||||
** Use of the underscored variants may cause problems if you move your code to
|
||||
** certain System-V-based systems; for maximum portability, use the
|
||||
** underscore-free variants. The underscored variants are provided for
|
||||
** backward compatibility only; they may disappear from future versions of
|
||||
** this file.
|
||||
*/
|
||||
|
||||
#define SECS_PER_MIN SECSPERMIN
|
||||
#define MINS_PER_HOUR MINSPERHOUR
|
||||
#define HOURS_PER_DAY HOURSPERDAY
|
||||
#define DAYS_PER_WEEK DAYSPERWEEK
|
||||
#define DAYS_PER_NYEAR DAYSPERNYEAR
|
||||
#define DAYS_PER_LYEAR DAYSPERLYEAR
|
||||
#define SECS_PER_HOUR SECSPERHOUR
|
||||
#define SECS_PER_DAY SECSPERDAY
|
||||
#define MONS_PER_YEAR MONSPERYEAR
|
||||
|
||||
#endif /* !defined USG */
|
||||
|
||||
#endif /* !defined TZFILE_H */
|
||||
|
@ -1,19 +1,20 @@
|
||||
static char elsieid[] = "@(#)zic.c 7.115";
|
||||
#include "postgres.h"
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
#include "pgtz.h"
|
||||
#undef unlink
|
||||
#undef TZDIR
|
||||
#define TZDIR "data"
|
||||
#include "private.h"
|
||||
#include "tzfile.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#undef unlink
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "private.h"
|
||||
#include "locale.h"
|
||||
#include "tzfile.h"
|
||||
|
||||
#if HAVE_SYS_STAT_H
|
||||
#include "sys/stat.h"
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#ifdef S_IRUSR
|
||||
#define MKDIR_UMASK (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
|
||||
@ -22,11 +23,7 @@ static char elsieid[] = "@(#)zic.c 7.115";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This allows zic to compile by just assigning a dummy value.
|
||||
* pgtz.c references it, but no one uses it from zic.
|
||||
*/
|
||||
char my_exec_path[MAXPGPATH] = "";
|
||||
static char elsieid[] = "@(#)zic.c 7.115";
|
||||
|
||||
/*
|
||||
** On some ancient hosts, predicates like `isspace(C)' are defined
|
||||
@ -36,7 +33,7 @@ char my_exec_path[MAXPGPATH] = "";
|
||||
** For portability, we check both ancient and modern requirements.
|
||||
** If isascii is not defined, the isascii check succeeds trivially.
|
||||
*/
|
||||
#include "ctype.h"
|
||||
#include <ctype.h>
|
||||
#ifndef isascii
|
||||
#define isascii(x) 1
|
||||
#endif
|
||||
@ -94,62 +91,57 @@ struct zone {
|
||||
time_t z_untiltime;
|
||||
};
|
||||
|
||||
extern int getopt P((int argc, char * const argv[],
|
||||
const char * options));
|
||||
extern int link P((const char * fromname, const char * toname));
|
||||
extern char * optarg;
|
||||
extern int optind;
|
||||
|
||||
static void addtt P((time_t starttime, int type));
|
||||
static int addtype P((long gmtoff, const char * abbr, int isdst,
|
||||
int ttisstd, int ttisgmt));
|
||||
static void leapadd P((time_t t, int positive, int rolling, int count));
|
||||
static void adjleap P((void));
|
||||
static void associate P((void));
|
||||
static int ciequal P((const char * ap, const char * bp));
|
||||
static void convert P((long val, char * buf));
|
||||
static void dolink P((const char * fromfile, const char * tofile));
|
||||
static void doabbr P((char * abbr, const char * format,
|
||||
const char * letters, int isdst));
|
||||
static void eat P((const char * name, int num));
|
||||
static void eats P((const char * name, int num,
|
||||
const char * rname, int rnum));
|
||||
static long eitol P((int i));
|
||||
static void error P((const char * message));
|
||||
static char ** getfields P((char * buf));
|
||||
static long gethms P((const char * string, const char * errstrng,
|
||||
int signable));
|
||||
static void infile P((const char * filename));
|
||||
static void inleap P((char ** fields, int nfields));
|
||||
static void inlink P((char ** fields, int nfields));
|
||||
static void inrule P((char ** fields, int nfields));
|
||||
static int inzcont P((char ** fields, int nfields));
|
||||
static int inzone P((char ** fields, int nfields));
|
||||
static int inzsub P((char ** fields, int nfields, int iscont));
|
||||
static int itsabbr P((const char * abbr, const char * word));
|
||||
static int itsdir P((const char * name));
|
||||
static int lowerit P((int c));
|
||||
static char * memcheck P((char * tocheck));
|
||||
static int mkdirs P((char * filename));
|
||||
static void newabbr P((const char * abbr));
|
||||
static long oadd P((long t1, long t2));
|
||||
static void outzone P((const struct zone * zp, int ntzones));
|
||||
static void puttzcode P((long code, FILE * fp));
|
||||
static int rcomp P((const void * leftp, const void * rightp));
|
||||
static time_t rpytime P((const struct rule * rp, int wantedy));
|
||||
static void rulesub P((struct rule * rp,
|
||||
extern int link (const char * fromname, const char * toname);
|
||||
static void addtt (time_t starttime, int type);
|
||||
static int addtype (long gmtoff, const char * abbr, int isdst,
|
||||
int ttisstd, int ttisgmt);
|
||||
static void leapadd (time_t t, int positive, int rolling, int count);
|
||||
static void adjleap (void);
|
||||
static void associate (void);
|
||||
static int ciequal (const char * ap, const char * bp);
|
||||
static void convert (long val, char * buf);
|
||||
static void dolink (const char * fromfile, const char * tofile);
|
||||
static void doabbr (char * abbr, const char * format,
|
||||
const char * letters, int isdst);
|
||||
static void eat (const char * name, int num);
|
||||
static void eats (const char * name, int num,
|
||||
const char * rname, int rnum);
|
||||
static long eitol (int i);
|
||||
static void error (const char * message);
|
||||
static char ** getfields (char * buf);
|
||||
static long gethms (const char * string, const char * errstrng,
|
||||
int signable);
|
||||
static void infile (const char * filename);
|
||||
static void inleap (char ** fields, int nfields);
|
||||
static void inlink (char ** fields, int nfields);
|
||||
static void inrule (char ** fields, int nfields);
|
||||
static int inzcont (char ** fields, int nfields);
|
||||
static int inzone (char ** fields, int nfields);
|
||||
static int inzsub (char ** fields, int nfields, int iscont);
|
||||
static int itsabbr (const char * abbr, const char * word);
|
||||
static int itsdir (const char * name);
|
||||
static int lowerit (int c);
|
||||
static char * memcheck (char * tocheck);
|
||||
static int mkdirs (char * filename);
|
||||
static void newabbr (const char * abbr);
|
||||
static long oadd (long t1, long t2);
|
||||
static void outzone (const struct zone * zp, int ntzones);
|
||||
static void puttzcode (long code, FILE * fp);
|
||||
static int rcomp (const void * leftp, const void * rightp);
|
||||
static time_t rpytime (const struct rule * rp, int wantedy);
|
||||
static void rulesub (struct rule * rp,
|
||||
const char * loyearp, const char * hiyearp,
|
||||
const char * typep, const char * monthp,
|
||||
const char * dayp, const char * timep));
|
||||
static void setboundaries P((void));
|
||||
static time_t tadd P((time_t t1, long t2));
|
||||
static void usage P((void));
|
||||
static void writezone P((const char * name));
|
||||
static int yearistype P((int year, const char * type));
|
||||
const char * dayp, const char * timep);
|
||||
static void setboundaries (void);
|
||||
static time_t tadd (time_t t1, long t2);
|
||||
static void usage (void);
|
||||
static void writezone (const char * name);
|
||||
static int yearistype (int year, const char * type);
|
||||
|
||||
#if !(HAVE_STRERROR - 0)
|
||||
static char * strerror P((int));
|
||||
#endif /* !(HAVE_STRERROR - 0) */
|
||||
#ifndef HAVE_STRERROR
|
||||
static char * strerror (int);
|
||||
#endif
|
||||
|
||||
static int charcnt;
|
||||
static int errors;
|
||||
@ -271,8 +263,8 @@ struct lookup {
|
||||
const int l_value;
|
||||
};
|
||||
|
||||
static struct lookup const * byword P((const char * string,
|
||||
const struct lookup * lp));
|
||||
static struct lookup const * byword (const char * string,
|
||||
const struct lookup * lp);
|
||||
|
||||
static struct lookup const line_codes[] = {
|
||||
{ "Rule", LC_RULE },
|
||||
@ -389,10 +381,8 @@ char * const ptr;
|
||||
** Error handling.
|
||||
*/
|
||||
|
||||
#if !(HAVE_STRERROR - 0)
|
||||
static char *
|
||||
strerror(errnum)
|
||||
int errnum;
|
||||
#ifndef HAVE_STRERROR
|
||||
static char *strerror(int errnum)
|
||||
{
|
||||
extern char * sys_errlist[];
|
||||
extern int sys_nerr;
|
||||
@ -400,14 +390,9 @@ int errnum;
|
||||
return (errnum > 0 && errnum <= sys_nerr) ?
|
||||
sys_errlist[errnum] : _("Unknown system error");
|
||||
}
|
||||
#endif /* !(HAVE_STRERROR - 0) */
|
||||
#endif
|
||||
|
||||
static void
|
||||
eats(name, num, rname, rnum)
|
||||
const char * const name;
|
||||
const int num;
|
||||
const char * const rname;
|
||||
const int rnum;
|
||||
static void eats(const char *name, const int num, const char *rname, const int rnum)
|
||||
{
|
||||
filename = name;
|
||||
linenum = num;
|
||||
@ -415,17 +400,12 @@ const int rnum;
|
||||
rlinenum = rnum;
|
||||
}
|
||||
|
||||
static void
|
||||
eat(name, num)
|
||||
const char * const name;
|
||||
const int num;
|
||||
static void eat(const char *name, const int num)
|
||||
{
|
||||
eats(name, num, (char *) NULL, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
error(string)
|
||||
const char * const string;
|
||||
static void error(const char *string)
|
||||
{
|
||||
/*
|
||||
** Match the format of "cc" to allow sh users to
|
||||
@ -441,9 +421,7 @@ const char * const string;
|
||||
++errors;
|
||||
}
|
||||
|
||||
static void
|
||||
warning(string)
|
||||
const char * const string;
|
||||
static void warning(const char *string)
|
||||
{
|
||||
char * cp;
|
||||
|
||||
@ -454,8 +432,7 @@ const char * const string;
|
||||
--errors;
|
||||
}
|
||||
|
||||
static void
|
||||
usage P((void))
|
||||
static void usage(void)
|
||||
{
|
||||
(void) fprintf(stderr, _("%s: usage is %s [ --version ] [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n"),
|
||||
progname, progname);
|
||||
@ -469,25 +446,15 @@ static const char * leapsec;
|
||||
static const char * yitcommand;
|
||||
static int sflag = FALSE;
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char * argv[];
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
register int i;
|
||||
register int j;
|
||||
register int c;
|
||||
|
||||
#ifdef unix
|
||||
#ifndef WIN32
|
||||
(void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH));
|
||||
#endif /* defined unix */
|
||||
#if HAVE_GETTEXT - 0
|
||||
(void) setlocale(LC_MESSAGES, "");
|
||||
#ifdef TZ_DOMAINDIR
|
||||
(void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
|
||||
#endif /* defined TEXTDOMAINDIR */
|
||||
(void) textdomain(TZ_DOMAIN);
|
||||
#endif /* HAVE_GETTEXT - 0 */
|
||||
#endif /* !WIN32 */
|
||||
progname = argv[0];
|
||||
for (i = 1; i < argc; ++i)
|
||||
if (strcmp(argv[i], "--version") == 0) {
|
||||
@ -558,7 +525,7 @@ _("%s: More than one -L option specified\n"),
|
||||
if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
|
||||
usage(); /* usage message by request */
|
||||
if (directory == NULL)
|
||||
directory = TZDIR;
|
||||
directory = "data";
|
||||
if (yitcommand == NULL)
|
||||
yitcommand = "yearistype";
|
||||
|
||||
@ -600,10 +567,7 @@ _("%s: More than one -L option specified\n"),
|
||||
return (errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
static void
|
||||
dolink(fromfile, tofile)
|
||||
const char * const fromfile;
|
||||
const char * const tofile;
|
||||
static void dolink(const char *fromfile, const char *tofile)
|
||||
{
|
||||
register char * fromname;
|
||||
register char * toname;
|
||||
@ -635,7 +599,7 @@ const char * const tofile;
|
||||
(void) exit(EXIT_FAILURE);
|
||||
|
||||
result = link(fromname, toname);
|
||||
#if (HAVE_SYMLINK - 0)
|
||||
#ifdef HAVE_SYMLINK
|
||||
if (result != 0 &&
|
||||
access(fromname, F_OK) == 0 &&
|
||||
!itsdir(fromname)) {
|
||||
@ -682,8 +646,7 @@ warning(_("hard link failed, symbolic link used"));
|
||||
#define MAX_BITS_IN_FILE 32
|
||||
#define TIME_T_BITS_IN_FILE ((TYPE_BIT(time_t) < MAX_BITS_IN_FILE) ? TYPE_BIT(time_t) : MAX_BITS_IN_FILE)
|
||||
|
||||
static void
|
||||
setboundaries P((void))
|
||||
static void setboundaries(void)
|
||||
{
|
||||
if (TYPE_SIGNED(time_t)) {
|
||||
min_time = ~ (time_t) 0;
|
||||
@ -697,15 +660,13 @@ setboundaries P((void))
|
||||
max_time <<= TIME_T_BITS_IN_FILE - 1;
|
||||
--max_time;
|
||||
}
|
||||
min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year;
|
||||
max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year;
|
||||
min_year = TM_YEAR_BASE + pg_gmtime(&min_time)->tm_year;
|
||||
max_year = TM_YEAR_BASE + pg_gmtime(&max_time)->tm_year;
|
||||
min_year_representable = min_year;
|
||||
max_year_representable = max_year;
|
||||
}
|
||||
|
||||
static int
|
||||
itsdir(name)
|
||||
const char * const name;
|
||||
static int itsdir(const char *name)
|
||||
{
|
||||
register char * myname;
|
||||
register int accres;
|
||||
@ -725,17 +686,13 @@ const char * const name;
|
||||
** Sort by rule name.
|
||||
*/
|
||||
|
||||
static int
|
||||
rcomp(cp1, cp2)
|
||||
const void * cp1;
|
||||
const void * cp2;
|
||||
static int rcomp(const void *cp1, const void *cp2)
|
||||
{
|
||||
return strcmp(((const struct rule *) cp1)->r_name,
|
||||
((const struct rule *) cp2)->r_name);
|
||||
}
|
||||
|
||||
static void
|
||||
associate P((void))
|
||||
static void associate(void)
|
||||
{
|
||||
register struct zone * zp;
|
||||
register struct rule * rp;
|
||||
@ -810,9 +767,7 @@ associate P((void))
|
||||
(void) exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void
|
||||
infile(name)
|
||||
const char * name;
|
||||
static void infile(const char *name)
|
||||
{
|
||||
register FILE * fp;
|
||||
register char ** fields;
|
||||
@ -914,11 +869,7 @@ _("%s: panic: Invalid l_value %d\n"),
|
||||
** Call error with errstring and return zero on errors.
|
||||
*/
|
||||
|
||||
static long
|
||||
gethms(string, errstring, signable)
|
||||
const char * string;
|
||||
const char * const errstring;
|
||||
const int signable;
|
||||
static long gethms(const char *string, const char *errstring, const int signable)
|
||||
{
|
||||
int hh, mm, ss, sign;
|
||||
|
||||
@ -953,10 +904,7 @@ const int signable;
|
||||
eitol(SECSPERMIN) + eitol(ss));
|
||||
}
|
||||
|
||||
static void
|
||||
inrule(fields, nfields)
|
||||
register char ** const fields;
|
||||
const int nfields;
|
||||
static void inrule(register char **fields, const int nfields)
|
||||
{
|
||||
static struct rule r;
|
||||
|
||||
@ -980,10 +928,7 @@ const int nfields;
|
||||
rules[nrules++] = r;
|
||||
}
|
||||
|
||||
static int
|
||||
inzone(fields, nfields)
|
||||
register char ** const fields;
|
||||
const int nfields;
|
||||
static int inzone(register char **fields, const int nfields)
|
||||
{
|
||||
register int i;
|
||||
static char * buf;
|
||||
@ -1025,10 +970,7 @@ _("duplicate zone name %s (file \"%s\", line %d)"),
|
||||
return inzsub(fields, nfields, FALSE);
|
||||
}
|
||||
|
||||
static int
|
||||
inzcont(fields, nfields)
|
||||
register char ** const fields;
|
||||
const int nfields;
|
||||
static int inzcont(register char **fields, const int nfields)
|
||||
{
|
||||
if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) {
|
||||
error(_("wrong number of fields on Zone continuation line"));
|
||||
@ -1037,11 +979,7 @@ const int nfields;
|
||||
return inzsub(fields, nfields, TRUE);
|
||||
}
|
||||
|
||||
static int
|
||||
inzsub(fields, nfields, iscont)
|
||||
register char ** const fields;
|
||||
const int nfields;
|
||||
const int iscont;
|
||||
static int inzsub(register char **fields, const int nfields, const int iscont)
|
||||
{
|
||||
register char * cp;
|
||||
static struct zone z;
|
||||
@ -1114,10 +1052,7 @@ const int iscont;
|
||||
return hasuntil;
|
||||
}
|
||||
|
||||
static void
|
||||
inleap(fields, nfields)
|
||||
register char ** const fields;
|
||||
const int nfields;
|
||||
static void inleap(register char **fields, const int nfields)
|
||||
{
|
||||
register const char * cp;
|
||||
register const struct lookup * lp;
|
||||
@ -1211,10 +1146,7 @@ const int nfields;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
inlink(fields, nfields)
|
||||
register char ** const fields;
|
||||
const int nfields;
|
||||
static void inlink(register char **fields, const int nfields)
|
||||
{
|
||||
struct link l;
|
||||
|
||||
@ -1239,15 +1171,7 @@ const int nfields;
|
||||
links[nlinks++] = l;
|
||||
}
|
||||
|
||||
static void
|
||||
rulesub(rp, loyearp, hiyearp, typep, monthp, dayp, timep)
|
||||
register struct rule * const rp;
|
||||
const char * const loyearp;
|
||||
const char * const hiyearp;
|
||||
const char * const typep;
|
||||
const char * const monthp;
|
||||
const char * const dayp;
|
||||
const char * const timep;
|
||||
static void rulesub(register struct rule *rp, const char *loyearp, const char *hiyearp, const char *typep, const char *monthp, const char *dayp, const char *timep)
|
||||
{
|
||||
register const struct lookup * lp;
|
||||
register const char * cp;
|
||||
@ -1399,10 +1323,7 @@ const char * const timep;
|
||||
ifree(dp);
|
||||
}
|
||||
|
||||
static void
|
||||
convert(val, buf)
|
||||
const long val;
|
||||
char * const buf;
|
||||
static void convert(const long val, char *buf)
|
||||
{
|
||||
register int i;
|
||||
register long shift;
|
||||
@ -1411,10 +1332,7 @@ char * const buf;
|
||||
buf[i] = val >> shift;
|
||||
}
|
||||
|
||||
static void
|
||||
puttzcode(val, fp)
|
||||
const long val;
|
||||
FILE * const fp;
|
||||
static void puttzcode(const long val, FILE *fp)
|
||||
{
|
||||
char buf[4];
|
||||
|
||||
@ -1422,10 +1340,7 @@ FILE * const fp;
|
||||
(void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp);
|
||||
}
|
||||
|
||||
static int
|
||||
atcomp(avp, bvp)
|
||||
void * avp;
|
||||
void * bvp;
|
||||
static int atcomp(const void *avp,const void *bvp)
|
||||
{
|
||||
if (((struct attype *) avp)->at < ((struct attype *) bvp)->at)
|
||||
return -1;
|
||||
@ -1434,9 +1349,7 @@ void * bvp;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
writezone(name)
|
||||
const char * const name;
|
||||
static void writezone(const char *name)
|
||||
{
|
||||
register FILE * fp;
|
||||
register int i, j;
|
||||
@ -1579,12 +1492,7 @@ const char * const name;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
doabbr(abbr, format, letters, isdst)
|
||||
char * const abbr;
|
||||
const char * const format;
|
||||
const char * const letters;
|
||||
const int isdst;
|
||||
static void doabbr(char *abbr, const char *format, const char *letters, const int isdst)
|
||||
{
|
||||
if (strchr(format, '/') == NULL) {
|
||||
if (letters == NULL)
|
||||
@ -1598,16 +1506,14 @@ const int isdst;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
outzone(zpfirst, zonecount)
|
||||
const struct zone * const zpfirst;
|
||||
const int zonecount;
|
||||
static void outzone(const struct zone *zpfirst, const int zonecount)
|
||||
{
|
||||
register const struct zone * zp;
|
||||
register struct rule * rp;
|
||||
register int i, j;
|
||||
register int usestart, useuntil;
|
||||
register time_t starttime, untiltime;
|
||||
register time_t starttime = 0;
|
||||
register time_t untiltime = 0;
|
||||
register long gmtoff;
|
||||
register long stdoff;
|
||||
register int year;
|
||||
@ -1617,8 +1523,6 @@ const int zonecount;
|
||||
register int type;
|
||||
char startbuf[BUFSIZ];
|
||||
|
||||
INITIALIZE(untiltime);
|
||||
INITIALIZE(starttime);
|
||||
/*
|
||||
** Now. . .finally. . .generate some useful data!
|
||||
*/
|
||||
@ -1676,11 +1580,10 @@ const int zonecount;
|
||||
}
|
||||
for ( ; ; ) {
|
||||
register int k;
|
||||
register time_t jtime, ktime;
|
||||
register time_t jtime, ktime = 0;
|
||||
register long offset;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
INITIALIZE(ktime);
|
||||
if (useuntil) {
|
||||
/*
|
||||
** Turn untiltime into UTC
|
||||
@ -1786,10 +1689,7 @@ error(_("can't determine time zone abbreviation to use just after until time"));
|
||||
writezone(zpfirst->z_name);
|
||||
}
|
||||
|
||||
static void
|
||||
addtt(starttime, type)
|
||||
const time_t starttime;
|
||||
int type;
|
||||
static void addtt(const time_t starttime, int type)
|
||||
{
|
||||
if (starttime <= min_time ||
|
||||
(timecnt == 1 && attypes[0].at < min_time)) {
|
||||
@ -1814,13 +1714,7 @@ int type;
|
||||
++timecnt;
|
||||
}
|
||||
|
||||
static int
|
||||
addtype(gmtoff, abbr, isdst, ttisstd, ttisgmt)
|
||||
const long gmtoff;
|
||||
const char * const abbr;
|
||||
const int isdst;
|
||||
const int ttisstd;
|
||||
const int ttisgmt;
|
||||
static int addtype(const long gmtoff, const char *abbr, const int isdst, const int ttisstd, const int ttisgmt)
|
||||
{
|
||||
register int i, j;
|
||||
|
||||
@ -1870,12 +1764,7 @@ const int ttisgmt;
|
||||
return i;
|
||||
}
|
||||
|
||||
static void
|
||||
leapadd(t, positive, rolling, count)
|
||||
const time_t t;
|
||||
const int positive;
|
||||
const int rolling;
|
||||
int count;
|
||||
static void leapadd(const time_t t, const int positive, const int rolling, int count)
|
||||
{
|
||||
register int i, j;
|
||||
|
||||
@ -1904,8 +1793,7 @@ int count;
|
||||
} while (positive && --count != 0);
|
||||
}
|
||||
|
||||
static void
|
||||
adjleap P((void))
|
||||
static void adjleap(void)
|
||||
{
|
||||
register int i;
|
||||
register long last = 0;
|
||||
@ -1919,10 +1807,7 @@ adjleap P((void))
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
yearistype(year, type)
|
||||
const int year;
|
||||
const char * const type;
|
||||
static int yearistype(const int year, const char *type)
|
||||
{
|
||||
static char * buf;
|
||||
int result;
|
||||
@ -1945,18 +1830,13 @@ const char * const type;
|
||||
(void) exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static int
|
||||
lowerit(a)
|
||||
int a;
|
||||
static int lowerit(int a)
|
||||
{
|
||||
a = (unsigned char) a;
|
||||
return (isascii(a) && isupper(a)) ? tolower(a) : a;
|
||||
}
|
||||
|
||||
static int
|
||||
ciequal(ap, bp) /* case-insensitive equality */
|
||||
register const char * ap;
|
||||
register const char * bp;
|
||||
static int ciequal(register const char *ap, register const char *bp)
|
||||
{
|
||||
while (lowerit(*ap) == lowerit(*bp++))
|
||||
if (*ap++ == '\0')
|
||||
@ -1964,10 +1844,7 @@ register const char * bp;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
itsabbr(abbr, word)
|
||||
register const char * abbr;
|
||||
register const char * word;
|
||||
static int itsabbr(register const char *abbr, register const char *word)
|
||||
{
|
||||
if (lowerit(*abbr) != lowerit(*word))
|
||||
return FALSE;
|
||||
@ -1980,10 +1857,7 @@ register const char * word;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const struct lookup *
|
||||
byword(word, table)
|
||||
register const char * const word;
|
||||
register const struct lookup * const table;
|
||||
static const struct lookup *byword(register const char *word, register const struct lookup *table)
|
||||
{
|
||||
register const struct lookup * foundlp;
|
||||
register const struct lookup * lp;
|
||||
@ -2009,9 +1883,7 @@ register const struct lookup * const table;
|
||||
return foundlp;
|
||||
}
|
||||
|
||||
static char **
|
||||
getfields(cp)
|
||||
register char * cp;
|
||||
static char **getfields(register char *cp)
|
||||
{
|
||||
register char * dp;
|
||||
register char ** array;
|
||||
@ -2045,10 +1917,7 @@ register char * cp;
|
||||
return array;
|
||||
}
|
||||
|
||||
static long
|
||||
oadd(t1, t2)
|
||||
const long t1;
|
||||
const long t2;
|
||||
static long oadd(const long t1, const long t2)
|
||||
{
|
||||
register long t;
|
||||
|
||||
@ -2060,10 +1929,7 @@ const long t2;
|
||||
return t;
|
||||
}
|
||||
|
||||
static time_t
|
||||
tadd(t1, t2)
|
||||
const time_t t1;
|
||||
const long t2;
|
||||
static time_t tadd(const time_t t1, const long t2)
|
||||
{
|
||||
register time_t t;
|
||||
|
||||
@ -2084,10 +1950,7 @@ const long t2;
|
||||
** 1970, 00:00 LOCAL time - in that year that the rule refers to.
|
||||
*/
|
||||
|
||||
static time_t
|
||||
rpytime(rp, wantedy)
|
||||
register const struct rule * const rp;
|
||||
register const int wantedy;
|
||||
static time_t rpytime(register const struct rule *rp, register const int wantedy)
|
||||
{
|
||||
register int y, m, i;
|
||||
register long dayoff; /* with a nod to Margaret O. */
|
||||
@ -2168,9 +2031,7 @@ register const int wantedy;
|
||||
return tadd(t, rp->r_tod);
|
||||
}
|
||||
|
||||
static void
|
||||
newabbr(string)
|
||||
const char * const string;
|
||||
static void newabbr(const char *string)
|
||||
{
|
||||
register int i;
|
||||
|
||||
@ -2183,9 +2044,7 @@ const char * const string;
|
||||
charcnt += eitol(i);
|
||||
}
|
||||
|
||||
static int
|
||||
mkdirs(argname)
|
||||
char * const argname;
|
||||
static int mkdirs(char *argname)
|
||||
{
|
||||
register char * name;
|
||||
register char * cp;
|
||||
@ -2195,7 +2054,7 @@ char * const argname;
|
||||
cp = name = ecpyalloc(argname);
|
||||
while ((cp = strchr(cp + 1, '/')) != 0) {
|
||||
*cp = '\0';
|
||||
#ifndef unix
|
||||
#ifdef WIN32
|
||||
/*
|
||||
** DOS drive specifier?
|
||||
*/
|
||||
@ -2204,7 +2063,7 @@ char * const argname;
|
||||
*cp = '/';
|
||||
continue;
|
||||
}
|
||||
#endif /* !defined unix */
|
||||
#endif /* WIN32 */
|
||||
if (!itsdir(name)) {
|
||||
/*
|
||||
** It doesn't seem to exist, so we try to create it.
|
||||
@ -2230,9 +2089,7 @@ _("%s: Can't create directory %s: %s\n"),
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long
|
||||
eitol(i)
|
||||
const int i;
|
||||
static long eitol(const int i)
|
||||
{
|
||||
long l;
|
||||
|
||||
@ -2262,3 +2119,13 @@ int link(const char *oldpath, const char *newpath) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This allows zic to compile by just assigning a dummy value.
|
||||
* localtime.c references it, but no one uses it from zic.
|
||||
*/
|
||||
char *
|
||||
pg_TZDIR(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
Reference in New Issue
Block a user