Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd8b15ee

Browse files
committed
Sync our copy of the timezone library with IANA release tzcode2020a.
This absorbs a leap-second-related bug fix in localtime.c, andteaches zic to handle an expiration marker in the leapseconds file.Neither are of any interest to us (for the foreseeable futureanyway), but we need to stay more or less in sync with upstream.Also adjust some over-eager changes in the README from commit9573384.I have no intention of making changes that require C99 in this code,until such time as all the live back branches require C99. Otherwiseback-patching will get too exciting.For the same reason, absorb assorted whitespace and other cosmeticchanges from HEAD into the back branches; mostly this reflects use ofimproved versions of pgindent.All in all then, quite a boring update. But I figured I'd get itdone while I was looking at this code.
1 parent6924c37 commitd8b15ee

File tree

3 files changed

+142
-68
lines changed

3 files changed

+142
-68
lines changed

‎src/timezone/README

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ match properly on the old version.
5555
Time Zone code
5656
==============
5757

58-
The code in this directory is currently synced with tzcode release2019b.
58+
The code in this directory is currently synced with tzcode release2020a.
5959
There are many cosmetic (and not so cosmetic) differences from the
6060
original tzcode library, but diffs in the upstream version should usually
6161
be propagated to our version. Here are some notes about that.
@@ -71,7 +71,14 @@ fixed that.)
7171

7272
* We need the code to follow Postgres' portability conventions; this
7373
includes relying on configure's results rather than hand-hacked
74-
#defines (see private.h).
74+
#defines (see private.h in particular).
75+
76+
* Similarly, avoid relying on <stdint.h> features that may not exist on old
77+
systems. In particular this means using Postgres' definitions of the int32
78+
and int64 typedefs, not int_fast32_t/int_fast64_t. Likewise we use
79+
PG_INT32_MIN/MAX not INT32_MIN/MAX. (Once we desupport all PG versions
80+
that don't require C99, it'd be practical to rely on <stdint.h> and remove
81+
this set of diffs; but that day is not yet.)
7582

7683
* Since Postgres is typically built on a system that has its own copy
7784
of the <time.h> functions, we must avoid conflicting with those. This
@@ -109,6 +116,13 @@ to first run the tzcode source files through a sed filter like this:
109116
-e 's|^\*/| */|' \
110117
-e 's/\bregister[ \t]//g' \
111118
-e 's/\bATTRIBUTE_PURE[ \t]//g' \
119+
-e 's/int_fast32_t/int32/g' \
120+
-e 's/int_fast64_t/int64/g' \
121+
-e 's/intmax_t/int64/g' \
122+
-e 's/INT32_MIN/PG_INT32_MIN/g' \
123+
-e 's/INT32_MAX/PG_INT32_MAX/g' \
124+
-e 's/INTMAX_MIN/PG_INT64_MIN/g' \
125+
-e 's/INTMAX_MAX/PG_INT64_MAX/g' \
112126
-e 's/struct[ \t]+tm\b/struct pg_tm/g' \
113127
-e 's/\btime_t\b/pg_time_t/g' \
114128
-e 's/lineno/lineno_t/g' \

‎src/timezone/localtime.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ struct rule
9292
staticstructpg_tm*gmtsub(pg_time_tconst*,int32,structpg_tm*);
9393
staticboolincrement_overflow(int*,int);
9494
staticboolincrement_overflow_time(pg_time_t*,int32);
95+
staticint64leapcorr(structstateconst*,pg_time_t);
9596
staticstructpg_tm*timesub(pg_time_tconst*,int32,structstateconst*,
9697
structpg_tm*);
9798
staticbooltypesequiv(structstateconst*,int,int);
@@ -477,12 +478,14 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
477478

478479
for (i=0;i<ts->timecnt;i++)
479480
if (sp->timecnt==0
480-
||sp->ats[sp->timecnt-1]<ts->ats[i])
481+
|| (sp->ats[sp->timecnt-1]
482+
<ts->ats[i]+leapcorr(sp,ts->ats[i])))
481483
break;
482484
while (i<ts->timecnt
483485
&&sp->timecnt<TZ_MAX_TIMES)
484486
{
485-
sp->ats[sp->timecnt]=ts->ats[i];
487+
sp->ats[sp->timecnt]
488+
=ts->ats[i]+leapcorr(sp,ts->ats[i]);
486489
sp->types[sp->timecnt]= (sp->typecnt
487490
+ts->types[i]);
488491
sp->timecnt++;
@@ -1601,6 +1604,22 @@ increment_overflow_time(pg_time_t *tp, int32 j)
16011604
return false;
16021605
}
16031606

