diff options
| author | Paul Eggert | 2011-01-30 11:22:51 -0800 |
|---|---|---|
| committer | Paul Eggert | 2011-01-30 11:22:51 -0800 |
| commit | fcabb1a6e66f7e6cf4fe0984c4d5c169f4decd8a (patch) | |
| tree | 4926d2f913499164126038fc65515eff32521172 | |
| parent | 253f7d1bc55aec58986aa36f8a6e4725d311ed24 (diff) | |
| parent | 3de84ad9c45382c181e3383d433442f4e19ba722 (diff) | |
| download | emacs-fcabb1a6e66f7e6cf4fe0984c4d5c169f4decd8a.tar.gz emacs-fcabb1a6e66f7e6cf4fe0984c4d5c169f4decd8a.zip | |
Merge: import mktime and move-if-change fixes from gnulib
| -rw-r--r-- | ChangeLog | 99 | ||||
| -rwxr-xr-x | configure | 19 | ||||
| -rw-r--r-- | lib/intprops.h | 4 | ||||
| -rw-r--r-- | lib/mktime.c | 198 | ||||
| -rw-r--r-- | m4/mktime.m4 | 21 | ||||
| -rwxr-xr-x | move-if-change | 16 |
6 files changed, 268 insertions, 89 deletions
| @@ -1,3 +1,102 @@ | |||
| 1 | 2011-01-30 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | gnulib: import mktime and move-if-change fixes from gnulib | ||
| 4 | |||
| 5 | * configure: Regenerate from the following. | ||
| 6 | |||
| 7 | 2011-01-30 Paul Eggert <eggert@cs.ucla.edu> | ||
| 8 | |||
| 9 | mktime: clarify long_int width checking | ||
| 10 | * lib/mktime.c (long_int_is_wide_enough): Move this assertion to | ||
| 11 | the top level, to make it clearer that the assumption about | ||
| 12 | long_int width is being checked. See | ||
| 13 | <http://lists.gnu.org/archive/html/bug-gnulib/2011-01/msg00554.html>. | ||
| 14 | |||
| 15 | 2011-01-29 Paul Eggert <eggert@cs.ucla.edu> | ||
| 16 | |||
| 17 | TYPE_MAXIMUM: avoid theoretically undefined behavior | ||
| 18 | * lib/intprops.h (TYPE_MINIMUM, TYPE_MAXIMUM): Do not shift a | ||
| 19 | negative number, which the C Standard says has undefined behavior. | ||
| 20 | In practice this is not a problem, but might as well do it by the book. | ||
| 21 | Reported by Rich Felker and Eric Blake; see | ||
| 22 | <http://lists.gnu.org/archive/html/bug-gnulib/2011-01/msg00493.html>. | ||
| 23 | * m4/mktime.m4 (AC_FUNC_MKTIME): Likewise. | ||
| 24 | * lib/mktime.c (TYPE_MAXIMUM): Redo slightly to match the others. | ||
| 25 | |||
| 26 | mktime: #undef mktime before #defining it | ||
| 27 | * lib/mktime.c (mktime) [DEBUG]: #undef mktime before #defining it. | ||
| 28 | |||
| 29 | mktime: systematically normalize tm_isdst comparisons | ||
| 30 | * lib/mktime.c (isdst_differ): New function. | ||
| 31 | (__mktime_internal): Use it systematically for all isdst comparisons. | ||
| 32 | This completes the fix for libc BZ #6723, and removes the need for | ||
| 33 | normalizing tm_isdst. See | ||
| 34 | <http://sourceware.org/bugzilla/show_bug.cgi?id=6723> | ||
| 35 | (not_equal_tm) [DEBUG]: Use isdst_differ here, too. | ||
| 36 | |||
| 37 | mktime: fix some integer overflow issues and sidestep the rest | ||
| 38 | |||
| 39 | This was prompted by a bug report by Benjamin Lindner for MinGW | ||
| 40 | <http://lists.gnu.org/archive/html/bug-gnulib/2011-01/msg00472.html>. | ||
| 41 | His bug is due to signed integer overflow (0 - INT_MIN), and I | ||
| 42 | I scanned through mktime.c looking for other integer overflow | ||
| 43 | problems, fixing all the bugs I found. | ||
| 44 | |||
| 45 | Although the C Standard says the resulting code is still not safe | ||
| 46 | in the presence of integer overflow, in practice it should be good | ||
| 47 | enough for all real-world two's-complement implementations, except | ||
| 48 | for debugging environments that deliberately trap on integer | ||
| 49 | overflow (e.g., gcc -ftrapv). | ||
| 50 | |||
| 51 | * lib/mktime.c (WRAPV): New macro. | ||
| 52 | (SHR): Also check that long_int and time_t shift right in the | ||
| 53 | usual way, before using the fast-but-unportable method. | ||
| 54 | (TYPE_ONES_COMPLEMENT, TYPE_SIGNED_MAGNITUDE): Remove, no longer | ||
| 55 | used. The code already assumed two's complement, so there's | ||
| 56 | no need to test for alternatives. All uses removed. | ||
| 57 | (TYPE_MAXIMUM): Don't rely here on overflow behavior not defined by | ||
| 58 | the C standard. Problem reported by Rich Felker in | ||
| 59 | <http://lists.gnu.org/archive/html/bug-gnulib/2011-01/msg00488.html>. | ||
| 60 | (twos_complement_arithmetic): Also check long_int and time_t. | ||
| 61 | (time_t_avg, time_t_add_ok, time_t_int_add_ok): New functions. | ||
| 62 | (guess_time_tm, ranged_convert, __mktime_internal): Use them. | ||
| 63 | (__mktime_internal): Avoid integer overflow with unary subtraction | ||
| 64 | in two instances where -1 - X is an adequate replacement for -X, | ||
| 65 | since the calculations are approximate. | ||
| 66 | |||
| 67 | 2011-01-29 Eric Blake <eblake@redhat.com> | ||
| 68 | |||
| 69 | mktime: avoid infinite loop | ||
| 70 | * m4/mktime.m4 (AC_FUNC_MKTIME): Avoid overflow on possibly-signed | ||
| 71 | type; behavior is still undefined but portable to all known targets. | ||
| 72 | Reported by Rich Felker. | ||
| 73 | |||
| 74 | 2011-01-28 Paul Eggert <eggert@cs.ucla.edu> | ||
| 75 | |||
| 76 | mktime: avoid problems on NetBSD 5 / i386 | ||
| 77 | * lib/mktime.c (long_int): New type. This works around a problem | ||
| 78 | on NetBSD 5 / i386, where 'long int' and 'int' are both 32 bits | ||
| 79 | but time_t is 64 bits, and where I expect the existing code is | ||
| 80 | wrong in some cases. | ||
| 81 | (leapyear, ydhms_diff, guess_time_tm, __mktime_internal): Use it. | ||
| 82 | (ydhms_diff): Bring back the compile-time check for wide-enough | ||
| 83 | year and yday. | ||
| 84 | |||
| 85 | mktime: fix misspelling in comment | ||
| 86 | * lib/mktime.c (__mktime_internal): Fix misspelling in comment. | ||
| 87 | This merges all recent glibc changes of importance. | ||
| 88 | |||
| 89 | 2011-01-28 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> | ||
| 90 | |||
| 91 | move-if-change: cope with concurrent mv of identical file. | ||
| 92 | * move-if-change (CMPPROG): Accept environment | ||
| 93 | variable as an override for `cmp'. | ||
| 94 | (usage): Document CMPPROG. | ||
| 95 | Adjust comparison to drop stdout. Cope with failure of mv if | ||
| 96 | the target file exists and is identical to the source, for | ||
| 97 | parallel builds. | ||
| 98 | Report from H.J. Lu against binutils in PR binutils/12283. | ||
| 99 | |||
| 1 | 2011-01-29 Eli Zaretskii <eliz@gnu.org> | 100 | 2011-01-29 Eli Zaretskii <eliz@gnu.org> |
| 2 | 101 | ||
| 3 | * lib/makefile.w32-in: | 102 | * lib/makefile.w32-in: |
| @@ -14906,20 +14906,23 @@ main () | |||
| 14906 | int result = 0; | 14906 | int result = 0; |
| 14907 | time_t t, delta; | 14907 | time_t t, delta; |
| 14908 | int i, j; | 14908 | int i, j; |
| 14909 | int time_t_signed_magnitude = (time_t) ~ (time_t) 0 < (time_t) -1; | ||
| 14910 | int time_t_signed = ! ((time_t) 0 < (time_t) -1); | ||
| 14909 | 14911 | ||
| 14910 | /* This test makes some buggy mktime implementations loop. | 14912 | /* This test makes some buggy mktime implementations loop. |
| 14911 | Give up after 60 seconds; a mktime slower than that | 14913 | Give up after 60 seconds; a mktime slower than that |
| 14912 | isn't worth using anyway. */ | 14914 | isn't worth using anyway. */ |
| 14913 | alarm (60); | 14915 | alarm (60); |
| 14914 | 14916 | ||
| 14915 | for (;;) | 14917 | time_t_max = (! time_t_signed |
| 14916 | { | 14918 | ? (time_t) -1 |
| 14917 | t = (time_t_max << 1) + 1; | 14919 | : ((((time_t) 1 << (sizeof (time_t) * CHAR_BIT - 2)) - 1) |
| 14918 | if (t <= time_t_max) | 14920 | * 2 + 1)); |
| 14919 | break; | 14921 | time_t_min = (! time_t_signed |
| 14920 | time_t_max = t; | 14922 | ? (time_t) 0 |
| 14921 | } | 14923 | : time_t_signed_magnitude |
| 14922 | time_t_min = - ((time_t) ~ (time_t) 0 == (time_t) -1) - time_t_max; | 14924 | ? ~ (time_t) 0 |
| 14925 | : ~ time_t_max); | ||
| 14923 | 14926 | ||
| 14924 | delta = time_t_max / 997; /* a suitable prime number */ | 14927 | delta = time_t_max / 997; /* a suitable prime number */ |
| 14925 | for (i = 0; i < N_STRINGS; i++) | 14928 | for (i = 0; i < N_STRINGS; i++) |
diff --git a/lib/intprops.h b/lib/intprops.h index 511a5aa9890..58b1b3fbf44 100644 --- a/lib/intprops.h +++ b/lib/intprops.h | |||
| @@ -49,11 +49,11 @@ | |||
| 49 | ? (t) 0 \ | 49 | ? (t) 0 \ |
| 50 | : TYPE_SIGNED_MAGNITUDE (t) \ | 50 | : TYPE_SIGNED_MAGNITUDE (t) \ |
| 51 | ? ~ (t) 0 \ | 51 | ? ~ (t) 0 \ |
| 52 | : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))) | 52 | : ~ TYPE_MAXIMUM (t))) |
| 53 | # define TYPE_MAXIMUM(t) \ | 53 | # define TYPE_MAXIMUM(t) \ |
| 54 | ((t) (! TYPE_SIGNED (t) \ | 54 | ((t) (! TYPE_SIGNED (t) \ |
| 55 | ? (t) -1 \ | 55 | ? (t) -1 \ |
| 56 | : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))) | 56 | : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) |
| 57 | 57 | ||
| 58 | /* Return zero if T can be determined to be an unsigned type. | 58 | /* Return zero if T can be determined to be an unsigned type. |
| 59 | Otherwise, return 1. | 59 | Otherwise, return 1. |
diff --git a/lib/mktime.c b/lib/mktime.c index f77330564fc..c68ad9ba262 100644 --- a/lib/mktime.c +++ b/lib/mktime.c | |||
| @@ -25,6 +25,24 @@ | |||
| 25 | # include <config.h> | 25 | # include <config.h> |
| 26 | #endif | 26 | #endif |
| 27 | 27 | ||
| 28 | /* Some of the code in this file assumes that signed integer overflow | ||
| 29 | silently wraps around. This assumption can't easily be programmed | ||
| 30 | around, nor can it be checked for portably at compile-time or | ||
| 31 | easily eliminated at run-time. | ||
| 32 | |||
| 33 | Define WRAPV to 1 if the assumption is valid. Otherwise, define it | ||
| 34 | to 0; this forces the use of slower code that, while not guaranteed | ||
| 35 | by the C Standard, works on all production platforms that we know | ||
| 36 | about. */ | ||
| 37 | #ifndef WRAPV | ||
| 38 | # if (__GNUC__ == 4 && 4 <= __GNUC_MINOR__) || 4 < __GNUC__ | ||
| 39 | # pragma GCC optimize ("wrapv") | ||
| 40 | # define WRAPV 1 | ||
| 41 | # else | ||
| 42 | # define WRAPV 0 | ||
| 43 | # endif | ||
| 44 | #endif | ||
| 45 | |||
| 28 | /* Assume that leap seconds are possible, unless told otherwise. | 46 | /* Assume that leap seconds are possible, unless told otherwise. |
| 29 | If the host has a `zic' command with a `-L leapsecondfilename' option, | 47 | If the host has a `zic' command with a `-L leapsecondfilename' option, |
| 30 | then it supports leap seconds; otherwise it probably doesn't. */ | 48 | then it supports leap seconds; otherwise it probably doesn't. */ |
| @@ -42,9 +60,21 @@ | |||
| 42 | # include <stdio.h> | 60 | # include <stdio.h> |
| 43 | # include <stdlib.h> | 61 | # include <stdlib.h> |
| 44 | /* Make it work even if the system's libc has its own mktime routine. */ | 62 | /* Make it work even if the system's libc has its own mktime routine. */ |
| 63 | # undef mktime | ||
| 45 | # define mktime my_mktime | 64 | # define mktime my_mktime |
| 46 | #endif /* DEBUG */ | 65 | #endif /* DEBUG */ |
| 47 | 66 | ||
| 67 | /* Verify a requirement at compile-time (unlike assert, which is runtime). */ | ||
| 68 | #define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; } | ||
| 69 | |||
| 70 | /* A signed type that is at least one bit wider than int. */ | ||
| 71 | #if INT_MAX <= LONG_MAX / 2 | ||
| 72 | typedef long int long_int; | ||
| 73 | #else | ||
| 74 | typedef long long int long_int; | ||
| 75 | #endif | ||
| 76 | verify (long_int_is_wide_enough, INT_MAX == INT_MAX * (long_int) 2 / 2); | ||
| 77 | |||
| 48 | /* Shift A right by B bits portably, by dividing A by 2**B and | 78 | /* Shift A right by B bits portably, by dividing A by 2**B and |
| 49 | truncating towards minus infinity. A and B should be free of side | 79 | truncating towards minus infinity. A and B should be free of side |
| 50 | effects, and B should be in the range 0 <= B <= INT_BITS - 2, where | 80 | effects, and B should be in the range 0 <= B <= INT_BITS - 2, where |
| @@ -55,9 +85,11 @@ | |||
| 55 | implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift | 85 | implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift |
| 56 | right in the usual way when A < 0, so SHR falls back on division if | 86 | right in the usual way when A < 0, so SHR falls back on division if |
| 57 | ordinary A >> B doesn't seem to be the usual signed shift. */ | 87 | ordinary A >> B doesn't seem to be the usual signed shift. */ |
| 58 | #define SHR(a, b) \ | 88 | #define SHR(a, b) \ |
| 59 | (-1 >> 1 == -1 \ | 89 | ((-1 >> 1 == -1 \ |
| 60 | ? (a) >> (b) \ | 90 | && (long_int) -1 >> 1 == -1 \ |
| 91 | && ((time_t) -1 >> 1 == -1 || ! TYPE_SIGNED (time_t))) \ | ||
| 92 | ? (a) >> (b) \ | ||
| 61 | : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0)) | 93 | : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0)) |
| 62 | 94 | ||
| 63 | /* The extra casts in the following macros work around compiler bugs, | 95 | /* The extra casts in the following macros work around compiler bugs, |
| @@ -68,12 +100,8 @@ | |||
| 68 | #define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) | 100 | #define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) |
| 69 | 101 | ||
| 70 | /* True if negative values of the signed integer type T use two's | 102 | /* True if negative values of the signed integer type T use two's |
| 71 | complement, ones' complement, or signed magnitude representation, | 103 | complement, or if T is an unsigned integer type. */ |
| 72 | respectively. Much GNU code assumes two's complement, but some | ||
| 73 | people like to be portable to all possible C hosts. */ | ||
| 74 | #define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) | 104 | #define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) |
| 75 | #define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0) | ||
| 76 | #define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1) | ||
| 77 | 105 | ||
| 78 | /* True if the arithmetic type T is signed. */ | 106 | /* True if the arithmetic type T is signed. */ |
| 79 | #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) | 107 | #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) |
| @@ -85,13 +113,11 @@ | |||
| 85 | #define TYPE_MINIMUM(t) \ | 113 | #define TYPE_MINIMUM(t) \ |
| 86 | ((t) (! TYPE_SIGNED (t) \ | 114 | ((t) (! TYPE_SIGNED (t) \ |
| 87 | ? (t) 0 \ | 115 | ? (t) 0 \ |
| 88 | : TYPE_SIGNED_MAGNITUDE (t) \ | 116 | : ~ TYPE_MAXIMUM (t))) |
| 89 | ? ~ (t) 0 \ | ||
| 90 | : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))) | ||
| 91 | #define TYPE_MAXIMUM(t) \ | 117 | #define TYPE_MAXIMUM(t) \ |
| 92 | ((t) (! TYPE_SIGNED (t) \ | 118 | ((t) (! TYPE_SIGNED (t) \ |
| 93 | ? (t) -1 \ | 119 | ? (t) -1 \ |
| 94 | : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))) | 120 | : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) |
| 95 | 121 | ||
| 96 | #ifndef TIME_T_MIN | 122 | #ifndef TIME_T_MIN |
| 97 | # define TIME_T_MIN TYPE_MINIMUM (time_t) | 123 | # define TIME_T_MIN TYPE_MINIMUM (time_t) |
| @@ -101,14 +127,11 @@ | |||
| 101 | #endif | 127 | #endif |
| 102 | #define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1) | 128 | #define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1) |
| 103 | 129 | ||
| 104 | /* Verify a requirement at compile-time (unlike assert, which is runtime). */ | ||
| 105 | #define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; } | ||
| 106 | |||
| 107 | verify (time_t_is_integer, TYPE_IS_INTEGER (time_t)); | 130 | verify (time_t_is_integer, TYPE_IS_INTEGER (time_t)); |
| 108 | verify (twos_complement_arithmetic, TYPE_TWOS_COMPLEMENT (int)); | 131 | verify (twos_complement_arithmetic, |
| 109 | /* The code also assumes that signed integer overflow silently wraps | 132 | (TYPE_TWOS_COMPLEMENT (int) |
| 110 | around, but this assumption can't be stated without causing a | 133 | && TYPE_TWOS_COMPLEMENT (long_int) |
| 111 | diagnostic on some hosts. */ | 134 | && TYPE_TWOS_COMPLEMENT (time_t))); |
| 112 | 135 | ||
| 113 | #define EPOCH_YEAR 1970 | 136 | #define EPOCH_YEAR 1970 |
| 114 | #define TM_YEAR_BASE 1900 | 137 | #define TM_YEAR_BASE 1900 |
| @@ -116,7 +139,7 @@ verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0); | |||
| 116 | 139 | ||
| 117 | /* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */ | 140 | /* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */ |
| 118 | static inline int | 141 | static inline int |
| 119 | leapyear (long int year) | 142 | leapyear (long_int year) |
| 120 | { | 143 | { |
| 121 | /* Don't add YEAR to TM_YEAR_BASE, as that might overflow. | 144 | /* Don't add YEAR to TM_YEAR_BASE, as that might overflow. |
| 122 | Also, work even if YEAR is negative. */ | 145 | Also, work even if YEAR is negative. */ |
| @@ -150,6 +173,14 @@ const unsigned short int __mon_yday[2][13] = | |||
| 150 | # include "mktime-internal.h" | 173 | # include "mktime-internal.h" |
| 151 | #endif | 174 | #endif |
| 152 | 175 | ||
| 176 | /* Return 1 if the values A and B differ according to the rules for | ||
| 177 | tm_isdst: A and B differ if one is zero and the other positive. */ | ||
| 178 | static int | ||
| 179 | isdst_differ (int a, int b) | ||
| 180 | { | ||
| 181 | return (!a != !b) & (0 <= a) & (0 <= b); | ||
| 182 | } | ||
| 183 | |||
| 153 | /* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) - | 184 | /* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) - |
| 154 | (YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks | 185 | (YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks |
| 155 | were not adjusted between the time stamps. | 186 | were not adjusted between the time stamps. |
| @@ -162,15 +193,10 @@ const unsigned short int __mon_yday[2][13] = | |||
| 162 | detect overflow. */ | 193 | detect overflow. */ |
| 163 | 194 | ||
| 164 | static inline time_t | 195 | static inline time_t |
| 165 | ydhms_diff (long int year1, long int yday1, int hour1, int min1, int sec1, | 196 | ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1, |
| 166 | int year0, int yday0, int hour0, int min0, int sec0) | 197 | int year0, int yday0, int hour0, int min0, int sec0) |
| 167 | { | 198 | { |
| 168 | verify (C99_integer_division, -1 / 2 == 0); | 199 | verify (C99_integer_division, -1 / 2 == 0); |
| 169 | #if 0 /* This assertion fails on 32-bit systems with 64-bit time_t, such as | ||
| 170 | NetBSD 5 on i386. */ | ||
| 171 | verify (long_int_year_and_yday_are_wide_enough, | ||
| 172 | INT_MAX <= LONG_MAX / 2 || TIME_T_MAX <= UINT_MAX); | ||
| 173 | #endif | ||
| 174 | 200 | ||
| 175 | /* Compute intervening leap days correctly even if year is negative. | 201 | /* Compute intervening leap days correctly even if year is negative. |
| 176 | Take care to avoid integer overflow here. */ | 202 | Take care to avoid integer overflow here. */ |
| @@ -193,6 +219,53 @@ ydhms_diff (long int year1, long int yday1, int hour1, int min1, int sec1, | |||
| 193 | return seconds; | 219 | return seconds; |
| 194 | } | 220 | } |
| 195 | 221 | ||
| 222 | /* Return the average of A and B, even if A + B would overflow. */ | ||
| 223 | static time_t | ||
| 224 | time_t_avg (time_t a, time_t b) | ||
| 225 | { | ||
| 226 | return SHR (a, 1) + SHR (b, 1) + (a & b & 1); | ||
| 227 | } | ||
| 228 | |||
| 229 | /* Return 1 if A + B does not overflow. If time_t is unsigned and if | ||
| 230 | B's top bit is set, assume that the sum represents A - -B, and | ||
| 231 | return 1 if the subtraction does not wrap around. */ | ||
| 232 | static int | ||
| 233 | time_t_add_ok (time_t a, time_t b) | ||
| 234 | { | ||
| 235 | if (! TYPE_SIGNED (time_t)) | ||
| 236 | { | ||
| 237 | time_t sum = a + b; | ||
| 238 | return (sum < a) == (TIME_T_MIDPOINT <= b); | ||
| 239 | } | ||
| 240 | else if (WRAPV) | ||
| 241 | { | ||
| 242 | time_t sum = a + b; | ||
| 243 | return (sum < a) == (b < 0); | ||
| 244 | } | ||
| 245 | else | ||
| 246 | { | ||
| 247 | time_t avg = time_t_avg (a, b); | ||
| 248 | return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2; | ||
| 249 | } | ||
| 250 | } | ||
| 251 | |||
| 252 | /* Return 1 if A + B does not overflow. */ | ||
| 253 | static int | ||
| 254 | time_t_int_add_ok (time_t a, int b) | ||
| 255 | { | ||
| 256 | verify (int_no_wider_than_time_t, INT_MAX <= TIME_T_MAX); | ||
| 257 | if (WRAPV) | ||
| 258 | { | ||
| 259 | time_t sum = a + b; | ||
| 260 | return (sum < a) == (b < 0); | ||
| 261 | } | ||
| 262 | else | ||
| 263 | { | ||
| 264 | int a_odd = a & 1; | ||
| 265 | time_t avg = SHR (a, 1) + (SHR (b, 1) + (a_odd & b)); | ||
| 266 | return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2; | ||
| 267 | } | ||
| 268 | } | ||
| 196 | 269 | ||
| 197 | /* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC), | 270 | /* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC), |
| 198 | assuming that *T corresponds to *TP and that no clock adjustments | 271 | assuming that *T corresponds to *TP and that no clock adjustments |
| @@ -201,7 +274,7 @@ ydhms_diff (long int year1, long int yday1, int hour1, int min1, int sec1, | |||
| 201 | If overflow occurs, yield the minimal or maximal value, except do not | 274 | If overflow occurs, yield the minimal or maximal value, except do not |
| 202 | yield a value equal to *T. */ | 275 | yield a value equal to *T. */ |
| 203 | static time_t | 276 | static time_t |
| 204 | guess_time_tm (long int year, long int yday, int hour, int min, int sec, | 277 | guess_time_tm (long_int year, long_int yday, int hour, int min, int sec, |
| 205 | const time_t *t, const struct tm *tp) | 278 | const time_t *t, const struct tm *tp) |
| 206 | { | 279 | { |
| 207 | if (tp) | 280 | if (tp) |
| @@ -209,9 +282,8 @@ guess_time_tm (long int year, long int yday, int hour, int min, int sec, | |||
| 209 | time_t d = ydhms_diff (year, yday, hour, min, sec, | 282 | time_t d = ydhms_diff (year, yday, hour, min, sec, |
| 210 | tp->tm_year, tp->tm_yday, | 283 | tp->tm_year, tp->tm_yday, |
| 211 | tp->tm_hour, tp->tm_min, tp->tm_sec); | 284 | tp->tm_hour, tp->tm_min, tp->tm_sec); |
| 212 | time_t t1 = *t + d; | 285 | if (time_t_add_ok (*t, d)) |
| 213 | if ((t1 < *t) == (TYPE_SIGNED (time_t) ? d < 0 : TIME_T_MAX / 2 < d)) | 286 | return *t + d; |
| 214 | return t1; | ||
| 215 | } | 287 | } |
| 216 | 288 | ||
| 217 | /* Overflow occurred one way or another. Return the nearest result | 289 | /* Overflow occurred one way or another. Return the nearest result |
| @@ -243,9 +315,7 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *), | |||
| 243 | they differ by 1. */ | 315 | they differ by 1. */ |
| 244 | while (bad != ok + (bad < 0 ? -1 : 1)) | 316 | while (bad != ok + (bad < 0 ? -1 : 1)) |
| 245 | { | 317 | { |
| 246 | time_t mid = *t = (bad < 0 | 318 | time_t mid = *t = time_t_avg (ok, bad); |
| 247 | ? bad + ((ok - bad) >> 1) | ||
| 248 | : ok + ((bad - ok) >> 1)); | ||
| 249 | r = convert (t, tp); | 319 | r = convert (t, tp); |
| 250 | if (r) | 320 | if (r) |
| 251 | ok = mid; | 321 | ok = mid; |
| @@ -294,9 +364,7 @@ __mktime_internal (struct tm *tp, | |||
| 294 | int mday = tp->tm_mday; | 364 | int mday = tp->tm_mday; |
| 295 | int mon = tp->tm_mon; | 365 | int mon = tp->tm_mon; |
| 296 | int year_requested = tp->tm_year; | 366 | int year_requested = tp->tm_year; |
| 297 | /* Normalize the value. */ | 367 | int isdst = tp->tm_isdst; |
| 298 | int isdst = ((tp->tm_isdst >> (8 * sizeof (tp->tm_isdst) - 1)) | ||
| 299 | | (tp->tm_isdst != 0)); | ||
| 300 | 368 | ||
| 301 | /* 1 if the previous probe was DST. */ | 369 | /* 1 if the previous probe was DST. */ |
| 302 | int dst2; | 370 | int dst2; |
| @@ -305,8 +373,8 @@ __mktime_internal (struct tm *tp, | |||
| 305 | int mon_remainder = mon % 12; | 373 | int mon_remainder = mon % 12; |
| 306 | int negative_mon_remainder = mon_remainder < 0; | 374 | int negative_mon_remainder = mon_remainder < 0; |
| 307 | int mon_years = mon / 12 - negative_mon_remainder; | 375 | int mon_years = mon / 12 - negative_mon_remainder; |
| 308 | long int lyear_requested = year_requested; | 376 | long_int lyear_requested = year_requested; |
| 309 | long int year = lyear_requested + mon_years; | 377 | long_int year = lyear_requested + mon_years; |
| 310 | 378 | ||
| 311 | /* The other values need not be in range: | 379 | /* The other values need not be in range: |
| 312 | the remaining code handles minor overflows correctly, | 380 | the remaining code handles minor overflows correctly, |
| @@ -318,8 +386,8 @@ __mktime_internal (struct tm *tp, | |||
| 318 | int mon_yday = ((__mon_yday[leapyear (year)] | 386 | int mon_yday = ((__mon_yday[leapyear (year)] |
| 319 | [mon_remainder + 12 * negative_mon_remainder]) | 387 | [mon_remainder + 12 * negative_mon_remainder]) |
| 320 | - 1); | 388 | - 1); |
| 321 | long int lmday = mday; | 389 | long_int lmday = mday; |
| 322 | long int yday = mon_yday + lmday; | 390 | long_int yday = mon_yday + lmday; |
| 323 | 391 | ||
| 324 | time_t guessed_offset = *offset; | 392 | time_t guessed_offset = *offset; |
| 325 | 393 | ||
| @@ -373,9 +441,9 @@ __mktime_internal (struct tm *tp, | |||
| 373 | 441 | ||
| 374 | int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM); | 442 | int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM); |
| 375 | int diff = approx_biennia - approx_requested_biennia; | 443 | int diff = approx_biennia - approx_requested_biennia; |
| 376 | int abs_diff = diff < 0 ? - diff : diff; | 444 | int abs_diff = diff < 0 ? -1 - diff : diff; |
| 377 | 445 | ||
| 378 | /* IRIX 4.0.5 cc miscaculates TIME_T_MIN / 3: it erroneously | 446 | /* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously |
| 379 | gives a positive value of 715827882. Setting a variable | 447 | gives a positive value of 715827882. Setting a variable |
| 380 | first then doing math on it seems to work. | 448 | first then doing math on it seems to work. |
| 381 | (ghazi@caip.rutgers.edu) */ | 449 | (ghazi@caip.rutgers.edu) */ |
| @@ -391,7 +459,7 @@ __mktime_internal (struct tm *tp, | |||
| 391 | time_t repaired_t0 = -1 - t0; | 459 | time_t repaired_t0 = -1 - t0; |
| 392 | approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM); | 460 | approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM); |
| 393 | diff = approx_biennia - approx_requested_biennia; | 461 | diff = approx_biennia - approx_requested_biennia; |
| 394 | abs_diff = diff < 0 ? - diff : diff; | 462 | abs_diff = diff < 0 ? -1 - diff : diff; |
| 395 | if (overflow_threshold < abs_diff) | 463 | if (overflow_threshold < abs_diff) |
| 396 | return -1; | 464 | return -1; |
| 397 | guessed_offset += repaired_t0 - t0; | 465 | guessed_offset += repaired_t0 - t0; |
| @@ -426,7 +494,7 @@ __mktime_internal (struct tm *tp, | |||
| 426 | 494 | ||
| 427 | /* We have a match. Check whether tm.tm_isdst has the requested | 495 | /* We have a match. Check whether tm.tm_isdst has the requested |
| 428 | value, if any. */ | 496 | value, if any. */ |
| 429 | if (isdst != tm.tm_isdst && 0 <= isdst && 0 <= tm.tm_isdst) | 497 | if (isdst_differ (isdst, tm.tm_isdst)) |
| 430 | { | 498 | { |
| 431 | /* tm.tm_isdst has the wrong value. Look for a neighboring | 499 | /* tm.tm_isdst has the wrong value. Look for a neighboring |
| 432 | time with the right value, and use its UTC offset. | 500 | time with the right value, and use its UTC offset. |
| @@ -459,22 +527,20 @@ __mktime_internal (struct tm *tp, | |||
| 459 | 527 | ||
| 460 | for (delta = stride; delta < delta_bound; delta += stride) | 528 | for (delta = stride; delta < delta_bound; delta += stride) |
| 461 | for (direction = -1; direction <= 1; direction += 2) | 529 | for (direction = -1; direction <= 1; direction += 2) |
| 462 | { | 530 | if (time_t_int_add_ok (t, delta * direction)) |
| 463 | time_t ot = t + delta * direction; | 531 | { |
| 464 | if ((ot < t) == (direction < 0)) | 532 | time_t ot = t + delta * direction; |
| 465 | { | 533 | struct tm otm; |
| 466 | struct tm otm; | 534 | ranged_convert (convert, &ot, &otm); |
| 467 | ranged_convert (convert, &ot, &otm); | 535 | if (! isdst_differ (isdst, otm.tm_isdst)) |
| 468 | if (otm.tm_isdst == isdst) | 536 | { |
| 469 | { | 537 | /* We found the desired tm_isdst. |
| 470 | /* We found the desired tm_isdst. | 538 | Extrapolate back to the desired time. */ |
| 471 | Extrapolate back to the desired time. */ | 539 | t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm); |
| 472 | t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm); | 540 | ranged_convert (convert, &t, &tm); |
| 473 | ranged_convert (convert, &t, &tm); | 541 | goto offset_found; |
| 474 | goto offset_found; | 542 | } |
| 475 | } | 543 | } |
| 476 | } | ||
| 477 | } | ||
| 478 | } | 544 | } |
| 479 | 545 | ||
| 480 | offset_found: | 546 | offset_found: |
| @@ -485,11 +551,13 @@ __mktime_internal (struct tm *tp, | |||
| 485 | /* Adjust time to reflect the tm_sec requested, not the normalized value. | 551 | /* Adjust time to reflect the tm_sec requested, not the normalized value. |
| 486 | Also, repair any damage from a false match due to a leap second. */ | 552 | Also, repair any damage from a false match due to a leap second. */ |
| 487 | int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec; | 553 | int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec; |
| 554 | if (! time_t_int_add_ok (t, sec_requested)) | ||
| 555 | return -1; | ||
| 488 | t1 = t + sec_requested; | 556 | t1 = t + sec_requested; |
| 557 | if (! time_t_int_add_ok (t1, sec_adjustment)) | ||
| 558 | return -1; | ||
| 489 | t2 = t1 + sec_adjustment; | 559 | t2 = t1 + sec_adjustment; |
| 490 | if (((t1 < t) != (sec_requested < 0)) | 560 | if (! convert (&t2, &tm)) |
| 491 | | ((t2 < t1) != (sec_adjustment < 0)) | ||
| 492 | | ! convert (&t2, &tm)) | ||
| 493 | return -1; | 561 | return -1; |
| 494 | t = t2; | 562 | t = t2; |
| 495 | } | 563 | } |
| @@ -540,7 +608,7 @@ not_equal_tm (const struct tm *a, const struct tm *b) | |||
| 540 | | (a->tm_mon ^ b->tm_mon) | 608 | | (a->tm_mon ^ b->tm_mon) |
| 541 | | (a->tm_year ^ b->tm_year) | 609 | | (a->tm_year ^ b->tm_year) |
| 542 | | (a->tm_yday ^ b->tm_yday) | 610 | | (a->tm_yday ^ b->tm_yday) |
| 543 | | (a->tm_isdst ^ b->tm_isdst)); | 611 | | isdst_differ (a->tm_isdst, b->tm_isdst)); |
| 544 | } | 612 | } |
| 545 | 613 | ||
| 546 | static void | 614 | static void |
| @@ -664,6 +732,6 @@ main (int argc, char **argv) | |||
| 664 | 732 | ||
| 665 | /* | 733 | /* |
| 666 | Local Variables: | 734 | Local Variables: |
| 667 | compile-command: "gcc -DDEBUG -Wall -W -O -g mktime.c -o mktime" | 735 | compile-command: "gcc -DDEBUG -I. -Wall -W -O2 -g mktime.c -o mktime" |
| 668 | End: | 736 | End: |
| 669 | */ | 737 | */ |
diff --git a/m4/mktime.m4 b/m4/mktime.m4 index f2b131ba456..56b2416d619 100644 --- a/m4/mktime.m4 +++ b/m4/mktime.m4 | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | # serial 17 | 1 | # serial 19 |
| 2 | dnl Copyright (C) 2002-2003, 2005-2007, 2009-2011 Free Software Foundation, | 2 | dnl Copyright (C) 2002-2003, 2005-2007, 2009-2011 Free Software Foundation, |
| 3 | dnl Inc. | 3 | dnl Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| @@ -165,20 +165,23 @@ main () | |||
| 165 | int result = 0; | 165 | int result = 0; |
| 166 | time_t t, delta; | 166 | time_t t, delta; |
| 167 | int i, j; | 167 | int i, j; |
| 168 | int time_t_signed_magnitude = (time_t) ~ (time_t) 0 < (time_t) -1; | ||
| 169 | int time_t_signed = ! ((time_t) 0 < (time_t) -1); | ||
| 168 | 170 | ||
| 169 | /* This test makes some buggy mktime implementations loop. | 171 | /* This test makes some buggy mktime implementations loop. |
| 170 | Give up after 60 seconds; a mktime slower than that | 172 | Give up after 60 seconds; a mktime slower than that |
| 171 | isn't worth using anyway. */ | 173 | isn't worth using anyway. */ |
| 172 | alarm (60); | 174 | alarm (60); |
| 173 | 175 | ||
| 174 | for (;;) | 176 | time_t_max = (! time_t_signed |
| 175 | { | 177 | ? (time_t) -1 |
| 176 | t = (time_t_max << 1) + 1; | 178 | : ((((time_t) 1 << (sizeof (time_t) * CHAR_BIT - 2)) - 1) |
| 177 | if (t <= time_t_max) | 179 | * 2 + 1)); |
| 178 | break; | 180 | time_t_min = (! time_t_signed |
| 179 | time_t_max = t; | 181 | ? (time_t) 0 |
| 180 | } | 182 | : time_t_signed_magnitude |
| 181 | time_t_min = - ((time_t) ~ (time_t) 0 == (time_t) -1) - time_t_max; | 183 | ? ~ (time_t) 0 |
| 184 | : ~ time_t_max); | ||
| 182 | 185 | ||
| 183 | delta = time_t_max / 997; /* a suitable prime number */ | 186 | delta = time_t_max / 997; /* a suitable prime number */ |
| 184 | for (i = 0; i < N_STRINGS; i++) | 187 | for (i = 0; i < N_STRINGS; i++) |
diff --git a/move-if-change b/move-if-change index a891ca51f0c..e7ba25e3127 100755 --- a/move-if-change +++ b/move-if-change | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # Like mv $1 $2, but if the files are the same, just delete $1. | 2 | # Like mv $1 $2, but if the files are the same, just delete $1. |
| 3 | # Status is zero if successful, nonzero otherwise. | 3 | # Status is zero if successful, nonzero otherwise. |
| 4 | 4 | ||
| 5 | VERSION='2007-09-28 23:10'; # UTC | 5 | VERSION='2011-01-28 20:09'; # UTC |
| 6 | # The definition above must lie within the first 8 lines in order | 6 | # The definition above must lie within the first 8 lines in order |
| 7 | # for the Emacs time-stamp write hook (at end) to update it. | 7 | # for the Emacs time-stamp write hook (at end) to update it. |
| 8 | # If you change this file with Emacs, please let the write hook | 8 | # If you change this file with Emacs, please let the write hook |
| @@ -32,15 +32,18 @@ If SOURCE is different than DEST, then move it to DEST; else remove SOURCE. | |||
| 32 | --help display this help and exit | 32 | --help display this help and exit |
| 33 | --version output version information and exit | 33 | --version output version information and exit |
| 34 | 34 | ||
| 35 | The variable CMPPROG can be used to specify an alternative to \`cmp'. | ||
| 36 | |||
| 35 | Report bugs to <bug-gnulib@gnu.org>." | 37 | Report bugs to <bug-gnulib@gnu.org>." |
| 36 | 38 | ||
| 37 | version=`expr "$VERSION" : '\([^ ]*\)'` | 39 | version=`expr "$VERSION" : '\([^ ]*\)'` |
| 38 | version="move-if-change (gnulib) $version | 40 | version="move-if-change (gnulib) $version |
| 39 | Copyright (C) 2007 Free Software Foundation, Inc. | 41 | Copyright (C) 2011 Free Software Foundation, Inc. |
| 40 | License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> | 42 | License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> |
| 41 | This is free software: you are free to change and redistribute it. | 43 | This is free software: you are free to change and redistribute it. |
| 42 | There is NO WARRANTY, to the extent permitted by law." | 44 | There is NO WARRANTY, to the extent permitted by law." |
| 43 | 45 | ||
| 46 | cmpprog=${CMPPROG-cmp} | ||
| 44 | 47 | ||
| 45 | for arg | 48 | for arg |
| 46 | do | 49 | do |
| @@ -60,12 +63,15 @@ do | |||
| 60 | esac | 63 | esac |
| 61 | done | 64 | done |
| 62 | 65 | ||
| 63 | test $# = 2 || { echo "$0: $usage" >&2; exit 1; } | 66 | test $# -eq 2 || { echo "$0: $usage" >&2; exit 1; } |
| 64 | 67 | ||
| 65 | if test -r "$2" && cmp -s -- "$1" "$2"; then | 68 | if test -r "$2" && $cmpprog -- "$1" "$2" >/dev/null; then |
| 66 | rm -f -- "$1" | 69 | rm -f -- "$1" |
| 67 | else | 70 | else |
| 68 | mv -f -- "$1" "$2" | 71 | if mv -f -- "$1" "$2"; then :; else |
| 72 | # Ignore failure due to a concurrent move-if-change. | ||
| 73 | test -r "$2" && $cmpprog -- "$1" "$2" >/dev/null && rm -f -- "$1" | ||
| 74 | fi | ||
| 69 | fi | 75 | fi |
| 70 | 76 | ||
| 71 | ## Local Variables: | 77 | ## Local Variables: |