emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 2856b1d: Merge from gnulib


From: Paul Eggert
Subject: [Emacs-diffs] master 2856b1d: Merge from gnulib
Date: Mon, 27 Jul 2015 23:51:26 +0000

branch: master
commit 2856b1dd6f0ff5164eb5a54ddfadb9963f9e9237
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    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.
---
 lib/gnulib.mk       |    2 +-
 lib/strftime.c      |   10 +++++-
 lib/time-internal.h |   49 +++++++++++++++++++++++++
 lib/time.in.h       |   12 +++---
 lib/time_rz.c       |   98 ++++++++++++--------------------------------------
 m4/gnulib-comp.m4   |    1 +
 6 files changed, 90 insertions(+), 82 deletions(-)

diff --git a/lib/gnulib.mk b/lib/gnulib.mk
index 1ca12a2..67c7e18 100644
--- a/lib/gnulib.mk
+++ b/lib/gnulib.mk
@@ -1640,7 +1640,7 @@ EXTRA_libgnu_a_SOURCES += time_r.c
 ## begin gnulib module time_rz
 
 
-EXTRA_DIST += time_rz.c
+EXTRA_DIST += time-internal.h time_rz.c
 
 EXTRA_libgnu_a_SOURCES += time_rz.c
 
diff --git a/lib/strftime.c b/lib/strftime.c
index c7cec26..d1ca346 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -30,6 +30,7 @@
 # else
 #  include "strftime.h"
 # endif
+# include "time-internal.h"
 #endif
 
 #include <ctype.h>
@@ -440,6 +441,9 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
 # define am_len STRLEN (a_month)
 # define ap_len STRLEN (ampm)
 #endif
+#if HAVE_TZNAME
+  char **tzname_vec = tzname;
+#endif
   const char *zone;
   size_t i = 0;
   STREAM_OR_CHAR_T *p = s;
@@ -475,6 +479,10 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
     }
   else
     {
+# if !HAVE_TM_ZONE
+      /* Infer the zone name from *TZ instead of from TZNAME.  */
+      tzname_vec = tz->tzname_copy;
+# endif
       /* POSIX.1 requires that local time zone information be used as
          though strftime called tzset.  */
 # if HAVE_TZSET
@@ -483,7 +491,7 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
     }
   /* The tzset() call might have changed the value.  */
   if (!(zone && *zone) && tp->tm_isdst >= 0)
-    zone = tzname[tp->tm_isdst != 0];
+    zone = tzname_vec[tp->tm_isdst != 0];
 #endif
   if (! zone)
     zone = "";
diff --git a/lib/time-internal.h b/lib/time-internal.h
new file mode 100644
index 0000000..6bf3f8d
--- /dev/null
+++ b/lib/time-internal.h
@@ -0,0 +1,49 @@
+/* Time internal interface
+
+   Copyright 2015 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with this program; if not, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by Paul Eggert.  */
+
+/* A time zone rule.  */
+struct tm_zone
+{
+  /* More abbreviations, should they be needed.  Their TZ_IS_SET
+     members are zero.  */
+  struct tm_zone *next;
+
+#if HAVE_TZNAME && !HAVE_TM_ZONE
+  /* Copies of recent strings taken from tzname[0] and tzname[1].
+     The copies are in ABBRS, so that they survive tzset.  Null if unknown.  */
+  char *tzname_copy[2];
+#endif
+
+  /* If nonzero, the rule represents the TZ environment variable set
+     to the first "abbreviation" (this may be the empty string).
+     Otherwise, it represents an unset TZ.  */
+  char tz_is_set;
+
+  /* A sequence of null-terminated strings packed next to each other.
+     The strings are followed by an extra null byte.  If TZ_IS_SET,
+     there must be at least one string and the first string (which is
+     actually a TZ environment value value) may be empty.  Otherwise
+     all strings must be nonempty.
+
+     Abbreviations are stored here because otherwise the values of
+     tm_zone and/or tzname would be dead after changing TZ and calling
+     tzset.  Abbreviations never move once allocated, and are live
+     until tzfree is called.  */
+  char abbrs[FLEXIBLE_ARRAY_MEMBER];
+};
diff --git a/lib/time.in.h b/lib/time.in.h
index 1adfe92..a90552c 100644
--- a/lib/time.in.h
+++ b/lib/time.in.h
@@ -22,13 +22,13 @@
 
 /* Don't get in the way of glibc when it includes time.h merely to
    declare a few standard symbols, rather than to declare all the
-   symbols.  Also, Solaris 8 <time.h> eventually includes itself
+   symbols.  (However, skip this for MinGW as it treats __need_time_t
+   incompatibly.)  Also, Solaris 8 <time.h> eventually includes itself
    recursively; if that is happening, just include the system <time.h>
-   without adding our own declarations.  MinGW system headers use
-   these symbols as well, but we don't want to exclude MinGW from the
-   'else' branch below.  */
-#if (((defined __need_time_t || defined __need_clock_t         \
-       || defined __need_timespec) && !defined __MINGW32__)    \
+   without adding our own declarations.  */
+#if (((defined __need_time_t || defined __need_clock_t \
+       || defined __need_timespec)                     \
+      && !defined __MINGW32__)                         \
      || defined address@hidden@_TIME_H)
 
 # @INCLUDE_NEXT@ @NEXT_TIME_H@
diff --git a/lib/time_rz.c b/lib/time_rz.c
index 8a4d7d1..cbbe2c6 100644
--- a/lib/time_rz.c
+++ b/lib/time_rz.c
@@ -32,35 +32,12 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "time-internal.h"
+
 #if !HAVE_TZSET
 static void tzset (void) { }
 #endif
 
