]> git.pld-linux.org Git - packages/findutils.git/blame - 22_gl_update_mktime.diff
- x32 rebuild
[packages/findutils.git] / 22_gl_update_mktime.diff
CommitLineData
0bbe8578
JR
1Description: Update mktime* from gnulib 20140202+stable-2
2 This fixes a build-error on x32.
3 Diagnosis and solution by Helmut Grohne.
4Author: Andreas Metzler <ametzler@debian.org>
5Origin: vendor
6Bug-Debian: http://bugs.debian.org/753896
7Forwarded: not-needed
8Last-Update: 2014-07-06
9
10--- /dev/null
11+++ findutils-4.4.2/gnulib/lib/mktime-internal.h
12@@ -0,0 +1,4 @@
13+#include <time.h>
14+time_t mktime_internal (struct tm *,
15+ struct tm * (*) (time_t const *, struct tm *),
16+ time_t *);
17--- findutils-4.4.2.orig/gnulib/lib/mktime.c
18+++ findutils-4.4.2/gnulib/lib/mktime.c
19@@ -1,21 +1,21 @@
20-/* Convert a `struct tm' to a time_t value.
21- Copyright (C) 1993-1999, 2002-2005, 2006, 2007 Free Software Foundation, Inc.
22+/* Convert a 'struct tm' to a time_t value.
23+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
24 This file is part of the GNU C Library.
25 Contributed by Paul Eggert <eggert@twinsun.com>.
26
27- This program is free software; you can redistribute it and/or modify
28- it under the terms of the GNU General Public License as published by
29- the Free Software Foundation; either version 3, or (at your option)
30- any later version.
31+ The GNU C Library is free software; you can redistribute it and/or
32+ modify it under the terms of the GNU Lesser General Public
33+ License as published by the Free Software Foundation; either
34+ version 2.1 of the License, or (at your option) any later version.
35
36- This program is distributed in the hope that it will be useful,
37+ The GNU C Library is distributed in the hope that it will be useful,
38 but WITHOUT ANY WARRANTY; without even the implied warranty of
39- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40- GNU General Public License for more details.
41+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
42+ Lesser General Public License for more details.
43
44- You should have received a copy of the GNU General Public License along
45- with this program; if not, write to the Free Software Foundation,
46- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
47+ You should have received a copy of the GNU Lesser General Public
48+ License along with the GNU C Library; if not, see
49+ <http://www.gnu.org/licenses/>. */
50
51 /* Define this to have a standalone program to test this implementation of
52 mktime. */
53@@ -26,7 +26,7 @@
54 #endif
55
56 /* Assume that leap seconds are possible, unless told otherwise.
57- If the host has a `zic' command with a `-L leapsecondfilename' option,
58+ If the host has a 'zic' command with a '-L leapsecondfilename' option,
59 then it supports leap seconds; otherwise it probably doesn't. */
60 #ifndef LEAP_SECONDS_POSSIBLE
61 # define LEAP_SECONDS_POSSIBLE 1
62@@ -42,9 +42,43 @@
63 # include <stdio.h>
64 # include <stdlib.h>
65 /* Make it work even if the system's libc has its own mktime routine. */
66+# undef mktime
67 # define mktime my_mktime
68 #endif /* DEBUG */
69
70+/* Some of the code in this file assumes that signed integer overflow
71+ silently wraps around. This assumption can't easily be programmed
72+ around, nor can it be checked for portably at compile-time or
73+ easily eliminated at run-time.
74+
75+ Define WRAPV to 1 if the assumption is valid and if
76+ #pragma GCC optimize ("wrapv")
77+ does not trigger GCC bug 51793
78+ <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51793>.
79+ Otherwise, define it to 0; this forces the use of slower code that,
80+ while not guaranteed by the C Standard, works on all production
81+ platforms that we know about. */
82+#ifndef WRAPV
83+# if (((__GNUC__ == 4 && 4 <= __GNUC_MINOR__) || 4 < __GNUC__) \
84+ && defined __GLIBC__)
85+# pragma GCC optimize ("wrapv")
86+# define WRAPV 1
87+# else
88+# define WRAPV 0
89+# endif
90+#endif
91+
92+/* Verify a requirement at compile-time (unlike assert, which is runtime). */
93+#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
94+
95+/* A signed type that is at least one bit wider than int. */
96+#if INT_MAX <= LONG_MAX / 2
97+typedef long int long_int;
98+#else
99+typedef long long int long_int;
100+#endif
101+verify (long_int_is_wide_enough, INT_MAX == INT_MAX * (long_int) 2 / 2);
102+
103 /* Shift A right by B bits portably, by dividing A by 2**B and
104 truncating towards minus infinity. A and B should be free of side
105 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
106@@ -55,9 +89,11 @@
107 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
108 right in the usual way when A < 0, so SHR falls back on division if
109 ordinary A >> B doesn't seem to be the usual signed shift. */
110-#define SHR(a, b) \
111- (-1 >> 1 == -1 \
112- ? (a) >> (b) \
113+#define SHR(a, b) \
114+ ((-1 >> 1 == -1 \
115+ && (long_int) -1 >> 1 == -1 \
116+ && ((time_t) -1 >> 1 == -1 || ! TYPE_SIGNED (time_t))) \
117+ ? (a) >> (b) \
118 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
119
120 /* The extra casts in the following macros work around compiler bugs,
121@@ -68,12 +104,8 @@
122 #define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
123
124 /* True if negative values of the signed integer type T use two's
125- complement, ones' complement, or signed magnitude representation,
126- respectively. Much GNU code assumes two's complement, but some
127- people like to be portable to all possible C hosts. */
128+ complement, or if T is an unsigned integer type. */
129 #define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
130-#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0)
131-#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1)
132
133 /* True if the arithmetic type T is signed. */
134 #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
135@@ -85,13 +117,11 @@
136 #define TYPE_MINIMUM(t) \
137 ((t) (! TYPE_SIGNED (t) \
138 ? (t) 0 \
139- : TYPE_SIGNED_MAGNITUDE (t) \
140- ? ~ (t) 0 \
141- : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))
142+ : ~ TYPE_MAXIMUM (t)))
143 #define TYPE_MAXIMUM(t) \
144 ((t) (! TYPE_SIGNED (t) \
145 ? (t) -1 \
146- : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))
147+ : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
148
149 #ifndef TIME_T_MIN
150 # define TIME_T_MIN TYPE_MINIMUM (time_t)
151@@ -101,22 +131,19 @@
152 #endif
153 #define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1)
154
155-/* Verify a requirement at compile-time (unlike assert, which is runtime). */
156-#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
157-
158 verify (time_t_is_integer, TYPE_IS_INTEGER (time_t));
159-verify (twos_complement_arithmetic, TYPE_TWOS_COMPLEMENT (int));
160-/* The code also assumes that signed integer overflow silently wraps
161- around, but this assumption can't be stated without causing a
162- diagnostic on some hosts. */
163+verify (twos_complement_arithmetic,
164+ (TYPE_TWOS_COMPLEMENT (int)
165+ && TYPE_TWOS_COMPLEMENT (long_int)
166+ && TYPE_TWOS_COMPLEMENT (time_t)));
167
168 #define EPOCH_YEAR 1970
169 #define TM_YEAR_BASE 1900
170 verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0);
171
172 /* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */
173-static inline int
174-leapyear (long int year)
175+static int
176+leapyear (long_int year)
177 {
178 /* Don't add YEAR to TM_YEAR_BASE, as that might overflow.
179 Also, work even if YEAR is negative. */
180@@ -147,8 +174,17 @@ const unsigned short int __mon_yday[2][1
181 # undef __localtime_r
182 # define __localtime_r localtime_r
183 # define __mktime_internal mktime_internal
184+# include "mktime-internal.h"
185 #endif
186
187+/* Return 1 if the values A and B differ according to the rules for
188+ tm_isdst: A and B differ if one is zero and the other positive. */
189+static int
190+isdst_differ (int a, int b)
191+{
192+ return (!a != !b) && (0 <= a) && (0 <= b);
193+}
194+
195 /* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) -
196 (YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks
197 were not adjusted between the time stamps.
198@@ -160,13 +196,11 @@ const unsigned short int __mon_yday[2][1
199 The result may overflow. It is the caller's responsibility to
200 detect overflow. */
201
202-static inline time_t
203-ydhms_diff (long int year1, long int yday1, int hour1, int min1, int sec1,
204+static time_t
205+ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1,
206 int year0, int yday0, int hour0, int min0, int sec0)
207 {
208 verify (C99_integer_division, -1 / 2 == 0);
209- verify (long_int_year_and_yday_are_wide_enough,
210- INT_MAX <= LONG_MAX / 2 || TIME_T_MAX <= UINT_MAX);
211
212 /* Compute intervening leap days correctly even if year is negative.
213 Take care to avoid integer overflow here. */
214@@ -189,6 +223,53 @@ ydhms_diff (long int year1, long int yda
215 return seconds;
216 }
217
218+/* Return the average of A and B, even if A + B would overflow. */
219+static time_t
220+time_t_avg (time_t a, time_t b)
221+{
222+ return SHR (a, 1) + SHR (b, 1) + (a & b & 1);
223+}
224+
225+/* Return 1 if A + B does not overflow. If time_t is unsigned and if
226+ B's top bit is set, assume that the sum represents A - -B, and
227+ return 1 if the subtraction does not wrap around. */
228+static int
229+time_t_add_ok (time_t a, time_t b)
230+{
231+ if (! TYPE_SIGNED (time_t))
232+ {
233+ time_t sum = a + b;
234+ return (sum < a) == (TIME_T_MIDPOINT <= b);
235+ }
236+ else if (WRAPV)
237+ {
238+ time_t sum = a + b;
239+ return (sum < a) == (b < 0);
240+ }
241+ else
242+ {
243+ time_t avg = time_t_avg (a, b);
244+ return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2;
245+ }
246+}
247+
248+/* Return 1 if A + B does not overflow. */
249+static int
250+time_t_int_add_ok (time_t a, int b)
251+{
252+ verify (int_no_wider_than_time_t, INT_MAX <= TIME_T_MAX);
253+ if (WRAPV)
254+ {
255+ time_t sum = a + b;
256+ return (sum < a) == (b < 0);
257+ }
258+ else
259+ {
260+ int a_odd = a & 1;
261+ time_t avg = SHR (a, 1) + (SHR (b, 1) + (a_odd & b));
262+ return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2;
263+ }
264+}
265
266 /* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC),
267 assuming that *T corresponds to *TP and that no clock adjustments
268@@ -197,7 +278,7 @@ ydhms_diff (long int year1, long int yda
269 If overflow occurs, yield the minimal or maximal value, except do not
270 yield a value equal to *T. */
271 static time_t
272-guess_time_tm (long int year, long int yday, int hour, int min, int sec,
273+guess_time_tm (long_int year, long_int yday, int hour, int min, int sec,
274 const time_t *t, const struct tm *tp)
275 {
276 if (tp)
277@@ -205,9 +286,8 @@ guess_time_tm (long int year, long int y
278 time_t d = ydhms_diff (year, yday, hour, min, sec,
279 tp->tm_year, tp->tm_yday,
280 tp->tm_hour, tp->tm_min, tp->tm_sec);
281- time_t t1 = *t + d;
282- if ((t1 < *t) == (TYPE_SIGNED (time_t) ? d < 0 : TIME_T_MAX / 2 < d))
283- return t1;
284+ if (time_t_add_ok (*t, d))
285+ return *t + d;
286 }
287
288 /* Overflow occurred one way or another. Return the nearest result
289@@ -239,9 +319,7 @@ ranged_convert (struct tm *(*convert) (c
290 they differ by 1. */
291 while (bad != ok + (bad < 0 ? -1 : 1))
292 {
293- time_t mid = *t = (bad < 0
294- ? bad + ((ok - bad) >> 1)
295- : ok + ((bad - ok) >> 1));
296+ time_t mid = *t = time_t_avg (ok, bad);
297 r = convert (t, tp);
298 if (r)
299 ok = mid;
300@@ -299,8 +377,8 @@ __mktime_internal (struct tm *tp,
301 int mon_remainder = mon % 12;
302 int negative_mon_remainder = mon_remainder < 0;
303 int mon_years = mon / 12 - negative_mon_remainder;
304- long int lyear_requested = year_requested;
305- long int year = lyear_requested + mon_years;
306+ long_int lyear_requested = year_requested;
307+ long_int year = lyear_requested + mon_years;
308
309 /* The other values need not be in range:
310 the remaining code handles minor overflows correctly,
311@@ -312,8 +390,8 @@ __mktime_internal (struct tm *tp,
312 int mon_yday = ((__mon_yday[leapyear (year)]
313 [mon_remainder + 12 * negative_mon_remainder])
314 - 1);
315- long int lmday = mday;
316- long int yday = mon_yday + lmday;
317+ long_int lmday = mday;
318+ long_int yday = mon_yday + lmday;
319
320 time_t guessed_offset = *offset;
321
322@@ -367,9 +445,9 @@ __mktime_internal (struct tm *tp,
323
324 int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM);
325 int diff = approx_biennia - approx_requested_biennia;
326- int abs_diff = diff < 0 ? - diff : diff;
327+ int approx_abs_diff = diff < 0 ? -1 - diff : diff;
328
329- /* IRIX 4.0.5 cc miscaculates TIME_T_MIN / 3: it erroneously
330+ /* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously
331 gives a positive value of 715827882. Setting a variable
332 first then doing math on it seems to work.
333 (ghazi@caip.rutgers.edu) */
334@@ -378,15 +456,15 @@ __mktime_internal (struct tm *tp,
335 time_t overflow_threshold =
336 (time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM;
337
338- if (overflow_threshold < abs_diff)
339+ if (overflow_threshold < approx_abs_diff)
340 {
341 /* Overflow occurred. Try repairing it; this might work if
342 the time zone offset is enough to undo the overflow. */
343 time_t repaired_t0 = -1 - t0;
344 approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
345 diff = approx_biennia - approx_requested_biennia;
346- abs_diff = diff < 0 ? - diff : diff;
347- if (overflow_threshold < abs_diff)
348+ approx_abs_diff = diff < 0 ? -1 - diff : diff;
349+ if (overflow_threshold < approx_abs_diff)
350 return -1;
351 guessed_offset += repaired_t0 - t0;
352 t0 = repaired_t0;
353@@ -420,7 +498,7 @@ __mktime_internal (struct tm *tp,
354
355 /* We have a match. Check whether tm.tm_isdst has the requested
356 value, if any. */
357- if (isdst != tm.tm_isdst && 0 <= isdst && 0 <= tm.tm_isdst)
358+ if (isdst_differ (isdst, tm.tm_isdst))
359 {
360 /* tm.tm_isdst has the wrong value. Look for a neighboring
361 time with the right value, and use its UTC offset.
362@@ -453,22 +531,20 @@ __mktime_internal (struct tm *tp,
363
364 for (delta = stride; delta < delta_bound; delta += stride)
365 for (direction = -1; direction <= 1; direction += 2)
366- {
367- time_t ot = t + delta * direction;
368- if ((ot < t) == (direction < 0))
369- {
370- struct tm otm;
371- ranged_convert (convert, &ot, &otm);
372- if (otm.tm_isdst == isdst)
373- {
374- /* We found the desired tm_isdst.
375- Extrapolate back to the desired time. */
376- t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm);
377- ranged_convert (convert, &t, &tm);
378- goto offset_found;
379- }
380- }
381- }
382+ if (time_t_int_add_ok (t, delta * direction))
383+ {
384+ time_t ot = t + delta * direction;
385+ struct tm otm;
386+ ranged_convert (convert, &ot, &otm);
387+ if (! isdst_differ (isdst, otm.tm_isdst))
388+ {
389+ /* We found the desired tm_isdst.
390+ Extrapolate back to the desired time. */
391+ t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm);
392+ ranged_convert (convert, &t, &tm);
393+ goto offset_found;
394+ }
395+ }
396 }
397
398 offset_found:
399@@ -479,11 +555,13 @@ __mktime_internal (struct tm *tp,
400 /* Adjust time to reflect the tm_sec requested, not the normalized value.
401 Also, repair any damage from a false match due to a leap second. */
402 int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec;
403+ if (! time_t_int_add_ok (t, sec_requested))
404+ return -1;
405 t1 = t + sec_requested;
406+ if (! time_t_int_add_ok (t1, sec_adjustment))
407+ return -1;
408 t2 = t1 + sec_adjustment;
409- if (((t1 < t) != (sec_requested < 0))
410- | ((t2 < t1) != (sec_adjustment < 0))
411- | ! convert (&t2, &tm))
412+ if (! convert (&t2, &tm))
413 return -1;
414 t = t2;
415 }
416@@ -505,7 +583,7 @@ mktime (struct tm *tp)
417 {
418 #ifdef _LIBC
419 /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
420- time zone names contained in the external variable `tzname' shall
421+ time zone names contained in the external variable 'tzname' shall
422 be set as if the tzset() function had been called. */
423 __tzset ();
424 #endif
425@@ -534,7 +612,7 @@ not_equal_tm (const struct tm *a, const
426 | (a->tm_mon ^ b->tm_mon)
427 | (a->tm_year ^ b->tm_year)
428 | (a->tm_yday ^ b->tm_yday)
429- | (a->tm_isdst ^ b->tm_isdst));
430+ | isdst_differ (a->tm_isdst, b->tm_isdst));
431 }
432
433 static void
434@@ -658,6 +736,6 @@ main (int argc, char **argv)
435 \f
436 /*
437 Local Variables:
438-compile-command: "gcc -DDEBUG -Wall -W -O -g mktime.c -o mktime"
439+compile-command: "gcc -DDEBUG -I. -Wall -W -O2 -g mktime.c -o mktime"
440 End:
441 */
This page took 0.069281 seconds and 4 git commands to generate.