1607+
staticint64
1608+
leapcorr(structstateconst*sp,pg_time_tt)
1609+
{
1610+
structlsinfoconst*lp;
1611+
inti;
1612+
1613+
i=sp->leapcnt;
1614+
while (--i >=0)
1615+
{
1616+
lp=&sp->lsis[i];
1617+
if (t >=lp->ls_trans)
1618+
returnlp->ls_corr;
1619+
}
1620+
return0;
1621+
}
1622+
16041623
/*
16051624
* Find the next DST transition time in the given zone after the given time
16061625
*

‎src/timezone/zic.c

Lines changed: 105 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,14 @@ static void warning(const char *string,...) pg_attribute_printf(1, 2);
125125
staticvoidusage(FILE*stream,intstatus)pg_attribute_noreturn();
126126
staticvoidaddtt(zic_tstarttime,inttype);
127127
staticintaddtype(zic_t,charconst*,bool,bool,bool);
128-
staticvoidleapadd(zic_t,bool,int,int);
128+
staticvoidleapadd(zic_t,int,int);
129129
staticvoidadjleap(void);
130130
staticvoidassociate(void);
131131
staticvoiddolink(constchar*,constchar*,bool);
132132
staticchar**getfields(char*buf);
133133
staticzic_tgethms(constchar*string,constchar*errstring);
134134
staticzic_tgetsave(char*,bool*);
135+
staticvoidinexpires(char**,int);
135136
staticvoidinfile(constchar*filename);
136137
staticvoidinleap(char**fields,intnfields);
137138
staticvoidinlink(char**fields,intnfields);
@@ -202,6 +203,7 @@ static inttypecnt;
202203
#defineLC_ZONE1
203204
#defineLC_LINK2
204205
#defineLC_LEAP3
206+
#defineLC_EXPIRES4
205207

206208
/*
207209
* Which fields are which on a Zone line.
@@ -267,6 +269,9 @@ static inttypecnt;
267269
#defineLP_ROLL6
268270
#defineLEAP_FIELDS7
269271

272+
/* Expires lines are like Leap lines, except without CORR and ROLL fields. */
273+
#defineEXPIRES_FIELDS5
274+
270275
/*
271276
* Year synonyms.
272277
*/
@@ -312,6 +317,7 @@ static struct lookup const zi_line_codes[] = {
312317
};
313318
staticstructlookupconstleap_line_codes[]= {
314319
{"Leap",LC_LEAP},
320+
{"Expires",LC_EXPIRES},
315321
{NULL,0}
316322
};
317323

@@ -584,6 +590,12 @@ static zic_t const max_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE);
584590
staticzic_tlo_time=MINVAL(zic_t,TIME_T_BITS_IN_FILE);
585591
staticzic_thi_time=MAXVAL(zic_t,TIME_T_BITS_IN_FILE);
586592

