>From 1a27ec76bc436a64070461bbbf28e0511c7cf3b8 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Sat, 23 Nov 2019 16:31:47 -0800
Subject: [PATCH] Allow definition of vars the system lacks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

For example, FreeBSD lacks ���altzone��� but we may want to
support it in the replacement library.
* Makefile, NEWS: Document change.
* localtime.c (tzname, timezone, daylight, altzone): Define only
if necessary: either the corresponding macro is 2, or it is 1 and
TZ_TIME_T is set so we are implementing the features under a
different name.
* private.h (ALTZONE): Default to 1 or 0.
All uses now changed to ���#if��� instead of ���#ifdef���.
(tzname, timezone, daylight, altzone):
Declare only if necessary: either the corresponding macro is 2,
or it is 1 and TZ_TIME_T is set (so we are implementing the
features under a different name) or !HAVE_POSIX_DECLS (so the
system headers lack the decls).
---
 Makefile    | 15 ++++++++++-----
 NEWS        | 10 ++++++++++
 localtime.c | 20 +++++++++-----------
 private.h   | 21 +++++++++++++--------
 strftime.c  |  4 ++--
 5 files changed, 44 insertions(+), 26 deletions(-)

diff --git a/Makefile b/Makefile
index 6c03858..865b39f 100644
--- a/Makefile
+++ b/Makefile
@@ -295,8 +295,9 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
 # than TM_GMTOFF and TM_ZONE.  However, most of them are standardized.
 # #
 # # To omit or support the external variable "tzname", add one of:
-# #	-DHAVE_TZNAME=0
-# #	-DHAVE_TZNAME=1
+# #	-DHAVE_TZNAME=0 # do not support "tzname"
+# #	-DHAVE_TZNAME=1 # support "tzname", which is defined by system library
+# #	-DHAVE_TZNAME=2 # support and define "tzname"
 # # to the "CFLAGS=" line.  "tzname" is required by POSIX 1988 and later.
 # # If not defined, the code attempts to guess HAVE_TZNAME from other macros.
 # # Warning: unless time_tz is also defined, HAVE_TZNAME=1 can cause
@@ -304,16 +305,20 @@ GCC_DEBUG_FLAGS = -DGCC_LINT -g3 -O3 -fno-common \
 # # presumably due to memory allocation issues.
 # #
 # # To omit or support the external variables "timezone" and "daylight", add
-# #	-DUSG_COMPAT=0
-# #	-DUSG_COMPAT=1
+# #	-DUSG_COMPAT=0 # do not support
+# #	-DUSG_COMPAT=1 # support, and variables are defined by system library
+# #	-DUSG_COMPAT=2 # support and define variables
 # # to the "CFLAGS=" line; "timezone" and "daylight" are inspired by
 # # Unix Systems Group code and are required by POSIX 2008 (with XSI) and later.
 # # If not defined, the code attempts to guess USG_COMPAT from other macros.
 # #
 # # To support the external variable "altzone", add
-# #	-DALTZONE
+# #	-DALTZONE=0 # do not support
+# #	-DALTZONE=1 # support "altzone", which is defined by system library
+# #	-DALTZONE=2 # support and define "altzone"
 # # to the end of the "CFLAGS=" line; although "altzone" appeared in
 # # System V Release 3.1 it has not been standardized.
+# # If not defined, the code attempts to guess ALTZONE from other macros.
 #
 # If you want functions that were inspired by early versions of X3J11's work,
 # add
diff --git a/NEWS b/NEWS
index 92bff58..28b6bad 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,16 @@ Unreleased, experimental changes
     been renamed to America/Nuuk.  A backwards-compatibility link
     remains for the old name.
 
+  Changes to code
+
+    The configuration macros HAVE_TZNAME and USG_COMPAT should now be
+    set to 1 if the system library supports the feature, and 2 if not.
+    As before, these macros are nonzero if tzcode should support the
+    feature, zero otherwise.
+
+    The configuration macro ALTZONE now has the same values with the
+    same meaning as HAVE_TZNAME and USG_COMPAT.
+
 
 Release 2019c - 2019-09-11 08:59:48 -0700
 
