Commit f285322f authored by Tom Lane's avatar Tom Lane

Sync our copy of the timezone library with IANA release tzcode2019b.

A large fraction of this diff is just due to upstream's somewhat
random decision to rename a bunch of internal variables and struct
fields.  However, there is an interesting new feature in zic:
it's grown a "-b slim" option that emits zone files without 32-bit
data and other backwards-compatibility hacks.  We should consider
whether we wish to enable that.
parent fec0778c
......@@ -55,7 +55,7 @@ match properly on the old version.
Time Zone code
==============
The code in this directory is currently synced with tzcode release 2019a.
The code in this directory is currently synced with tzcode release 2019b.
There are many cosmetic (and not so cosmetic) differences from the
original tzcode library, but diffs in the upstream version should usually
be propagated to our version. Here are some notes about that.
......@@ -127,4 +127,7 @@ and then run them through pgindent. (The first three sed patterns deal
with conversion of their block comment style to something pgindent
won't make a hash of; the remainder address other points noted above.)
After that, the files can be diff'd directly against our corresponding
files.
files. Also, it's typically helpful to diff against the previous tzcode
release (after processing that the same way), and then try to apply the
diff to our files. This will take care of most of the changes
mechanically.
......@@ -107,15 +107,15 @@ static bool typesequiv(struct state const *, int, int);
static struct pg_tm tm;
/* Initialize *S to a value based on GMTOFF, ISDST, and ABBRIND. */
/* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */
static void
init_ttinfo(struct ttinfo *s, int32 gmtoff, bool isdst, int abbrind)
init_ttinfo(struct ttinfo *s, int32 utoff, bool isdst, int desigidx)
{
s->tt_gmtoff = gmtoff;
s->tt_utoff = utoff;
s->tt_isdst = isdst;
s->tt_abbrind = abbrind;
s->tt_desigidx = desigidx;
s->tt_ttisstd = false;
s->tt_ttisgmt = false;
s->tt_ttisut = false;
}
static int32
......@@ -251,7 +251,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
for (stored = 4; stored <= 8; stored *= 2)
{
int32 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
int32 ttisgmtcnt = detzcode(up->tzhead.tzh_ttisgmtcnt);
int32 ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
int64 prevtr = 0;
int32 prevcorr = 0;
int32 leapcnt = detzcode(up->tzhead.tzh_leapcnt);
......@@ -270,7 +270,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
&& 0 <= timecnt && timecnt < TZ_MAX_TIMES
&& 0 <= charcnt && charcnt < TZ_MAX_CHARS
&& (ttisstdcnt == typecnt || ttisstdcnt == 0)
&& (ttisgmtcnt == typecnt || ttisgmtcnt == 0)))
&& (ttisutcnt == typecnt || ttisutcnt == 0)))
return EINVAL;
if (nread
< (tzheadsize /* struct tzhead */
......@@ -280,7 +280,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
+ charcnt /* chars */
+ leapcnt * (stored + 4) /* lsinfos */
+ ttisstdcnt /* ttisstds */
+ ttisgmtcnt)) /* ttisgmts */
+ ttisutcnt)) /* ttisuts */
return EINVAL;
sp->leapcnt = leapcnt;
sp->timecnt = timecnt;
......@@ -332,19 +332,19 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
{
struct ttinfo *ttisp;
unsigned char isdst,
abbrind;
desigidx;
ttisp = &sp->ttis[i];
ttisp->tt_gmtoff = detzcode(p);
ttisp->tt_utoff = detzcode(p);
p += 4;
isdst = *p++;
if (!(isdst < 2))
return EINVAL;
ttisp->tt_isdst = isdst;
abbrind = *p++;
if (!(abbrind < sp->charcnt))
desigidx = *p++;
if (!(desigidx < sp->charcnt))
return EINVAL;
ttisp->tt_abbrind = abbrind;
ttisp->tt_desigidx = desigidx;
}
for (i = 0; i < sp->charcnt; ++i)
sp->chars[i] = *p++;
......@@ -398,13 +398,13 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
struct ttinfo *ttisp;
ttisp = &sp->ttis[i];
if (ttisgmtcnt == 0)
ttisp->tt_ttisgmt = false;
if (ttisutcnt == 0)
ttisp->tt_ttisut = false;
else
{
if (*p != true && *p != false)
return EINVAL;
ttisp->tt_ttisgmt = *p++;
ttisp->tt_ttisut = *p++;
}
}
......@@ -438,13 +438,13 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
for (i = 0; i < ts->typecnt; i++)
{
char *tsabbr = ts->chars + ts->ttis[i].tt_abbrind;
char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx;
int j;
for (j = 0; j < charcnt; j++)
if (strcmp(sp->chars + j, tsabbr) == 0)
{
ts->ttis[i].tt_abbrind = j;
ts->ttis[i].tt_desigidx = j;
gotabbr++;
break;
}
......@@ -456,7 +456,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
{
strcpy(sp->chars + j, tsabbr);
charcnt = j + tsabbrlen + 1;
ts->ttis[i].tt_abbrind = j;
ts->ttis[i].tt_desigidx = j;
gotabbr++;
}
}
......@@ -614,12 +614,13 @@ typesequiv(const struct state *sp, int a, int b)
const struct ttinfo *ap = &sp->ttis[a];
const struct ttinfo *bp = &sp->ttis[b];
result = ap->tt_gmtoff == bp->tt_gmtoff &&
ap->tt_isdst == bp->tt_isdst &&
ap->tt_ttisstd == bp->tt_ttisstd &&
ap->tt_ttisgmt == bp->tt_ttisgmt &&
strcmp(&sp->chars[ap->tt_abbrind],
&sp->chars[bp->tt_abbrind]) == 0;
result = (ap->tt_utoff == bp->tt_utoff
&& ap->tt_isdst == bp->tt_isdst
&& ap->tt_ttisstd == bp->tt_ttisstd
&& ap->tt_ttisut == bp->tt_ttisut
&& (strcmp(&sp->chars[ap->tt_desigidx],
&sp->chars[bp->tt_desigidx])
== 0));
}
return result;
}
......@@ -1176,7 +1177,7 @@ tzparse(const char *name, struct state *sp, bool lastditch)
if (!sp->ttis[j].tt_isdst)
{
theirstdoffset =
-sp->ttis[j].tt_gmtoff;
-sp->ttis[j].tt_utoff;
break;
}
}
......@@ -1187,7 +1188,7 @@ tzparse(const char *name, struct state *sp, bool lastditch)
if (sp->ttis[j].tt_isdst)
{
theirdstoffset =
-sp->ttis[j].tt_gmtoff;
-sp->ttis[j].tt_utoff;
break;
}
}
......@@ -1206,7 +1207,7 @@ tzparse(const char *name, struct state *sp, bool lastditch)
{
j = sp->types[i];
sp->types[i] = sp->ttis[j].tt_isdst;
if (sp->ttis[j].tt_ttisgmt)
if (sp->ttis[j].tt_ttisut)
{
/* No adjustment to transition time */
}
......@@ -1234,7 +1235,7 @@ tzparse(const char *name, struct state *sp, bool lastditch)
theirstdoffset;
}
}
theiroffset = -sp->ttis[j].tt_gmtoff;
theiroffset = -sp->ttis[j].tt_utoff;
if (sp->ttis[j].tt_isdst)
theirdstoffset = theiroffset;
else
......@@ -1357,14 +1358,14 @@ localsub(struct state const *sp, pg_time_t const *timep,
/*
* To get (wrong) behavior that's compatible with System V Release 2.0
* you'd replace the statement below with t += ttisp->tt_gmtoff;
* you'd replace the statement below with t += ttisp->tt_utoff;
* timesub(&t, 0L, sp, tmp);
*/
result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
result = timesub(&t, ttisp->tt_utoff, sp, tmp);
if (result)
{
result->tm_isdst = ttisp->tt_isdst;
result->tm_zone = unconstify(char *, &sp->chars[ttisp->tt_abbrind]);
result->tm_zone = unconstify(char *, &sp->chars[ttisp->tt_desigidx]);
}
return result;
}
......@@ -1647,7 +1648,7 @@ pg_next_dst_boundary(const pg_time_t *timep,
break;
}
ttisp = &sp->ttis[i];
*before_gmtoff = ttisp->tt_gmtoff;
*before_gmtoff = ttisp->tt_utoff;
*before_isdst = ttisp->tt_isdst;
return 0;
}
......@@ -1700,7 +1701,7 @@ pg_next_dst_boundary(const pg_time_t *timep,
/* No known transition > t, so use last known segment's type */
i = sp->types[sp->timecnt - 1];
ttisp = &sp->ttis[i];
*before_gmtoff = ttisp->tt_gmtoff;
*before_gmtoff = ttisp->tt_utoff;
*before_isdst = ttisp->tt_isdst;
return 0;
}
......@@ -1715,13 +1716,13 @@ pg_next_dst_boundary(const pg_time_t *timep,
break;
}
ttisp = &sp->ttis[i];
*before_gmtoff = ttisp->tt_gmtoff;
*before_gmtoff = ttisp->tt_utoff;
*before_isdst = ttisp->tt_isdst;
*boundary = sp->ats[0];
/* And for "after", use the first segment's type */
i = sp->types[0];
ttisp = &sp->ttis[i];
*after_gmtoff = ttisp->tt_gmtoff;
*after_gmtoff = ttisp->tt_utoff;
*after_isdst = ttisp->tt_isdst;
return 1;
}
......@@ -1743,12 +1744,12 @@ pg_next_dst_boundary(const pg_time_t *timep,
}
j = sp->types[i - 1];
ttisp = &sp->ttis[j];
*before_gmtoff = ttisp->tt_gmtoff;
*before_gmtoff = ttisp->tt_utoff;
*before_isdst = ttisp->tt_isdst;
*boundary = sp->ats[i];
j = sp->types[i];
ttisp = &sp->ttis[j];
*after_gmtoff = ttisp->tt_gmtoff;
*after_gmtoff = ttisp->tt_utoff;
*after_isdst = ttisp->tt_isdst;
return 1;
}
......@@ -1832,9 +1833,9 @@ pg_interpret_timezone_abbrev(const char *abbrev,
for (i = cutoff - 1; i >= 0; i--)
{
ttisp = &sp->ttis[sp->types[i]];
if (ttisp->tt_abbrind == abbrind)
if (ttisp->tt_desigidx == abbrind)
{
*gmtoff = ttisp->tt_gmtoff;
*gmtoff = ttisp->tt_utoff;
*isdst = ttisp->tt_isdst;
return true;
}
......@@ -1846,9 +1847,9 @@ pg_interpret_timezone_abbrev(const char *abbrev,
for (i = cutoff; i < sp->timecnt; i++)
{
ttisp = &sp->ttis[sp->types[i]];
if (ttisp->tt_abbrind == abbrind)
if (ttisp->tt_desigidx == abbrind)
{
*gmtoff = ttisp->tt_gmtoff;
*gmtoff = ttisp->tt_utoff;
*isdst = ttisp->tt_isdst;
return true;
}
......@@ -1875,10 +1876,10 @@ pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
sp = &tz->state;
for (i = 1; i < sp->typecnt; i++)
{
if (sp->ttis[i].tt_gmtoff != sp->ttis[0].tt_gmtoff)
if (sp->ttis[i].tt_utoff != sp->ttis[0].tt_utoff)
return false;
}
*gmtoff = sp->ttis[0].tt_gmtoff;
*gmtoff = sp->ttis[0].tt_utoff;
return true;
}
......
......@@ -25,11 +25,11 @@
struct ttinfo
{ /* time type information */
int32 tt_gmtoff; /* UT offset in seconds */
int32 tt_utoff; /* UT offset in seconds */
bool tt_isdst; /* used to set tm_isdst */
int tt_abbrind; /* abbreviation list index */
int tt_desigidx; /* abbreviation list index */
bool tt_ttisstd; /* transition is std time */
bool tt_ttisgmt; /* transition is UT */
bool tt_ttisut; /* transition is UT */
};
struct lsinfo
......
......@@ -41,7 +41,7 @@ struct tzhead
char tzh_magic[4]; /* TZ_MAGIC */
char tzh_version[1]; /* '\0' or '2' or '3' as of 2013 */
char tzh_reserved[15]; /* reserved; must be zero */
char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
char tzh_ttisutcnt[4]; /* coded number of trans. time flags */
char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
char tzh_leapcnt[4]; /* coded number of leap seconds */
char tzh_timecnt[4]; /* coded number of transition times */
......@@ -64,14 +64,15 @@ struct tzhead
* one (char [4]) total correction after above
* tzh_ttisstdcnt (char)s indexed by type; if 1, transition
* time is standard time, if 0,
* transition time is wall clock time
* if absent, transition times are
* assumed to be wall clock time
* tzh_ttisgmtcnt (char)s indexed by type; if 1, transition
* time is UT, if 0,
* transition time is local time
* if absent, transition times are
* transition time is local (wall clock)
* time; if absent, transition times are
* assumed to be local time
* tzh_ttisutcnt (char)s indexed by type; if 1, transition
* time is UT, if 0, transition time is
* local time; if absent, transition
* times are assumed to be local time.
* When this is 1, the corresponding
* std/wall indicator must also be 1.
*/
/*
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment