@@ -179,9 +179,11 @@ PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1};
179
179
QTBUG-53071 <https://bugreports.qt.io/browse/QTBUG-53071>. This
180
180
workaround will no longer be needed when Qt 5.6.1 and earlier are
181
181
obsolete, say in the year 2021. */
182
+ #ifndef WORK_AROUND_QTBUG_53071
182
183
enum
183
184
{
184
185
WORK_AROUND_QTBUG_53071 = true};
186
+ #endif
185
187
186
188
static int charcnt ;
187
189
static bool errors ;
@@ -1924,12 +1926,6 @@ atcomp(const void *avp, const void *bvp)
1924
1926
return (a < b ) ? -1 : (a > b );
1925
1927
}
1926
1928
1927
- static bool
1928
- is32 (const zic_t x )
1929
- {
1930
- return x == ((zic_t ) ((int32 ) x ));
1931
- }
1932
-
1933
1929
static void
1934
1930
swaptypes (int i , int j )
1935
1931
{
@@ -1983,7 +1979,12 @@ writezone(const char *const name, const char *const string, char version,
1983
1979
zic_t one = 1 ;
1984
1980
zic_t y2038_boundary = one << 31 ;
1985
1981
ptrdiff_t nats = timecnt + WORK_AROUND_QTBUG_53071 ;
1986
- zic_t * ats = emalloc (size_product (nats , sizeof * ats + 1 ));
1982
+
1983
+ /*
1984
+ * Allocate the ATS and TYPES arrays via a single malloc, as this is a bit
1985
+ * faster.
1986
+ */
1987
+ zic_t * ats = emalloc (MAXALIGN (size_product (nats , sizeof * ats + 1 )));
1987
1988
void * typesptr = ats + nats ;
1988
1989
unsigned char * types = typesptr ;
1989
1990
@@ -2041,20 +2042,6 @@ writezone(const char *const name, const char *const string, char version,
2041
2042
types [i ] = attypes [i ].type ;
2042
2043
}
2043
2044
2044
- /*
2045
- * Work around QTBUG-53071 for timestamps less than y2038_boundary - 1, by
2046
- * inserting a no-op transition at time y2038_boundary - 1. This works
2047
- * only for timestamps before the boundary, which should be good enough in
2048
- * practice as QTBUG-53071 should be long-dead by 2038.
2049
- */
2050
- if (WORK_AROUND_QTBUG_53071 && timecnt != 0
2051
- && ats [timecnt - 1 ] < y2038_boundary - 1 && strchr (string , '<' ))
2052
- {
2053
- ats [timecnt ] = y2038_boundary - 1 ;
2054
- types [timecnt ] = types [timecnt - 1 ];
2055
- timecnt ++ ;
2056
- }
2057
-
2058
2045
/*
2059
2046
* Correct for leap seconds.
2060
2047
*/
@@ -2069,32 +2056,48 @@ writezone(const char *const name, const char *const string, char version,
2069
2056
}
2070
2057
}
2071
2058
2059
+ /*
2060
+ * Work around QTBUG-53071 for timestamps less than y2038_boundary - 1, by
2061
+ * inserting a no-op transition at time y2038_boundary - 1. This works
2062
+ * only for timestamps before the boundary, which should be good enough in
2063
+ * practice as QTBUG-53071 should be long-dead by 2038. Do this after
2064
+ * correcting for leap seconds, as the idea is to insert a transition just
2065
+ * before 32-bit pg_time_t rolls around, and this occurs at a slightly
2066
+ * different moment if transitions are leap-second corrected.
2067
+ */
2068
+ if (WORK_AROUND_QTBUG_53071 && timecnt != 0
2069
+ && ats [timecnt - 1 ] < y2038_boundary - 1 && strchr (string , '<' ))
2070
+ {
2071
+ ats [timecnt ] = y2038_boundary - 1 ;
2072
+ types [timecnt ] = types [timecnt - 1 ];
2073
+ timecnt ++ ;
2074
+ }
2075
+
2072
2076
/*
2073
2077
* Figure out 32-bit-limited starts and counts.
2074
2078
*/
2075
2079
timecnt32 = timecnt ;
2076
2080
timei32 = 0 ;
2077
2081
leapcnt32 = leapcnt ;
2078
2082
leapi32 = 0 ;
2079
- while (timecnt32 > 0 && ! is32 ( ats [timecnt32 - 1 ]) )
2083
+ while (0 < timecnt32 && PG_INT32_MAX < ats [timecnt32 - 1 ])
2080
2084
-- timecnt32 ;
2081
- while (timecnt32 > 0 && !is32 (ats [timei32 ]))
2085
+ while (1 < timecnt32 && ats [timei32 ] < PG_INT32_MIN
2086
+ && ats [timei32 + 1 ] <= PG_INT32_MIN )
2082
2087
{
2088
+ /*
2089
+ * Discard too-low transitions, except keep any last too-low
2090
+ * transition if no transition is exactly at PG_INT32_MIN. The kept
2091
+ * transition will be output as an PG_INT32_MIN "transition"
2092
+ * appropriate for buggy 32-bit clients that do not use time type 0
2093
+ * for timestamps before the first transition; see below.
2094
+ */
2083
2095
-- timecnt32 ;
2084
2096
++ timei32 ;
2085
2097
}
2086
-
2087
- /*
2088
- * Output an INT32_MIN "transition" if appropriate; see below.
2089
- */
2090
- if (timei32 > 0 && ats [timei32 ] > PG_INT32_MIN )
2091
- {
2092
- -- timei32 ;
2093
- ++ timecnt32 ;
2094
- }
2095
- while (leapcnt32 > 0 && !is32 (trans [leapcnt32 - 1 ]))
2098
+ while (0 < leapcnt32 && PG_INT32_MAX < trans [leapcnt32 - 1 ])
2096
2099
-- leapcnt32 ;
2097
- while (leapcnt32 > 0 && ! is32 ( trans [leapi32 ]) )
2100
+ while (0 < leapcnt32 && trans [leapi32 ] < PG_INT32_MIN )
2098
2101
{
2099
2102
-- leapcnt32 ;
2100
2103
++ leapi32 ;
@@ -2327,7 +2330,8 @@ writezone(const char *const name, const char *const string, char version,
2327
2330
if (pass == 1 )
2328
2331
2329
2332
/*
2330
- * Output an INT32_MIN "transition" if appropriate; see above.
2333
+ * Output an PG_INT32_MIN "transition" if appropriate; see
2334
+ * above.
2331
2335
*/
2332
2336
puttzcode (((ats [i ] < PG_INT32_MIN ) ?
2333
2337
PG_INT32_MIN : ats [i ]), fp );
0 commit comments