-/* A time zone rule.  */
-struct tm_zone
-{
-  /* More abbreviations, should they be needed.  Their TZ_IS_SET
-     members are zero.  */
-  timezone_t next;
-
-  /* If nonzero, the rule represents the TZ environment variable set
-     to the first "abbreviation" (this may be the empty string).
-     Otherwise, it represents an unset TZ.  */
-  char tz_is_set;
-
-  /* A sequence of null-terminated strings packed next to each other.
-     The strings are followed by an extra null byte.  If TZ_IS_SET,
-     there must be at least one string and the first string (which is
-     actually a TZ environment value value) may be empty.  Otherwise
-     all strings must be nonempty.
-
-     Abbreviations are stored here because otherwise the values of
-     tm_zone and/or tzname would be dead after changing TZ and calling
-     tzset.  Abbreviations never move once allocated, and are live
-     until tzfree is called.  */
-  char abbrs[FLEXIBLE_ARRAY_MEMBER];
-};
-
 /* The approximate size to use for small allocation requests.  This is
    the largest "small" request for the GNU C library malloc.  */
 enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
@@ -124,39 +101,40 @@ tzalloc (char const *name)
   if (tz)
     {
       tz->next = NULL;
+#if HAVE_TZNAME && !HAVE_TM_ZONE
+      tz->tzname_copy[0] = tz->tzname_copy[1] = NULL;
+#endif
       tz->tz_is_set = !!name;
       extend_abbrs (tz->abbrs, name, name_size);
     }
   return tz;
 }
 
-#if HAVE_TZNAME
-/* If TZNAME_ADDRESS is nonnull, an assignment of a saved abbreviation.
-   TZNAME_ADDRESS should be either null, or &tzname[0], or &tzname[1].
-   *TZNAME_ADDRESS = TZNAME_VALUE should be done after revert_tz
-   (indirectly) calls tzset, so that revert_tz can overwrite tzset's
-   assignment to tzname.  Also, it should be done at the start of
-   the next localtime_tz or mktime_z, to undo the overwrite.  */
-static char **tzname_address;
-static char *tzname_value;
-#endif
-
-/* Save into TZ any nontrivial time zone abbreviation used by TM,
-   and update *TM (or prepare to update tzname) if they use the abbreviation.
-   Return true if successful, false (setting errno) otherwise.  */
+/* Save into TZ any nontrivial time zone abbreviation used by TM, and
+   update *TM (if HAVE_TM_ZONE) or *TZ (if !HAVE_TM_ZONE &&
+   HAVE_TZNAME) if they use the abbreviation.  Return true if
+   successful, false (setting errno) otherwise.  */
 static bool
 save_abbr (timezone_t tz, struct tm *tm)
 {
 #if HAVE_TM_ZONE || HAVE_TZNAME
   char const *zone = NULL;
-  char **tzname_zone = NULL;
   char *zone_copy = (char *) "";
+
+# if HAVE_TZNAME
+  int tzname_index = -1;
+# endif
+
 # if HAVE_TM_ZONE
   zone = tm->tm_zone;
 # endif
+
 # if HAVE_TZNAME
   if (! (zone && *zone) && 0 <= tm->tm_isdst)
-    zone = *(tzname_zone = &tzname[0 < tm->tm_isdst]);
+    {
+      tzname_index = tm->tm_isdst != 0;
+      zone = tzname[tzname_index];
+    }
 # endif
 
   /* No need to replace null zones, or zones within the struct tm.  */
@@ -196,14 +174,13 @@ save_abbr (timezone_t tz, struct tm *tm)
 
   /* Replace the zone name so that its lifetime matches that of TZ.  */
 # if HAVE_TM_ZONE
-  if (!tzname_zone)
-    tm->tm_zone = zone_copy;
-# endif
-# if HAVE_TZNAME
-  tzname_address = tzname_zone;
-  tzname_value = zone_copy;
+  tm->tm_zone = zone_copy;
+# else
+  if (0 <= tzname_index)
+    tz->tzname_copy[tzname_index] = zone_copy;
 # endif
 #endif
+
   return true;
 }
 
@@ -292,41 +269,16 @@ revert_tz (timezone_t tz)
       bool ok = change_env (tz);
       if (!ok)
         saved_errno = errno;
-#if HAVE_TZNAME
-      if (!ok)
-        tzname_address = NULL;
-      if (tzname_address)
-        {
-          char *old_value = *tzname_address;
-          *tzname_address = tzname_value;
-          tzname_value = old_value;
-        }
-#endif
       tzfree (tz);
       errno = saved_errno;
       return ok;
     }
 }
 
-/* Restore an old tzname setting that was temporarily munged by revert_tz.  */
-static void
-restore_tzname (void)
-{
-#if HAVE_TZNAME
-  if (tzname_address)
-    {
-      *tzname_address = tzname_value;
-      tzname_address = NULL;
-    }
-#endif
-}
-
 /* Use time zone TZ to compute localtime_r (T, TM).  */
 struct tm *
 localtime_rz (timezone_t tz, time_t const *t, struct tm *tm)
 {
-  restore_tzname ();
-
   if (!tz)
     return gmtime_r (t, tm);
   else
@@ -348,8 +300,6 @@ localtime_rz (timezone_t tz, time_t const *t, struct tm *tm)
 time_t
 mktime_z (timezone_t tz, struct tm *tm)
 {
-  restore_tzname ();
-
   if (!tz)
     return timegm (tm);
   else
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index cf71d7e..c48d2e5 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -959,6 +959,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/sys_types.in.h
   lib/tempname.c
   lib/tempname.h
+  lib/time-internal.h
   lib/time.in.h
   lib/time_r.c
   lib/time_rz.c



reply via email to

[Prev in Thread] Current Thread [Next in Thread]