bug-gnulib
[Top][All Lists]
Advanced

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

[PATCH 1/2] mktime, timegm: simplify merge to glibc


From: Paul Eggert
Subject: [PATCH 1/2] mktime, timegm: simplify merge to glibc
Date: Sat, 1 Sep 2018 00:23:23 -0700

Move code around to make a merge to glibc easier to audit.
This should not change behavior.
* lib/mktime.c: Include more standard files unconditionally.
(NEED_MKTIME_INTERNAL, NEED_MKTIME_WINDOWS)
(NEED_MKTIME_WORKING): Give default values to pacify -Wundef,
which glibc uses.  Default NEED_MKTIME_WORKING to DEBUG_MKTIME, to
simplify later conditionals; default the others to zero.  In uses
of these conditionals, explicitly spell out how _LIBC affects
things, so it’s easier to review from a glibc viewpoint.
(my_tzset, __tzset) [!_LIBC]: New function and macro, to better
compartmentalize tzset issues.  Move system-dependent tzsettish
code here from mktime.
(mktime): Move tzsettish code to my_tzset, and move
localtime_offset to within mktime so that it doesn’t
need a separate ifdef.
* lib/mktime-internal.h (__gmtime_r, __localtime_r, __mktime_internal):
Move these macros here from lib/mktime.c and lib/gmtime.c.
---
 ChangeLog             |  18 +++++++
 lib/mktime-internal.h |  16 ++++++
 lib/mktime.c          | 123 +++++++++++++++++++++---------------------
 lib/timegm.c          |  26 +++++----
 4 files changed, 109 insertions(+), 74 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 91967e12b..3f9cf9624 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2018-08-31  Paul Eggert  <address@hidden>
+
+       mktime, timegm: simplify merge to glibc
+       Move code around to make a merge to glibc easier to audit.
+       This should not change behavior.
+       * lib/mktime.c (NEED_MKTIME_INTERNAL, NEED_MKTIME_WINDOWS)
+       (NEED_MKTIME_WORKING): Give default values to pacify -Wundef,
+       which glibc uses.  Default NEED_MKTIME_WORKING to DEBUG_MKTIME, to
+       simplify later conditionals; default the others to zero.  In uses
+       of these conditionals, explicitly spell out how _LIBC affects
+       things, so it’s easier to review from a glibc viewpoint.
+       (my_tzset, __tzset) [!_LIBC]: New function and macro, to better
+       compartmentalize tzset issues.  Move system-dependent tzsettish
+       code here from mktime.
+       (mktime): Move tzsettish code to my_tzset, and move
+       localtime_offset to within mktime so that it doesn’t
+       need a separate ifdef.
+
 2018-08-27  Paul Eggert  <address@hidden>
 
        intprops: avoid evaluation of some expressions
diff --git a/lib/mktime-internal.h b/lib/mktime-internal.h
index f531b5591..3e64156e8 100644
--- a/lib/mktime-internal.h
+++ b/lib/mktime-internal.h
@@ -35,3 +35,19 @@ typedef int mktime_offset_t;
 time_t mktime_internal (struct tm *,
                         struct tm * (*) (time_t const *, struct tm *),
                         mktime_offset_t *);
+
+/* Although glibc source code uses leading underscores, Gnulib wants
+   ordinary names.
+
+   Portable standalone applications should supply a <time.h> that
+   declares a POSIX-compliant localtime_r, for the benefit of older
+   implementations that lack localtime_r or have a nonstandard one.
+   Similarly for gmtime_r.  See the gnulib time_r module for one way
+   to implement this.  */
+
+#undef __gmtime_r
+#undef __localtime_r
+#define __gmtime_r gmtime_r
+#define __localtime_r localtime_r
+
+#define __mktime_internal mktime_internal
diff --git a/lib/mktime.c b/lib/mktime.c
index 6c3679a67..285876479 100644
--- a/lib/mktime.c
+++ b/lib/mktime.c
@@ -28,6 +28,8 @@
    Macro/expression            Which gnulib module    This compilation unit
                                                       should define
 