diff --git a/localtime.c b/localtime.c
index 033e88f..d3f8fc7 100644
--- a/localtime.c
+++ b/localtime.c
@@ -193,20 +193,18 @@ static int		lcl_is_set;
 
 static struct tm	tm;
 
-#if !HAVE_POSIX_DECLS || TZ_TIME_T
-# if HAVE_TZNAME
+#if 2 <= HAVE_TZNAME + TZ_TIME_T
 char *			tzname[2] = {
 	(char *) wildabbr,
 	(char *) wildabbr
 };
-# endif
-# if USG_COMPAT
+#endif
+#if 2 <= USG_COMPAT + TZ_TIME_T
 long			timezone;
 int			daylight;
-# endif
-# ifdef ALTZONE
+#endif
+#if 2 <= ALTZONE + TZ_TIME_T
 long			altzone;
-# endif
 #endif
 
 /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX.  */
@@ -276,7 +274,7 @@ update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp)
   if (!ttisp->tt_isdst)
     timezone = - ttisp->tt_utoff;
 #endif
-#ifdef ALTZONE
+#if ALTZONE
   if (ttisp->tt_isdst)
     altzone = - ttisp->tt_utoff;
 #endif
@@ -295,9 +293,9 @@ settzname(void)
 	daylight = 0;
 	timezone = 0;
 #endif
-#ifdef ALTZONE
+#if ALTZONE
 	altzone = 0;
-#endif /* defined ALTZONE */
+#endif
 	if (sp == NULL) {
 		return;
 	}
@@ -2345,7 +2343,7 @@ posix2time(time_t t)
 #  define daylight 0
 #  define timezone 0
 # endif
-# ifndef ALTZONE
+# if !ALTZONE
 #  define altzone 0
 # endif
 
diff --git a/private.h b/private.h
index 87f923a..0d6d80f 100644
--- a/private.h
+++ b/private.h
@@ -198,6 +198,14 @@
 # endif
 #endif
 
+#ifndef ALTZONE
+# if defined __sun || defined _M_XENIX
+#  define ALTZONE 1
+# else
+#  define ALTZONE 0
+# endif
+#endif
+
 #ifndef R_OK
 #define R_OK	4
 #endif /* !defined R_OK */
@@ -477,7 +485,7 @@ typedef time_tz tz_time_t;
 #  undef  timezone
 #  define timezone tz_timezone
 # endif
-# ifdef ALTZONE
+# if ALTZONE
 #  undef  altzone
 #  define altzone tz_altzone
 # endif
@@ -518,17 +526,14 @@ extern char *asctime_r(struct tm const *restrict, char *restrict);
 extern char **environ;
 #endif
 
-#if TZ_TIME_T || !HAVE_POSIX_DECLS
-# if HAVE_TZNAME
+#if 2 <= HAVE_TZNAME + (TZ_TIME_T || !HAVE_POSIX_DECLS)
 extern char *tzname[];
-# endif
-# if USG_COMPAT
+#endif
+#if 2 <= USG_COMPAT + (TZ_TIME_T || !HAVE_POSIX_DECLS)
 extern long timezone;
 extern int daylight;
-# endif
 #endif
-
-#ifdef ALTZONE
+#if 2 <= ALTZONE + (TZ_TIME_T || !HAVE_POSIX_DECLS)
 extern long altzone;
 #endif
 
diff --git a/strftime.c b/strftime.c
index ac26f4b..14cbc9a 100644
--- a/strftime.c
+++ b/strftime.c
@@ -492,7 +492,7 @@ label:
 				*/
 				continue;
 			case 'z':
-#if defined TM_GMTOFF || USG_COMPAT || defined ALTZONE
+#if defined TM_GMTOFF || USG_COMPAT || ALTZONE
 				{
 				long		diff;
 				char const *	sign;
@@ -529,7 +529,7 @@ label:
 					continue;
 #  endif
 				else
-#  ifdef ALTZONE
+#  if ALTZONE
 					diff = -altzone;
 #  else
 					continue;
-- 
2.17.1