593+
/* The time specified by an Expires line, or negative if no such line. */
594+
staticzic_tleapexpires=-1;
595+
596+
/* The time specified by an #expires comment, or negative if no such line. */
597+
staticzic_tcomment_leapexpires=-1;
598+
587599
/* Set the time range of the output to TIMERANGE.
588600
Return true if successful. */
589601
staticbool
@@ -1279,7 +1291,8 @@ infile(const char *name)
12791291
}
12801292
if (nfields==0)
12811293
{
1282-
/* nothing to do */
1294+
if (name==leapsec&&*buf=='#')
1295+
sscanf(buf,"#expires "INT64_FORMAT,&comment_leapexpires);
12831296
}
12841297
elseif (wantcont)
12851298
{
@@ -1311,6 +1324,10 @@ infile(const char *name)
13111324
inleap(fields,nfields);
13121325
wantcont= false;
13131326
break;
1327+
caseLC_EXPIRES:
1328+
inexpires(fields,nfields);
1329+
wantcont= false;
1330+
break;
13141331
default:/* "cannot happen" */
13151332
fprintf(stderr,
13161333
_("%s: panic: Invalid l_value %d\n"),
@@ -1634,8 +1651,8 @@ inzsub(char **fields, int nfields, bool iscont)
16341651
returnhasuntil;
16351652
}
16361653

1637-
staticvoid
1638-
inleap(char**fields,intnfields)
1654+
staticzic_t
1655+
getleapdatetime(char**fields,intnfields,boolexpire_line)
16391656
{
16401657
constchar*cp;
16411658
conststructlookup*lp;
@@ -1651,11 +1668,6 @@ inleap(char **fields, int nfields)
16511668
zic_tt;
16521669
charxs;
16531670

1654-
if (nfields!=LEAP_FIELDS)
1655-
{
1656-
error(_("wrong number of fields on Leap line"));
1657-
return;
1658-
}
16591671
dayoff=0;
16601672
cp=fields[LP_YEAR];
16611673
if (sscanf(cp,"%d%c",&year,&xs)!=1)
@@ -1664,13 +1676,16 @@ inleap(char **fields, int nfields)
16641676
* Leapin' Lizards!
16651677
*/
16661678
error(_("invalid leaping year"));
1667-
return;
1679+
return-1;
1680+
}
1681+
if (!expire_line)
1682+
{
1683+
if (!leapseen||leapmaxyear<year)
1684+
leapmaxyear=year;
1685+
if (!leapseen||leapminyear>year)
1686+
leapminyear=year;
1687+
leapseen= true;
16681688
}
1669-
if (!leapseen||leapmaxyear<year)
1670-
leapmaxyear=year;
1671-
if (!leapseen||leapminyear>year)
1672-
leapminyear=year;
1673-
leapseen= true;
16741689
j=EPOCH_YEAR;
16751690
while (j!=year)
16761691
{
@@ -1689,7 +1704,7 @@ inleap(char **fields, int nfields)
16891704
if ((lp=byword(fields[LP_MONTH],mon_names))==NULL)
16901705
{
16911706
error(_("invalid month name"));
1692-
return;
1707+
return-1;
16931708
}
16941709
month=lp->l_value;
16951710
j=TM_JANUARY;
@@ -1704,56 +1719,70 @@ inleap(char **fields, int nfields)
17041719
day <=0||day>len_months[isleap(year)][month])
17051720
{
17061721
error(_("invalid day of month"));
1707-
return;
1722+
return-1;
17081723
}
17091724
dayoff=oadd(dayoff,day-1);
17101725
if (dayoff<min_time /SECSPERDAY)
17111726
{
17121727
error(_("time too small"));
1713-
return;
1728+
return-1;
17141729
}
17151730
if (dayoff>max_time /SECSPERDAY)
17161731
{
17171732
error(_("time too large"));
1718-
return;
1733+
return-1;
17191734
}
17201735
t=dayoff*SECSPERDAY;
17211736
tod=gethms(fields[LP_TIME],_("invalid time of day"));
1722-
cp=fields[LP_CORR];
1737+
t=tadd(t,tod);
1738+
if (t<0)
1739+
error(_("leap second precedes Epoch"));
1740+
returnt;
1741+
}
1742+
1743+
staticvoid
1744+
inleap(char**fields,intnfields)
1745+
{
1746+
if (nfields!=LEAP_FIELDS)
1747+
error(_("wrong number of fields on Leap line"));
1748+
else
17231749
{
1724-
boolpositive;
1725-
intcount;
1750+
zic_tt=getleapdatetime(fields,nfields, false);
17261751

1727-
if (strcmp(cp,"")==0)
1728-
{/* infile() turns "-" into "" */
1729-
positive= false;
1730-
count=1;
1731-
}
1732-
elseif (strcmp(cp,"+")==0)
1752+
if (0 <=t)
17331753
{
1734-
positive= true;
1735-
count=1;
1736-
}
1737-
else
1738-
{
1739-
error(_("illegal CORRECTION field on Leap line"));
1740-
return;
1741-
}
1742-
if ((lp=byword(fields[LP_ROLL],leap_types))==NULL)
1743-
{
1744-
error(_("illegal Rolling/Stationary field on Leap line"));
1745-
return;
1746-
}
1747-
t=tadd(t,tod);
1748-
if (t<0)
1749-
{
1750-
error(_("leap second precedes Epoch"));
1751-
return;
1754+
structlookupconst*lp=byword(fields[LP_ROLL],leap_types);
1755+
1756+
if (!lp)
1757+
error(_("invalid Rolling/Stationary field on Leap line"));
1758+
else
1759+
{
1760+
intcorrection=0;
1761+
1762+
if (!fields[LP_CORR][0])/* infile() turns "-" into "". */
1763+
correction=-1;
1764+
elseif (strcmp(fields[LP_CORR],"+")==0)
1765+
correction=1;
1766+
else
1767+
error(_("invalid CORRECTION field on Leap line"));
1768+
if (correction)
1769+
leapadd(t,correction,lp->l_value);
1770+
}
17521771
}
1753-
leapadd(t,positive,lp->l_value,count);
17541772
}
17551773
}
17561774