+   _LIBC                       (glibc proper)         mktime
+
    NEED_MKTIME_WORKING         mktime                 rpl_mktime
    || NEED_MKTIME_WINDOWS
 
@@ -51,25 +53,74 @@
 
 #include <limits.h>
 #include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include <intprops.h>
 #include <verify.h>
 
 #if DEBUG_MKTIME
 # include <stdio.h>
-# include <stdlib.h>
-# include <string.h>
 /* Make it work even if the system's libc has its own mktime routine.  */
 # undef mktime
 # define mktime my_mktime
+#endif /* DEBUG_MKTIME */
+
+#ifndef NEED_MKTIME_INTERNAL
+# define NEED_MKTIME_INTERNAL 0
+#endif
+#ifndef NEED_MKTIME_WINDOWS
+# define NEED_MKTIME_WINDOWS 0
+#endif
+#ifndef NEED_MKTIME_WORKING
+# define NEED_MKTIME_WORKING DEBUG_MKTIME
+#endif
+
+#ifdef _LIBC
+typedef time_t mktime_offset_t;
+#else
+# include "mktime-internal.h"
 #endif
 
-#if NEED_MKTIME_WINDOWS /* on native Windows */
-# include <stdlib.h>
-# include <string.h>
+#ifndef _LIBC
+static void
+my_tzset (void)
+{
+# if NEED_MKTIME_WINDOWS
+  /* Rectify the value of the environment variable TZ.
+     There are four possible kinds of such values:
+       - Traditional US time zone names, e.g. "PST8PDT".  Syntax: see
+         <https://msdn.microsoft.com/en-us/library/90s5c885.aspx>
+       - Time zone names based on geography, that contain one or more
+         slashes, e.g. "Europe/Moscow".
+       - Time zone names based on geography, without slashes, e.g.
+         "Singapore".
+       - Time zone names that contain explicit DST rules.  Syntax: see
+         
<http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03>
+     The Microsoft CRT understands only the first kind.  It produces incorrect
+     results if the value of TZ is of the other kinds.
+     But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value
+     of the second kind for most geographies, or of the first kind in a few
+     other geographies.  If it is of the second kind, neutralize it.  For the
+     Microsoft CRT, an absent or empty TZ means the time zone that the user
+     has set in the Windows Control Panel.
+     If the value of TZ is of the third or fourth kind -- Cygwin programs
+     understand these syntaxes as well --, it does not matter whether we
+     neutralize it or not, since these values occur only when a Cygwin user
+     has set TZ explicitly; this case is 1. rare and 2. under the user's
+     responsibility.  */
+  const char *tz = getenv ("TZ");
+  if (tz != NULL && strchr (tz, '/') != NULL)
+    _putenv ("TZ=");
+# elif HAVE_TZSET
+  tzset ();
+# endif
+}
+# undef __tzset
+# define __tzset() my_tzset ()
 #endif
 
-#if NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL || DEBUG_MKTIME
+#if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL
 
 /* A signed type that can represent an integer number of years
    multiplied by three times the number of seconds in a year.  It is
@@ -150,19 +201,6 @@ const unsigned short int __mon_yday[2][13] =
   };
 
 
-#ifdef _LIBC
-typedef time_t mktime_offset_t;
-#else
-/* Portable standalone applications should supply a <time.h> that
-   declares a POSIX-compliant localtime_r, for the benefit of older
-   implementations that lack localtime_r or have a nonstandard one.
-   See the gnulib time_r module for one way to implement this.  */
-# undef __localtime_r
-# define __localtime_r localtime_r
-# define __mktime_internal mktime_internal
-# include "mktime-internal.h"
-#endif
-
 /* Do the values A and B differ according to the rules for tm_isdst?
    A and B differ if one is zero and the other positive.  */
 static bool
@@ -304,6 +342,7 @@ ranged_convert (struct tm *(*convert) (const time_t *, 
struct tm *),
   return r;
 }
 
