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