1775+
staticvoid
1776+
inexpires(char**fields,intnfields)
1777+
{
1778+
if (nfields!=EXPIRES_FIELDS)
1779+
error(_("wrong number of fields on Expires line"));
1780+
elseif (0 <=leapexpires)
1781+
error(_("multiple Expires lines"));
1782+
else
1783+
leapexpires=getleapdatetime(fields,nfields, true);
1784+
}
1785+
17571786
staticvoid
17581787
inlink(char**fields,intnfields)
17591788
{
@@ -3369,32 +3398,25 @@ addtype(zic_t utoff, char const *abbr, bool isdst, bool ttisstd, bool ttisut)
33693398
}
33703399

33713400
staticvoid
3372-
leapadd(zic_tt,boolpositive,introlling,intcount)
3401+
leapadd(zic_tt,intcorrection,introlling)
33733402
{
3374-
inti,
3375-
j;
3403+
inti;
33763404

3377-
if (leapcnt+ (positive ?count :1)>TZ_MAX_LEAPS)
3405+
if (TZ_MAX_LEAPS <=leapcnt)
33783406
{
33793407
error(_("too many leap seconds"));
33803408
exit(EXIT_FAILURE);
33813409
}
33823410
for (i=0;i<leapcnt;++i)
33833411
if (t <=trans[i])
33843412
break;
3385-
do
3386-
{
3387-
for (j=leapcnt;j>i;--j)
3388-
{
3389-
trans[j]=trans[j-1];
3390-
corr[j]=corr[j-1];
3391-
roll[j]=roll[j-1];
3392-
}
3393-
trans[i]=t;
3394-
corr[i]=positive ?1 :-count;
3395-
roll[i]=rolling;
3396-
++leapcnt;
3397-
}while (positive&&--count!=0);
3413+
memmove(&trans[i+1],&trans[i], (leapcnt-i)*sizeof*trans);
3414+
memmove(&corr[i+1],&corr[i], (leapcnt-i)*sizeof*corr);
3415+
memmove(&roll[i+1],&roll[i], (leapcnt-i)*sizeof*roll);
3416+
trans[i]=t;
3417+
corr[i]=correction;
3418+
roll[i]=rolling;
3419+
++leapcnt;
33983420
}
33993421

34003422
staticvoid
@@ -3418,6 +3440,25 @@ adjleap(void)
34183440
trans[i]=tadd(trans[i],last);
34193441
last=corr[i]+=last;
34203442
}
3443+
3444+
if (leapexpires<0)
3445+
{
3446+
leapexpires=comment_leapexpires;
3447+
if (0 <=leapexpires)
3448+
warning(_("\"#expires\" is obsolescent; use \"Expires\""));
3449+
}
3450+
3451+
if (0 <=leapexpires)
3452+
{
3453+
leapexpires=oadd(leapexpires,last);
3454+
if (!(leapcnt==0|| (trans[leapcnt-1]<leapexpires)))
3455+
{
3456+
error(_("last Leap time does not precede Expires time"));
3457+
exit(EXIT_FAILURE);
3458+
}
3459+
if (leapexpires <=hi_time)
3460+
hi_time=leapexpires-1;
3461+
}
34213462
}
34223463

34233464
staticchar*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp