# HG changeset patch # User Paul Eggert # Date 1535763768 25200 # Node ID 9971c7f37ee6e022e08370fbfdb5048981544271 # Parent 74cf04d92ad5a1b623781d81ed7e538b1bcad2c5 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: 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. diff -r 74cf04d92ad5 -r 9971c7f37ee6 ChangeLog --- a/ChangeLog Thu Aug 30 06:27:53 2018 -0700 +++ b/ChangeLog Fri Aug 31 18:02:48 2018 -0700 @@ -1,3 +1,21 @@ +2018-08-31 Paul Eggert + + 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 intprops: avoid evaluation of some expressions diff -r 74cf04d92ad5 -r 9971c7f37ee6 lib/mktime-internal.h --- a/lib/mktime-internal.h Thu Aug 30 06:27:53 2018 -0700 +++ b/lib/mktime-internal.h Fri Aug 31 18:02:48 2018 -0700 @@ -35,3 +35,19 @@ 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 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 -r 74cf04d92ad5 -r 9971c7f37ee6 lib/mktime.c --- a/lib/mktime.c Thu Aug 30 06:27:53 2018 -0700 +++ b/lib/mktime.c Fri Aug 31 18:02:48 2018 -0700 @@ -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 #include +#include +#include #include #include #if DEBUG_MKTIME # include -# include -# include /* 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 -# include +#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 + + - 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 + + 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 @@ }; -#ifdef _LIBC -typedef time_t mktime_offset_t; -#else -/* Portable standalone applications should supply a 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 @@ 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 @@ return t; } -#endif /* NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL || DEBUG_MKTIME */ - -#if NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS || DEBUG_MKTIME +#endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL */ -# 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 - - - 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 - - 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 -r 74cf04d92ad5 -r 9971c7f37ee6 lib/timegm.c --- a/lib/timegm.c Thu Aug 30 06:27:53 2018 -0700 +++ b/lib/timegm.c Fri Aug 31 18:02:48 2018 -0700 @@ -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 . */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ #ifndef _LIBC # include @@ -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