@@ -167,9 +167,11 @@ PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1};
167
167
QTBUG-53071 <https://bugreports.qt.io/browse/QTBUG-53071>. This
168
168
workaround will no longer be needed when Qt 5.6.1 and earlier are
169
169
obsolete, say in the year 2021. */
170
+ #ifndef WORK_AROUND_QTBUG_53071
170
171
enum
171
172
{
172
173
WORK_AROUND_QTBUG_53071 = true};
174
+ #endif
173
175
174
176
static int charcnt ;
175
177
static bool errors ;
@@ -1912,12 +1914,6 @@ atcomp(const void *avp, const void *bvp)
1912
1914
return (a < b ) ? -1 : (a > b );
1913
1915
}
1914
1916
1915
- static bool
1916
- is32 (const zic_t x )
1917
- {
1918
- return x == ((zic_t ) ((int32 ) x ));
1919
- }
1920
-
1921
1917
static void
1922
1918
swaptypes (int i , int j )
1923
1919
{
@@ -1971,7 +1967,12 @@ writezone(const char *const name, const char *const string, char version,
1971
1967
zic_t one = 1 ;
1972
1968
zic_t y2038_boundary = one << 31 ;
1973
1969
ptrdiff_t nats = timecnt + WORK_AROUND_QTBUG_53071 ;
1974
- zic_t * ats = emalloc (size_product (nats , sizeof * ats + 1 ));
1970
+
1971
+ /*
1972
+ * Allocate the ATS and TYPES arrays via a single malloc, as this is a bit
1973
+ * faster.
1974
+ */
1975
+ zic_t * ats = emalloc (MAXALIGN (size_product (nats , sizeof * ats + 1 )));
1975
1976
void * typesptr = ats + nats ;
1976
1977
unsigned char * types = typesptr ;
1977
1978
@@ -2029,20 +2030,6 @@ writezone(const char *const name, const char *const string, char version,
2029
2030
types [i ] = attypes [i ].type ;
2030
2031
}
2031
2032
2032
- /*
2033
- * Work around QTBUG-53071 for timestamps less than y2038_boundary - 1, by
2034
- * inserting a no-op transition at time y2038_boundary - 1. This works
2035
- * only for timestamps before the boundary, which should be good enough in
2036
- * practice as QTBUG-53071 should be long-dead by 2038.
2037
- */
2038
- if (WORK_AROUND_QTBUG_53071 && timecnt != 0
2039
- && ats [timecnt - 1 ] < y2038_boundary - 1 && strchr (string , '<' ))
2040
- {
2041
- ats [timecnt ] = y2038_boundary - 1 ;
2042
- types [timecnt ] = types [timecnt - 1 ];
2043
- timecnt ++ ;
2044
- }
2045
-
2046
2033
/*
2047
2034
* Correct for leap seconds.
2048
2035
*/
@@ -2057,32 +2044,48 @@ writezone(const char *const name, const char *const string, char version,
2057
2044
}
2058
2045
}
2059
2046
2047
+ /*
2048
+ * Work around QTBUG-53071 for timestamps less than y2038_boundary - 1, by
2049
+ * inserting a no-op transition at time y2038_boundary - 1. This works
2050
+ * only for timestamps before the boundary, which should be good enough in
2051
+ * practice as QTBUG-53071 should be long-dead by 2038. Do this after
2052
+ * correcting for leap seconds, as the idea is to insert a transition just
2053
+ * before 32-bit pg_time_t rolls around, and this occurs at a slightly
2054
+ * different moment if transitions are leap-second corrected.
2055
+ */
2056
+ if (WORK_AROUND_QTBUG_53071 && timecnt != 0
2057
+ && ats [timecnt - 1 ] < y2038_boundary - 1 && strchr (string , '<' ))
2058
+ {
2059
+ ats [timecnt ] = y2038_boundary - 1 ;
2060
+ types [timecnt ] = types [timecnt - 1 ];
2061
+ timecnt ++ ;
2062
+ }
2063
+
2060
2064
/*
2061
2065
* Figure out 32-bit-limited starts and counts.
2062
2066
*/
2063
2067
timecnt32 = timecnt ;
2064
2068
timei32 = 0 ;
2065
2069
leapcnt32 = leapcnt ;
2066
2070
leapi32 = 0 ;
2067
- while (timecnt32 > 0 && ! is32 ( ats [timecnt32 - 1 ]) )
2071
+ while (0 < timecnt32 && PG_INT32_MAX < ats [timecnt32 - 1 ])
2068
2072
-- timecnt32 ;
2069
- while (timecnt32 > 0 && !is32 (ats [timei32 ]))
2073
+ while (1 < timecnt32 && ats [timei32 ] < PG_INT32_MIN
2074
+ && ats [timei32 + 1 ] <= PG_INT32_MIN )
2070
2075
{
2076
+ /*
2077
+ * Discard too-low transitions, except keep any last too-low
2078
+ * transition if no transition is exactly at PG_INT32_MIN. The kept
2079
+ * transition will be output as an PG_INT32_MIN "transition"
2080
+ * appropriate for buggy 32-bit clients that do not use time type 0
2081
+ * for timestamps before the first transition; see below.
2082
+ */
2071
2083
-- timecnt32 ;
2072
2084
++ timei32 ;
2073
2085
}
2074
-
2075
- /*
2076
- * Output an INT32_MIN "transition" if appropriate; see below.
2077
- */
2078
- if (timei32 > 0 && ats [timei32 ] > PG_INT32_MIN )
2079
- {
2080
- -- timei32 ;
2081
- ++ timecnt32 ;
2082
- }
2083
- while (leapcnt32 > 0 && !is32 (trans [leapcnt32 - 1 ]))
2086
+ while (0 < leapcnt32 && PG_INT32_MAX < trans [leapcnt32 - 1 ])
2084
2087
-- leapcnt32 ;
2085
- while (leapcnt32 > 0 && ! is32 ( trans [leapi32 ]) )
2088
+ while (0 < leapcnt32 && trans [leapi32 ] < PG_INT32_MIN )
2086
2089
{
2087
2090
-- leapcnt32 ;
2088
2091
++ leapi32 ;
@@ -2315,7 +2318,8 @@ writezone(const char *const name, const char *const string, char version,
2315
2318
if (pass == 1 )
2316
2319
2317
2320
/*
2318
- * Output an INT32_MIN "transition" if appropriate; see above.
2321
+ * Output an PG_INT32_MIN "transition" if appropriate; see
2322
+ * above.
2319
2323
*/
2320
2324
puttzcode (((ats [i ] < PG_INT32_MIN ) ?
2321
2325
PG_INT32_MIN : ats [i ]), fp );
0 commit comments