[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
- [PATCH 1/2] mktime, timegm: simplify merge to glibc,
Paul Eggert <=