aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert2015-07-27 16:50:44 -0700
committerPaul Eggert2015-07-27 16:51:22 -0700
commit2856b1dd6f0ff5164eb5a54ddfadb9963f9e9237 (patch)
treecff0c4728088e2cfc6939bd4a752c619a54c1cbd /lib
parent094d5e9ef0fac319816c00cc52e0a0f2ef41be37 (diff)
downloademacs-2856b1dd6f0ff5164eb5a54ddfadb9963f9e9237.tar.gz
emacs-2856b1dd6f0ff5164eb5a54ddfadb9963f9e9237.zip
Merge from gnulib
This incorporates: 2015-07-27 time_rz: port better to MinGW 2015-07-27 time: port __need_time_t to MinGW * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * lib/strftime.c, lib/time.in.h, lib/time_rz.c: Copy from gnulib. * lib/time-internal.h: New file, from gnulib.
Diffstat (limited to 'lib')
-rw-r--r--lib/gnulib.mk2
-rw-r--r--lib/strftime.c10
-rw-r--r--lib/time-internal.h49
-rw-r--r--lib/time.in.h12
-rw-r--r--lib/time_rz.c98
5 files changed, 89 insertions, 82 deletions
diff --git a/lib/gnulib.mk b/lib/gnulib.mk
index 1ca12a28beb..67c7e184016 100644
--- a/lib/gnulib.mk
+++ b/lib/gnulib.mk
@@ -1640,7 +1640,7 @@ EXTRA_libgnu_a_SOURCES += time_r.c
1640## begin gnulib module time_rz 1640## begin gnulib module time_rz
1641 1641
1642 1642
1643EXTRA_DIST += time_rz.c 1643EXTRA_DIST += time-internal.h time_rz.c
1644 1644
1645EXTRA_libgnu_a_SOURCES += time_rz.c 1645EXTRA_libgnu_a_SOURCES += time_rz.c
1646 1646
diff --git a/lib/strftime.c b/lib/strftime.c
index c7cec2621c9..d1ca346b687 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -30,6 +30,7 @@
30# else 30# else
31# include "strftime.h" 31# include "strftime.h"
32# endif 32# endif
33# include "time-internal.h"
33#endif 34#endif
34 35
35#include <ctype.h> 36#include <ctype.h>
@@ -440,6 +441,9 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
440# define am_len STRLEN (a_month) 441# define am_len STRLEN (a_month)
441# define ap_len STRLEN (ampm) 442# define ap_len STRLEN (ampm)
442#endif 443#endif
444#if HAVE_TZNAME
445 char **tzname_vec = tzname;
446#endif
443 const char *zone; 447 const char *zone;
444 size_t i = 0; 448 size_t i = 0;
445 STREAM_OR_CHAR_T *p = s; 449 STREAM_OR_CHAR_T *p = s;
@@ -475,6 +479,10 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
475 } 479 }
476 else 480 else
477 { 481 {
482# if !HAVE_TM_ZONE
483 /* Infer the zone name from *TZ instead of from TZNAME. */
484 tzname_vec = tz->tzname_copy;
485# endif
478 /* POSIX.1 requires that local time zone information be used as 486 /* POSIX.1 requires that local time zone information be used as
479 though strftime called tzset. */ 487 though strftime called tzset. */
480# if HAVE_TZSET 488# if HAVE_TZSET
@@ -483,7 +491,7 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
483 } 491 }
484 /* The tzset() call might have changed the value. */ 492 /* The tzset() call might have changed the value. */
485 if (!(zone && *zone) && tp->tm_isdst >= 0) 493 if (!(zone && *zone) && tp->tm_isdst >= 0)
486 zone = tzname[tp->tm_isdst != 0]; 494 zone = tzname_vec[tp->tm_isdst != 0];
487#endif 495#endif
488 if (! zone) 496 if (! zone)
489 zone = ""; 497 zone = "";
diff --git a/lib/time-internal.h b/lib/time-internal.h
new file mode 100644
index 00000000000..6bf3f8d30b7
--- /dev/null
+++ b/lib/time-internal.h
@@ -0,0 +1,49 @@
1/* Time internal interface
2
3 Copyright 2015 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, see <http://www.gnu.org/licenses/>. */
17
18/* Written by Paul Eggert. */
19
20/* A time zone rule. */
21struct tm_zone
22{
23 /* More abbreviations, should they be needed. Their TZ_IS_SET
24 members are zero. */
25 struct tm_zone *next;
26
27#if HAVE_TZNAME && !HAVE_TM_ZONE
28 /* Copies of recent strings taken from tzname[0] and tzname[1].
29 The copies are in ABBRS, so that they survive tzset. Null if unknown. */
30 char *tzname_copy[2];
31#endif
32
33 /* If nonzero, the rule represents the TZ environment variable set
34 to the first "abbreviation" (this may be the empty string).
35 Otherwise, it represents an unset TZ. */
36 char tz_is_set;
37
38 /* A sequence of null-terminated strings packed next to each other.
39 The strings are followed by an extra null byte. If TZ_IS_SET,
40 there must be at least one string and the first string (which is
41 actually a TZ environment value value) may be empty. Otherwise
42 all strings must be nonempty.
43
44 Abbreviations are stored here because otherwise the values of
45 tm_zone and/or tzname would be dead after changing TZ and calling
46 tzset. Abbreviations never move once allocated, and are live
47 until tzfree is called. */
48 char abbrs[FLEXIBLE_ARRAY_MEMBER];
49};
diff --git a/lib/time.in.h b/lib/time.in.h
index 1adfe925398..a90552ce447 100644
--- a/lib/time.in.h
+++ b/lib/time.in.h
@@ -22,13 +22,13 @@
22 22
23/* Don't get in the way of glibc when it includes time.h merely to 23/* Don't get in the way of glibc when it includes time.h merely to
24 declare a few standard symbols, rather than to declare all the 24 declare a few standard symbols, rather than to declare all the
25 symbols. Also, Solaris 8 <time.h> eventually includes itself 25 symbols. (However, skip this for MinGW as it treats __need_time_t
26 incompatibly.) Also, Solaris 8 <time.h> eventually includes itself
26 recursively; if that is happening, just include the system <time.h> 27 recursively; if that is happening, just include the system <time.h>
27 without adding our own declarations. MinGW system headers use 28 without adding our own declarations. */
28 these symbols as well, but we don't want to exclude MinGW from the 29#if (((defined __need_time_t || defined __need_clock_t \
29 'else' branch below. */ 30 || defined __need_timespec) \
30#if (((defined __need_time_t || defined __need_clock_t \ 31 && !defined __MINGW32__) \
31 || defined __need_timespec) && !defined __MINGW32__) \
32 || defined _@GUARD_PREFIX@_TIME_H) 32 || defined _@GUARD_PREFIX@_TIME_H)
33 33
34# @INCLUDE_NEXT@ @NEXT_TIME_H@ 34# @INCLUDE_NEXT@ @NEXT_TIME_H@
diff --git a/lib/time_rz.c b/lib/time_rz.c
index 8a4d7d13a2c..cbbe2c6ac2f 100644
--- a/lib/time_rz.c
+++ b/lib/time_rz.c
@@ -32,35 +32,12 @@
32#include <stdlib.h> 32#include <stdlib.h>
33#include <string.h> 33#include <string.h>
34 34
35#include "time-internal.h"
36
35#if !HAVE_TZSET 37#if !HAVE_TZSET
36static void tzset (void) { } 38static void tzset (void) { }
37#endif 39#endif
38 40
39/* A time zone rule. */
40struct tm_zone
41{
42 /* More abbreviations, should they be needed. Their TZ_IS_SET
43 members are zero. */
44 timezone_t next;
45
46 /* If nonzero, the rule represents the TZ environment variable set
47 to the first "abbreviation" (this may be the empty string).
48 Otherwise, it represents an unset TZ. */
49 char tz_is_set;
50
51 /* A sequence of null-terminated strings packed next to each other.
52 The strings are followed by an extra null byte. If TZ_IS_SET,
53 there must be at least one string and the first string (which is
54 actually a TZ environment value value) may be empty. Otherwise
55 all strings must be nonempty.
56
57 Abbreviations are stored here because otherwise the values of
58 tm_zone and/or tzname would be dead after changing TZ and calling
59 tzset. Abbreviations never move once allocated, and are live
60 until tzfree is called. */
61 char abbrs[FLEXIBLE_ARRAY_MEMBER];
62};
63
64/* The approximate size to use for small allocation requests. This is 41/* The approximate size to use for small allocation requests. This is
65 the largest "small" request for the GNU C library malloc. */ 42 the largest "small" request for the GNU C library malloc. */
66enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 }; 43enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
@@ -124,39 +101,40 @@ tzalloc (char const *name)
124 if (tz) 101 if (tz)
125 { 102 {
126 tz->next = NULL; 103 tz->next = NULL;
104#if HAVE_TZNAME && !HAVE_TM_ZONE
105 tz->tzname_copy[0] = tz->tzname_copy[1] = NULL;
106#endif
127 tz->tz_is_set = !!name; 107 tz->tz_is_set = !!name;
128 extend_abbrs (tz->abbrs, name, name_size); 108 extend_abbrs (tz->abbrs, name, name_size);
129 } 109 }
130 return tz; 110 return tz;
131} 111}
132 112
133#if HAVE_TZNAME 113/* Save into TZ any nontrivial time zone abbreviation used by TM, and
134/* If TZNAME_ADDRESS is nonnull, an assignment of a saved abbreviation. 114 update *TM (if HAVE_TM_ZONE) or *TZ (if !HAVE_TM_ZONE &&
135 TZNAME_ADDRESS should be either null, or &tzname[0], or &tzname[1]. 115 HAVE_TZNAME) if they use the abbreviation. Return true if
136 *TZNAME_ADDRESS = TZNAME_VALUE should be done after revert_tz 116 successful, false (setting errno) otherwise. */
137 (indirectly) calls tzset, so that revert_tz can overwrite tzset's
138 assignment to tzname. Also, it should be done at the start of
139 the next localtime_tz or mktime_z, to undo the overwrite. */
140static char **tzname_address;
141static char *tzname_value;
142#endif
143
144/* Save into TZ any nontrivial time zone abbreviation used by TM,
145 and update *TM (or prepare to update tzname) if they use the abbreviation.
146 Return true if successful, false (setting errno) otherwise. */
147static bool 117static bool
148save_abbr (timezone_t tz, struct tm *tm) 118save_abbr (timezone_t tz, struct tm *tm)
149{ 119{
150#if HAVE_TM_ZONE || HAVE_TZNAME 120#if HAVE_TM_ZONE || HAVE_TZNAME
151 char const *zone = NULL; 121 char const *zone = NULL;
152 char **tzname_zone = NULL;
153 char *zone_copy = (char *) ""; 122 char *zone_copy = (char *) "";
123
124# if HAVE_TZNAME
125 int tzname_index = -1;
126# endif
127
154# if HAVE_TM_ZONE 128# if HAVE_TM_ZONE
155 zone = tm->tm_zone; 129 zone = tm->tm_zone;
156# endif 130# endif
131
157# if HAVE_TZNAME 132# if HAVE_TZNAME
158 if (! (zone && *zone) && 0 <= tm->tm_isdst) 133 if (! (zone && *zone) && 0 <= tm->tm_isdst)
159 zone = *(tzname_zone = &tzname[0 < tm->tm_isdst]); 134 {
135 tzname_index = tm->tm_isdst != 0;
136 zone = tzname[tzname_index];
137 }
160# endif 138# endif
161 139
162 /* No need to replace null zones, or zones within the struct tm. */ 140 /* No need to replace null zones, or zones within the struct tm. */
@@ -196,14 +174,13 @@ save_abbr (timezone_t tz, struct tm *tm)
196 174
197 /* Replace the zone name so that its lifetime matches that of TZ. */ 175 /* Replace the zone name so that its lifetime matches that of TZ. */
198# if HAVE_TM_ZONE 176# if HAVE_TM_ZONE
199 if (!tzname_zone) 177 tm->tm_zone = zone_copy;
200 tm->tm_zone = zone_copy; 178# else
201# endif 179 if (0 <= tzname_index)
202# if HAVE_TZNAME 180 tz->tzname_copy[tzname_index] = zone_copy;
203 tzname_address = tzname_zone;
204 tzname_value = zone_copy;
205# endif 181# endif
206#endif 182#endif
183
207 return true; 184 return true;
208} 185}
209 186
@@ -292,41 +269,16 @@ revert_tz (timezone_t tz)
292 bool ok = change_env (tz); 269 bool ok = change_env (tz);
293 if (!ok) 270 if (!ok)
294 saved_errno = errno; 271 saved_errno = errno;
295#if HAVE_TZNAME
296 if (!ok)
297 tzname_address = NULL;
298 if (tzname_address)
299 {
300 char *old_value = *tzname_address;
301 *tzname_address = tzname_value;
302 tzname_value = old_value;
303 }
304#endif
305 tzfree (tz); 272 tzfree (tz);
306 errno = saved_errno; 273 errno = saved_errno;
307 return ok; 274 return ok;
308 } 275 }
309} 276}
310 277
311/* Restore an old tzname setting that was temporarily munged by revert_tz. */
312static void
313restore_tzname (void)
314{
315#if HAVE_TZNAME
316 if (tzname_address)
317 {
318 *tzname_address = tzname_value;
319 tzname_address = NULL;
320 }
321#endif
322}
323
324/* Use time zone TZ to compute localtime_r (T, TM). */ 278/* Use time zone TZ to compute localtime_r (T, TM). */
325struct tm * 279struct tm *
326localtime_rz (timezone_t tz, time_t const *t, struct tm *tm) 280localtime_rz (timezone_t tz, time_t const *t, struct tm *tm)
327{ 281{
328 restore_tzname ();
329
330 if (!tz) 282 if (!tz)
331 return gmtime_r (t, tm); 283 return gmtime_r (t, tm);
332 else 284 else
@@ -348,8 +300,6 @@ localtime_rz (timezone_t tz, time_t const *t, struct tm *tm)
348time_t 300time_t
349mktime_z (timezone_t tz, struct tm *tm) 301mktime_z (timezone_t tz, struct tm *tm)
350{ 302{
351 restore_tzname ();
352
353 if (!tz) 303 if (!tz)
354 return timegm (tm); 304 return timegm (tm);
355 else 305 else