version 1.70.2.1, 2018/05/21 04:35:55 |
version 1.70.2.2, 2018/11/26 01:52:12 |
Line 73 typedef int_fast64_t zic_t; |
|
Line 73 typedef int_fast64_t zic_t; |
|
static ptrdiff_t const PTRDIFF_MAX = MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t)); |
static ptrdiff_t const PTRDIFF_MAX = MAXVAL(ptrdiff_t, TYPE_BIT(ptrdiff_t)); |
#endif |
#endif |
|
|
|
/* The minimum alignment of a type, for pre-C11 platforms. */ |
|
#if __STDC_VERSION__ < 201112 |
|
# define _Alignof(type) offsetof(struct { char a; type b; }, b) |
|
#endif |
|
|
/* The type for line numbers. Use PRIdMAX to format them; formerly |
/* The type for line numbers. Use PRIdMAX to format them; formerly |
there was also "#define PRIdLINENO PRIdMAX" and formats used |
there was also "#define PRIdLINENO PRIdMAX" and formats used |
PRIdLINENO, but xgettext cannot grok that. */ |
PRIdLINENO, but xgettext cannot grok that. */ |
Line 199 enum { PERCENT_Z_LEN_BOUND = sizeof "+99 |
|
Line 204 enum { PERCENT_Z_LEN_BOUND = sizeof "+99 |
|
QTBUG-53071 <https://bugreports.qt.io/browse/QTBUG-53071>. This |
QTBUG-53071 <https://bugreports.qt.io/browse/QTBUG-53071>. This |
workaround will no longer be needed when Qt 5.6.1 and earlier are |
workaround will no longer be needed when Qt 5.6.1 and earlier are |
obsolete, say in the year 2021. */ |
obsolete, say in the year 2021. */ |
|
#ifndef WORK_AROUND_QTBUG_53071 |
enum { WORK_AROUND_QTBUG_53071 = 1 }; |
enum { WORK_AROUND_QTBUG_53071 = 1 }; |
|
#endif |
|
|
static int charcnt; |
static int charcnt; |
static bool errors; |
static bool errors; |
Line 441 size_product(size_t nitems, size_t items |
|
Line 448 size_product(size_t nitems, size_t items |
|
return nitems * itemsize; |
return nitems * itemsize; |
} |
} |
|
|
|
static ATTRIBUTE_PURE size_t |
|
align_to(size_t size, size_t alignment) |
|
{ |
|
size_t aligned_size = size + alignment - 1; |
|
aligned_size -= aligned_size % alignment; |
|
if (aligned_size < size) |
|
memory_exhausted(_("alignment overflow")); |
|
return aligned_size; |
|
} |
|
|
#if !HAVE_STRDUP |
#if !HAVE_STRDUP |
static char * |
static char * |
strdup(char const *str) |
strdup(char const *str) |
Line 1761 atcomp(const void *avp, const void *bvp) |
|
Line 1778 atcomp(const void *avp, const void *bvp) |
|
return (a < b) ? -1 : (a > b); |
return (a < b) ? -1 : (a > b); |
} |
} |
|
|
static bool |
|
is32(const zic_t x) |
|
{ |
|
return INT32_MIN <= x && x <= INT32_MAX; |
|
} |
|
|
|
static void |
static void |
writezone(const char *const name, const char *const string, char version) |
writezone(const char *const name, const char *const string, char version) |
{ |
{ |
Line 1781 writezone(const char *const name, const |
|
Line 1792 writezone(const char *const name, const |
|
zic_t one = 1; |
zic_t one = 1; |
zic_t y2038_boundary = one << 31; |
zic_t y2038_boundary = one << 31; |
ptrdiff_t nats = timecnt + WORK_AROUND_QTBUG_53071; |
ptrdiff_t nats = timecnt + WORK_AROUND_QTBUG_53071; |
zic_t *ats = zic_malloc(size_product(nats, sizeof *ats + 1)); |
|
|
/* Allocate the ATS and TYPES arrays via a single malloc, |
|
as this is a bit faster. */ |
|
zic_t *ats = zic_malloc(align_to(size_product(nats, sizeof *ats + 1), |
|
_Alignof(zic_t))); |
void *typesptr = ats + nats; |
void *typesptr = ats + nats; |
unsigned char *types = typesptr; |
unsigned char *types = typesptr; |
|
|
Line 1834 writezone(const char *const name, const |
|
Line 1849 writezone(const char *const name, const |
|
types[i] = attypes[i].type; |
types[i] = attypes[i].type; |
} |
} |
|
|
/* Work around QTBUG-53071 for time stamps less than y2038_boundary - 1, |
|
by inserting a no-op transition at time y2038_boundary - 1. |
|
This works only for timestamps before the boundary, which |
|
should be good enough in practice as QTBUG-53071 should be |
|
long-dead by 2038. */ |
|
if (WORK_AROUND_QTBUG_53071 && timecnt != 0 |
|
&& ats[timecnt - 1] < y2038_boundary - 1 && strchr(string, '<')) { |
|
ats[timecnt] = y2038_boundary - 1; |
|
types[timecnt] = types[timecnt - 1]; |
|
timecnt++; |
|
} |
|
|
|
/* |
/* |
** Correct for leap seconds. |
** Correct for leap seconds. |
*/ |
*/ |
Line 1857 writezone(const char *const name, const |
|
Line 1860 writezone(const char *const name, const |
|
break; |
break; |
} |
} |
} |
} |
|
|
|
/* Work around QTBUG-53071 for timestamps less than y2038_boundary - 1, |
|
by inserting a no-op transition at time y2038_boundary - 1. |
|
This works only for timestamps before the boundary, which |
|
should be good enough in practice as QTBUG-53071 should be |
|
long-dead by 2038. Do this after correcting for leap |
|
seconds, as the idea is to insert a transition just before |
|
32-bit time_t rolls around, and this occurs at a slightly |
|
different moment if transitions are leap-second corrected. */ |
|
if (WORK_AROUND_QTBUG_53071 && timecnt != 0 |
|
&& ats[timecnt - 1] < y2038_boundary - 1 && strchr(string, '<')) { |
|
ats[timecnt] = y2038_boundary - 1; |
|
types[timecnt] = types[timecnt - 1]; |
|
timecnt++; |
|
} |
|
|
/* |
/* |
** Figure out 32-bit-limited starts and counts. |
** Figure out 32-bit-limited starts and counts. |
*/ |
*/ |
Line 1864 writezone(const char *const name, const |
|
Line 1883 writezone(const char *const name, const |
|
timei32 = 0; |
timei32 = 0; |
leapcnt32 = leapcnt; |
leapcnt32 = leapcnt; |
leapi32 = 0; |
leapi32 = 0; |
while (timecnt32 > 0 && !is32(ats[timecnt32 - 1])) |
while (0 < timecnt32 && INT32_MAX < ats[timecnt32 - 1]) |
--timecnt32; |
--timecnt32; |
while (timecnt32 > 0 && !is32(ats[timei32])) { |
while (1 < timecnt32 && ats[timei32] < INT32_MIN |
|
&& ats[timei32 + 1] <= INT32_MIN) { |
|
/* Discard too-low transitions, except keep any last too-low |
|
transition if no transition is exactly at INT32_MIN. |
|
The kept transition will be output as an INT32_MIN |
|
"transition" appropriate for buggy 32-bit clients that do |
|
not use time type 0 for timestamps before the first |
|
transition; see below. */ |
--timecnt32; |
--timecnt32; |
++timei32; |
++timei32; |
} |
} |
/* |
while (0 < leapcnt32 && INT32_MAX < trans[leapcnt32 - 1]) |
** Output an INT32_MIN "transition" if appropriate; see below. |
|
*/ |
|
if (timei32 > 0 && ats[timei32] > INT32_MIN) { |
|
--timei32; |
|
++timecnt32; |
|
} |
|
while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1])) |
|
--leapcnt32; |
--leapcnt32; |
while (leapcnt32 > 0 && !is32(trans[leapi32])) { |
while (0 < leapcnt32 && trans[leapi32] < INT32_MIN) { |
--leapcnt32; |
--leapcnt32; |
++leapi32; |
++leapi32; |
} |
} |