+
 /* Convert *TP to a time_t value, inverting
    the monotonic and mostly-unit-linear conversion function CONVERT.
    Use *OFFSET to keep track of a guess at the offset of the result,
@@ -478,64 +517,28 @@ __mktime_internal (struct tm *tp,
   return t;
 }
 
-#endif /* NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL || DEBUG_MKTIME */
+#endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL */
 
-#if NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS || DEBUG_MKTIME
-
-# if NEED_MKTIME_WORKING || DEBUG_MKTIME
-static mktime_offset_t localtime_offset;
-# endif
+#if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS
 
 /* Convert *TP to a time_t value.  */
 time_t
 mktime (struct tm *tp)
 {
-# if NEED_MKTIME_WINDOWS
-  /* Rectify the value of the environment variable TZ.
-     There are four possible kinds of such values:
-       - Traditional US time zone names, e.g. "PST8PDT".  Syntax: see
-         <https://msdn.microsoft.com/en-us/library/90s5c885.aspx>
-       - Time zone names based on geography, that contain one or more
-         slashes, e.g. "Europe/Moscow".
-       - Time zone names based on geography, without slashes, e.g.
-         "Singapore".
-       - Time zone names that contain explicit DST rules.  Syntax: see
-         
<http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03>
-     The Microsoft CRT understands only the first kind.  It produces incorrect
-     results if the value of TZ is of the other kinds.
-     But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value
-     of the second kind for most geographies, or of the first kind in a few
-     other geographies.  If it is of the second kind, neutralize it.  For the
-     Microsoft CRT, an absent or empty TZ means the time zone that the user
-     has set in the Windows Control Panel.
-     If the value of TZ is of the third or fourth kind -- Cygwin programs
-     understand these syntaxes as well --, it does not matter whether we
-     neutralize it or not, since these values occur only when a Cygwin user
-     has set TZ explicitly; this case is 1. rare and 2. under the user's
-     responsibility.  */
-  const char *tz = getenv ("TZ");
-  if (tz != NULL && strchr (tz, '/') != NULL)
-    _putenv ("TZ=");
-# endif
-
-# if NEED_MKTIME_WORKING || DEBUG_MKTIME
-#  ifdef _LIBC
   /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
      time zone names contained in the external variable 'tzname' shall
      be set as if the tzset() function had been called.  */
   __tzset ();
-#  elif HAVE_TZSET
-  tzset ();
-#  endif
 
+# if defined __LIBC || NEED_MKTIME_WORKING
+  static mktime_offset_t localtime_offset;
   return __mktime_internal (tp, __localtime_r, &localtime_offset);
 # else
 #  undef mktime
   return mktime (tp);
 # endif
 }
-
-#endif /* NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS || DEBUG_MKTIME */
+#endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */
 
 #ifdef weak_alias
 weak_alias (mktime, timelocal)
diff --git a/lib/timegm.c b/lib/timegm.c
index 8cf56af1b..275a7a2ec 100644
--- a/lib/timegm.c
+++ b/lib/timegm.c
@@ -1,20 +1,21 @@
 /* Convert UTC calendar time to simple time.  Like mktime but assumes UTC.
 
-   Copyright (C) 1994, 1997, 2003-2004, 2006-2007, 2009-2018 Free Software
-   Foundation, Inc.  This file is part of the GNU C Library.
+   Copyright (C) 1994-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
 
-   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 2, or (at your option)
-   any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   The GNU C Library 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.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser 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 <https://www.gnu.org/licenses/>.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 #ifndef _LIBC
 # include <config.h>
@@ -25,9 +26,6 @@
 #ifdef _LIBC
 typedef time_t mktime_offset_t;
 #else
-# undef __gmtime_r
-# define __gmtime_r gmtime_r
-# define __mktime_internal mktime_internal
 # include "mktime-internal.h"
 #endif
 
-- 
2.17.1




reply via email to

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