Re: [PATCH] useless-if-before-free: Check for nullptr.

2024-06-17 Thread Bruno Haible
Collin Funk asked:
> > -my $VERSION = '2022-01-27 18:51'; # UTC
> > +my $VERSION = '2024-06-17 03:44'; # UTC
> 
> What is the point of time stamping the file?

The point is to produce a reasonable 'useless-if-before-free --version' output.

This is where this thread started. [1]

Bruno

[1] https://lists.gnu.org/archive/html/bug-gnulib/2024-06/msg00141.html






Re: [PATCH] useless-if-before-free: Check for nullptr.

2024-06-17 Thread Collin Funk
Hi Bruno,

Bruno Haible wrote:
> The point is to produce a reasonable 'useless-if-before-free --version' 
> output.
> 
> This is where this thread started. [1]

Ah, I see. I figured the typical 'git log' or 'sed ... ChangeLog'
would be used like gnulib-tool.sh, all-modules, etc.

But those are only useful with a Gnulib clone whereas the others can
be copied directly if the Gnulib stuff isn't needed.

Collin



doc: Update for macOS 12, 13, 14

2024-06-17 Thread Bruno Haible
The Gnulib documentation regarding macOS has not been updated for 3 years.
This patch does it.

To do so, I first augmented the symbols and headers database in
https://git.savannah.gnu.org/gitweb/?p=gnulib/maint-tools.git;a=tree;f=platforms

Then, I used the config.cache and config.log files from the GitHub builds to
verify that most macOS bugs from earlier macOS versions are still present in
versions 12, 13, 14.


2024-06-17  Bruno Haible  

doc: Update for macOS 12, 13, 14.
* doc/posix-headers/*.texi: Update.
* doc/glibc-headers/*.texi: Update.
* doc/posix-functions/*.texi: Likewise.
* doc/pastposix-functions/*.texi: Likewise.
* doc/glibc-functions/*.texi: Likewise.
* m4/canonicalize.m4 (gl_FUNC_REALPATH_WORKS): Update cross-compilation
guess.
* m4/printf.m4 (gl_PRINTF_DIRECTIVE_A): Update comments.
* m4/readlinkat.m4 (gl_FUNC_READLINKAT): Likewise.

https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=e253528c9ff94eb5d4b4e436e187f008b468da96






Re: new module 'tzname'

2024-06-17 Thread Bruno Haible
Hi Paul,

In tzname.texi you added:

  @item
  This variable's contents are unreliable if you use a geographical
  @env{TZ} setting like @code{TZ="America/Los_Angeles"}.

What do you mean by "unreliable"? I tested the values for this TZ
and for my local one, and tzname is reasonable — the same values on
all platforms (except native Windows, which does not support
geographical TZ values in the first place).

=== foo.c =
#include 
#include 
#include 

int
main ()
{
  const char *tz = getenv ("TZ");
  tzset ();
  printf ("TZ=%s -> tzname[0]=\"%s\", tzname[1]=\"%s\"\n",
  tz != NULL ? tz : "(null)",
  tzname[0], tzname[1]);
  return 0;
}
===
Results:

  TZ=Europe/Berlin ./a.out TZ=America/Los_Angeles 
./a.out

glibc tzname[0]="CET", tzname[1]="CEST"tzname[0]="PST", 
tzname[1]="PDT"
musl  tzname[0]="CET", tzname[1]="CEST"tzname[0]="PST", 
tzname[1]="PDT"
macOS 12  tzname[0]="CET", tzname[1]="CEST"tzname[0]="PST", 
tzname[1]="PDT"
FreeBSD 14.0  tzname[0]="CET", tzname[1]="CEST"tzname[0]="PST", 
tzname[1]="PDT"
NetBSD 10.0   tzname[0]="CET", tzname[1]="CEST"tzname[0]="PST", 
tzname[1]="PDT"
OpenBSD 7.5   tzname[0]="CET", tzname[1]="CEST"tzname[0]="PST", 
tzname[1]="PDT"
AIX 7.3   tzname[0]="CET", tzname[1]="CEST"tzname[0]="PST", 
tzname[1]="PDT"
Solaris 11.4  tzname[0]="CET", tzname[1]="CEST"tzname[0]="PST", 
tzname[1]="PDT"
Cygwin 3.4.6  tzname[0]="CET", tzname[1]="CEST"tzname[0]="PST", 
tzname[1]="PDT"


So, what is the actual problem?

Does the problem only appear with specific TZ values? If so, what is the
most relevant such TZ value?

And is the problem related to the unification/overloading of time zones that
caused so many discussions in summer 2021?

Bruno






Re: [PATCH 6/7] nstrftime, time_rz: don’t depend on tzname

2024-06-17 Thread Bruno Haible
Paul Eggert did:
> (set_tz, revert_tz): Declare, as they’re now extern.

This causes link errors on NetBSD 10 (caught by the CI):

gcc  -Wno-error -g -O2  -L/home/bruno/lib -L/usr/pkg/lib -o test-c-nstrftime 
test-c-nstrftime.o libtests.a ../gllib/libgnu.a libtests.a ../gllib/libgnu.a 
libtests.a   -lexecinfo -lm -lm -lm -lm -lm -lm  -lm -lm -lm -lm -lm
ld: ../gllib/libgnu.a(c-nstrftime.o): in function `__strftime_internal':
/home/bruno/testdir-all/build/gllib/../../gllib/strftime.c:1352: undefined 
reference to `revert_tz'
ld: /home/bruno/testdir-all/build/gllib/../../gllib/strftime.c:1340: undefined 
reference to `set_tz'
*** Error code 1 (continuing)

gcc  -Wno-error -g -O2  -L/home/bruno/lib -L/usr/pkg/lib -o test-nstrftime 
test-nstrftime.o libtests.a ../gllib/libgnu.a libtests.a ../gllib/libgnu.a 
libtests.a   -lexecinfo -lm -lm -lm -lm -lm -lm  -lm -lm -lm -lm -lm
ld: ../gllib/libgnu.a(nstrftime.o): in function `__strftime_internal':
/home/bruno/testdir-all/build/gllib/../../gllib/strftime.c:1340: undefined 
reference to `set_tz'
ld: /home/bruno/testdir-all/build/gllib/../../gllib/strftime.c:1352: undefined 
reference to `revert_tz'
*** Error code 1 (continuing)

gcc  -Wno-error -g -O2  -L/home/bruno/lib -L/usr/pkg/lib -o test-parse-datetime 
test-parse-datetime.o libtests.a ../gllib/libgnu.a libtests.a ../gllib/libgnu.a 
libtests.a-lexecinfo -lm -lm -lm -lm -lm -lm  -lm -lm -lm -lm -lm
ld: ../gllib/libgnu.a(nstrftime.o): in function `__strftime_internal':
/home/bruno/testdir-all/build/gllib/../../gllib/strftime.c:1340: undefined 
reference to `set_tz'
ld: /home/bruno/testdir-all/build/gllib/../../gllib/strftime.c:1352: undefined 
reference to `revert_tz'
*** Error code 1 (continuing)

The cause is that
  - NetBSD 10 has timezone_t, therefore HAVE_TIMEZONE_T is 1,
  - therefore time_rz.c is not getting compiled,
  - part of time_rz.c is not needed to compile (tzalloc, tzfree, etc.),
but other parts of time_rz.c (set_tz, revert_tz) *do* need to be
compiled.

This patch fixes it.


2024-06-17  Bruno Haible  

time_rz: Fix link errors on NetBSD (regression yesterday).
* lib/time-internal.c: New file, extracted from lib/time_rz.c.
(tzgetname): New function.
* lib/time_rz.c (getenv_TZ, setenv_TZ, change_env, set_tz, revert_tz):
Moved to lib/time-internal.c.
* modules/time_rz (Files): Add lib/time-internal.c.
(Depends-on): Update.
(Makefile.am): Arrange to compile time-internal.c on all platforms.

diff --git a/lib/time-internal.c b/lib/time-internal.c
new file mode 100644
index 00..dab67c762f
--- /dev/null
+++ b/lib/time-internal.c
@@ -0,0 +1,116 @@
+/* Time zone internal functions
+
+   Copyright 2015-2024 Free Software Foundation, Inc.
+
+   This file 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 3 of the
+   License, or (at your option) any later version.
+
+   This file 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see .  */
+
+/* Written by Paul Eggert.  */
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include "flexmember.h"
+#include "time-internal.h"
+
+/* Get and set the TZ environment variable.  These functions can be
+   overridden by programs like Emacs that manage their own environment.  */
+
+#ifndef getenv_TZ
+static char *
+getenv_TZ (void)
+{
+  return getenv ("TZ");
+}
+#endif
+
+#ifndef setenv_TZ
+static int
+setenv_TZ (char const *tz)
+{
+  return tz ? setenv ("TZ", tz, 1) : unsetenv ("TZ");
+}
+#endif
+
+#if !HAVE_TIMEZONE_T
+static const char *
+tzgetname (timezone_t tz, int isdst)
+{
+  return tz->tz_is_set ? tz->abbrs : NULL;
+}
+#endif
+
+/* Change the environment to match the specified timezone_t value.
+   Return true if successful, false (setting errno) otherwise.  */
+static bool
+change_env (timezone_t tz)
+{
+  if (setenv_TZ (tzgetname (tz, 0)) != 0)
+return false;
+  tzset ();
+  return true;
+}
+
+/* Temporarily set the time zone to TZ, which must not be null.
+   Return LOCAL_TZ if the time zone setting is already correct.
+   Otherwise return a newly allocated time zone representing the old
+   setting, or NULL (setting errno) on failure.  */
+timezone_t
+set_tz (timezone_t tz)
+{
+  char *env_tz = getenv_TZ ();
+  const char *tz_name = tzgetname (tz, 0);
+  if (env_tz
+  ? tz_name != NULL && strcmp (tz_name, env_tz) == 0
+  : tz_name == NULL)
+return local_tz;
+  else
+{
+  timezone_t old_tz = tzalloc (env_tz);
+  if (!old_tz)
+return old_tz;
+  if (! change

Re: [PATCH 6/7] nstrftime, time_rz: don’t depend on tzname

2024-06-17 Thread Bruno Haible
Paul Eggert did:
> (__strftime_internal): Simplify calculation of zone to be closer
> to what glibc does.

This causes 4 test suite failures on Solaris 11.4, from a null pointer
reference:

FAIL: test-c-nstrftime-1.sh
===

../../gltests/test-c-nstrftime-1.sh: line 3: 9936: Memory fault(coredump)
FAIL test-c-nstrftime-1.sh (exit status: 1)

FAIL: test-c-nstrftime-2.sh
===

../../gltests/test-c-nstrftime-2.sh: line 16: 9941: Memory fault(coredump)
FAIL test-c-nstrftime-2.sh (exit status: 1)

FAIL: test-nstrftime-1.sh
=

../../gltests/test-nstrftime-1.sh: line 3: 14141: Memory fault(coredump)
FAIL test-nstrftime-1.sh (exit status: 1)

FAIL: test-nstrftime-2.sh
=

../../gltests/test-nstrftime-2.sh: line 18: 14146: Memory fault(coredump)
FAIL test-nstrftime-2.sh (exit status: 1)

It crashes at strftime.c:2032. zone is NULL.

This patch fixes the crash.


2024-06-17  Bruno Haible  

nstrftime, c-nstrftime: Fix crash on Solaris 11.4.
* lib/strftime.c (__strftime_internal): Restore protection against zone
being NULL.

diff --git a/lib/strftime.c b/lib/strftime.c
index e33dbb8f7c..e422267913 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -949,6 +949,8 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG 
(size_t maxsize)
 zone = "GMT";
 }
 #endif
+  if (! zone)
+zone = "";
 
   if (hour12 > 12)
 hour12 -= 12;






Re: [PATCH 6/7] nstrftime, time_rz: don’t depend on tzname

2024-06-17 Thread Bruno Haible
After the Solaris crash fix, the nstrftime tests still fail, due to this
output:

<-00>0: expected "1970-01-01 00:00:00 - (-00)", got "1970-01-01 00:00:00 
+ (-00)"
<-00>0: expected "1985-11-05 00:53:21 - (-00)", got "1985-11-05 00:53:21 
+ (-00)"
<-00>0: expected "2001-09-09 01:46:42 - (-00)", got "2001-09-09 01:46:42 
+ (-00)"

Can you please look into that? I cannot judge whether - and +
should be treated as equivalent or not.

Bruno






Re: new module 'tzname', tm_zone and tm_gmtoff

2024-06-17 Thread Bruno Haible
Paul Eggert wrote:
> >>> tzname is used in three places:
> >>> - time_rz,
> >>
> >> This should be fixed to use strftime instead.
> > 
> > This seems wrong for two reasons:
> > 
> >* time_rz is a small module, without textual I/O.
> 
> Fair enough, and the changes I recently installed into Gnulib solved 
> this problem in a different way, which make time_rz even smaller. As you 
> suggested, the updated time_rz does not use strftime.

Glad it worked out. Thanks!

> >* It is bad design to require calling a complicated function
> >  in order to get elementary data about something.
> 
> True, but unfortunately strftime %Z is the only widely supported and 
> portable way to get the time zone abbreviation.

NetBSD has a tzgetname() function: https://man.netbsd.org/tzset.3
tzgetname (tz, i) is equivalent to tzname[i].

This is the style of API I like better.

Still, what about internationalization of time zone names? For example,
in German, we write "MEZ" instead of "CET", and "MESZ" instead of "CEST".
In  you
reference CLDR. That sounds like something could be implemented here...
Is there already an API for retrieving localized time zone names
somewhere?

> In the long run I suppose we can assume struct tm's tm_zone instead. But 
> this is standardized only in POSIX.1-2024, and for many years apps will 
> need to deal with less-capable systems, notably Microsoft Windows.
> 
> We could create a new module to get a time zone abbreviation. It could 
> define a new function that is given BUF, SIZE, TM and TZ and would be 
> the equivalent of strftime (BUF, SIZE, "%Z", TM) in the timezone TZ

And the caller has to try different TM values? Why not a function that
takes an index in [0, 1], like tzgetname() does?

> Regardless of whether we add such a module, though, we should remove the 
> tzname module from Gnulib, as Gnulib doesn't need it any more and nobody 
> should use it. Proposed patch attached.

No, please leave it as is:
  - It is needed for portability to native Windows. Even though you say
that tzname is problematic, it is in the POSIX standard, and apps
may want to use it (despite the warnings in the doc).
  - We might need this module in order to implement (or speed up?) the
API that we are discussing above.

> it wrongly assumes 
> that there are at most two time zone abbreviations for any particular 
> time zone setting.

Oh? Which time zone has 3 or more abbreviations?

Bruno






Re: new module 'tzname', tm_zone and tm_gmtoff

2024-06-17 Thread Paul Eggert

On 2024-06-17 08:32, Bruno Haible wrote:


NetBSD has a tzgetname() function: https://man.netbsd.org/tzset.3
tzgetname (tz, i) is equivalent to tzname[i].

This is the style of API I like better.


That API can't work in general. Some time zones have multiple 
abbreviations for standard time. A clue to the problem is the 
documentation's "The return values for both tzgetname() and
tzgmtoff() correspond to the latest time for which data is available, 
even if that refers to a future time." This is obviously a bad thing.




Still, what about internationalization of time zone names? For example,
in German, we write "MEZ" instead of "CET", and "MESZ" instead of "CEST".
In  you
reference CLDR. That sounds like something could be implemented here...
Is there already an API for retrieving localized time zone names
somewhere?


Not that I know of. CLDR may have something.



And the caller has to try different TM values? Why not a function that
takes an index in [0, 1], like tzgetname() does?


Because there are typically more than two abbreviations. Even 
Europe/Berlin, which is relatively stable, has had four (CET, CEST, 
CEMT, LMT) and may have more if the EU daylight-saving changes that are 
in the legislative pipeline ever actually happen.






Regardless of whether we add such a module, though, we should remove the
tzname module from Gnulib, as Gnulib doesn't need it any more and nobody
should use it. Proposed patch attached.


No, please leave it as is:
   - It is needed for portability to native Windows. Even though you say
 that tzname is problematic, it is in the POSIX standard, and apps
 may want to use it (despite the warnings in the doc).


Apps really, really shouldn't use tzname. And POSIX plans to remove 
tzname in a future edition.




   - We might need this module in order to implement (or speed up?) the
 API that we are discussing above.


Gnulib shouldn't use tzname even for our own internal APIs.




Re: new module 'tzname'

2024-06-17 Thread Paul Eggert

On 2024-06-17 06:47, Bruno Haible wrote:

   @item
   This variable's contents are unreliable if you use a geographical
   @env{TZ} setting like @code{TZ="America/Los_Angeles"}.

What do you mean by "unreliable"?


You'll get different results on different platforms, the tzname values 
may not be what you want, and behavior is undefined if different threads 
call localtime etc. at about the same time, even if the program never 
changes TZ. For example, run this with TZ="Europe/London":


#include 
#include 
#include 

int
main ()
{
  const char *tz = getenv ("TZ");
  time_t epoch = 0;
  localtime (&epoch);
  printf ("TZ=%s -> tzname[0]=\"%s\", tzname[1]=\"%s\"\n",
  tz != NULL ? tz : "(null)",
  tzname[0], tzname[1]);
}

On GNU/Linux you'll get this:

TZ=Europe/London -> tzname[0]="BST", tzname[1]="BST"

but musl says tzname[0]="GMT". Both behaviors conform to POSIX. The 
glibc behavior is arguably nicer for single-threaded apps, but it's 
debatable. The POSIX folks, partly at my instigation, have wisely thrown 
up their hands about this, which is partly why tzname is planned to be 
removed.


I hope this helps to explain why Gnulib and GNU apps should (and 
generally do) avoid tzname.




Re: vasnprintf: Reject a width > INT_MAX

2024-06-17 Thread Bruno Haible
I did:
>   vasnprintf: Reject a width > INT_MAX.
>   * lib/vasnprintf.c (VASNPRINTF): If a width is > INT_MAX, fail with
>   EOVERFLOW.

This causes a test failure on Cygwin. Namely, Cygwin has vasnprintf,
but with this argument list
"x%030dy\n", -17
it returns "x-17y\n", of length 6,

It's best to ignore this vasnprintf implementation. Not because huge
widths were important by themselves, but because an implementation that
just swallows parts of the output when it cannot produce them is also
likely to have bugs in other situations, such as when malloc() fails.

This patch does that, and thus fixes the test failure.


2024-06-17  Bruno Haible  

vasnprintf: Fix test failure on Cygwin.
* m4/vasnprintf.m4 (gl_FUNC_VASNPRINTF): Require AC_CANONICAL_HOST. Test
whether vasnprintf works reliably; invoke gl_REPLACE_VASNPRINTF if not.

diff --git a/m4/vasnprintf.m4 b/m4/vasnprintf.m4
index 5dc3fe0c4d..a02f4e1e1d 100644
--- a/m4/vasnprintf.m4
+++ b/m4/vasnprintf.m4
@@ -1,5 +1,5 @@
 # vasnprintf.m4
-# serial 53
+# serial 54
 dnl Copyright (C) 2002-2004, 2006-2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -7,8 +7,40 @@
 
 AC_DEFUN([gl_FUNC_VASNPRINTF],
 [
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
   AC_CHECK_FUNCS_ONCE([vasnprintf])
-  if test $ac_cv_func_vasnprintf = no; then
+  if test $ac_cv_func_vasnprintf = yes; then
+dnl On Cygwin, in directives with a huge width, the width is ignored, and
+dnl the function returns a wrong result.
+AC_CACHE_CHECK([whether vasnprintf works],
+  [gl_cv_func_vasnprintf_works],
+  [AC_RUN_IFELSE(
+ [AC_LANG_SOURCE(
+[[#include 
+]],
+[[size_t len;
+  char *res = vasnprintf (NULL, &len, "x%030dy\n", -17);
+  /* On Cygwin 3.4.6, res is "x-17y\n" and len == 6: wrong.  */
+  return (res != NULL && len < 10);
+]])
+ ],
+ [gl_cv_func_vasnprintf_works=yes],
+ [gl_cv_func_vasnprintf_works=no],
+ [case "$host_os" in
+ # Guess no on Cygwin.
+cygwin*) gl_cv_func_vasnprintf_works="guessing no";;
+ # If we don't know, obey --enable-cross-guesses.
+*)   gl_cv_func_vasnprintf_works="$gl_cross_guess_normal";;
+  esac
+ ])
+  ])
+  fi
+  if test $ac_cv_func_vasnprintf != yes \
+ || case "$gl_cv_func_vasnprintf_works" in
+  *yes) false;;
+  *)true;;
+esac
+  then
 gl_REPLACE_VASNPRINTF
   fi
 ])






Re: [PATCH 6/7] nstrftime, time_rz: don’t depend on tzname

2024-06-17 Thread Paul Eggert
Thanks for reporting and fixing that. For NetBSD, a better fix is to use 
the native timezone_t, so that Gnulib doesn't need to set and later 
restore TZ. I attempted to do by installing the attached.From 17432773bb157fe9bd11137edd42cd7be35e1dea Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Mon, 17 Jun 2024 16:16:29 -0700
Subject: [PATCH] nstrftime: improve fix for NetBSD link errors

This makes the NetBSD code thread-safe and presumably faster.
* lib/strftime.c (HAVE_NATIVE_TIME_Z): New macro.
(__strftime_internal): If HAVE_NATIVE_TIME_Z, use strftime_lz
or strftime_z instead of setting and reverting TZ.
* lib/time-internal.c: Remove, reverting recent change.
* lib/time_rz.c, modules/time_rz: Also revert recent changes,
since the relevant functions can now remain private to time_rz.c.
* m4/c-nstrftime.m4 (gl_C_GNU_STRFTIME): Check for strftime_lz.
* m4/nstrftime.m4 (gl_FUNC_GNU_STRFTIME): Check for strftime_z.
---
 ChangeLog   |  13 +
 lib/strftime.c  |  16 +-
 lib/time-internal.c | 116 
 lib/time_rz.c   |  78 +
 m4/c-nstrftime.m4   |   4 +-
 m4/nstrftime.m4 |   3 +-
 modules/time_rz |  12 ++---
 7 files changed, 116 insertions(+), 126 deletions(-)
 delete mode 100644 lib/time-internal.c

diff --git a/ChangeLog b/ChangeLog
index f0593b5e50..2ae4064d4f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2024-06-17  Paul Eggert  
+
+	nstrftime: improve fix for NetBSD link errors
+	This makes the NetBSD code thread-safe and presumably faster.
+	* lib/strftime.c (HAVE_NATIVE_TIME_Z): New macro.
+	(__strftime_internal): If HAVE_NATIVE_TIME_Z, use strftime_lz
+	or strftime_z instead of setting and reverting TZ.
+	* lib/time-internal.c: Remove, reverting recent change.
+	* lib/time_rz.c, modules/time_rz: Also revert recent changes,
+	since the relevant functions can now remain private to time_rz.c.
+	* m4/c-nstrftime.m4 (gl_C_GNU_STRFTIME): Check for strftime_lz.
+	* m4/nstrftime.m4 (gl_FUNC_GNU_STRFTIME): Check for strftime_z.
+
 2024-06-17  Bruno Haible  
 
 	vasnprintf: Fix test failure on Cygwin.
diff --git a/lib/strftime.c b/lib/strftime.c
index e422267913..2db6603a23 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -38,6 +38,8 @@
 # include "time-internal.h"
 #endif
 
+#define HAVE_NATIVE_TIME_Z (USE_C_LOCALE ? HAVE_STRFTIME_LZ : HAVE_STRFTIME_Z)
+
 /* Whether to require GNU behavior for AM and PM indicators, even on
other platforms.  This matters only in non-C locales.
The default is to require it; you can override this via
@@ -1336,6 +1338,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
 *u++ = format_char;
 *u = '\0';
 
+# if !HAVE_NATIVE_TIME_Z
 timezone_t old_tz = NULL;
 if (set_and_revert_tz)
   {
@@ -1343,16 +1346,27 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
 if (!old_tz)
   return 0;
   }
-# if USE_C_LOCALE && HAVE_STRFTIME_L
+# endif
+# if USE_C_LOCALE && (HAVE_STRFTIME_L || HAVE_STRFTIME_LZ)
 locale_t locale = c_locale ();
 if (!locale)
   return 0; /* errno is set here */
+# if HAVE_STRFTIME_LZ
+len = strftime_lz (tz, ubuf, sizeof ubuf, ufmt, tp, locale);
+# else
 len = strftime_l (ubuf, sizeof ubuf, ufmt, tp, locale);
+# endif
 # else
+#  if HAVE_STRFTIME_Z
+len = strftime_z (tz, ubuf, sizeof ubuf, ufmt, tp);
+#  else
 len = strftime (ubuf, sizeof ubuf, ufmt, tp);
+#  endif
 # endif
+# if !HAVE_NATIVE_TIME_Z
 if (old_tz && !revert_tz (old_tz))
   return 0;
+# endif
   }
 if (len != 0)
   {
diff --git a/lib/time-internal.c b/lib/time-internal.c
deleted file mode 100644
index dab67c762f..00
--- a/lib/time-internal.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Time zone internal functions
-
-   Copyright 2015-2024 Free Software Foundation, Inc.
-
-   This file 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 3 of the
-   License, or (at your option) any later version.
-
-   This file 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 Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public License
-   along with this program.  If not, see .  */
-
-/* Written by Paul Eggert.  */
-
-#include 
-
-#include 
-
-#include 
-#include 
-#include 
-
-#include "flexmember.h"
-#include "time-internal.h"
-
-/* Get and set the TZ environment variable.  The

Re: [PATCH 6/7] nstrftime, time_rz: don’t depend on tzname

2024-06-17 Thread Bruno Haible
Paul Eggert wrote:
> Thanks for reporting and fixing that. For NetBSD, a better fix is to use 
> the native timezone_t, so that Gnulib doesn't need to set and later 
> restore TZ.

Interesting. So, we have at least one platform now, where nstrftime is
multithread-safe.

Only an indentation nit:


2024-06-17  Bruno Haible  

nstrftime: Correct indentation.
* lib/strftime.c (__strftime_internal): Correct indentation of
preprocessor directives.

diff --git a/lib/strftime.c b/lib/strftime.c
index 2db6603a23..db59d65d05 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -1351,11 +1351,11 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG 
(size_t maxsize)
 locale_t locale = c_locale ();
 if (!locale)
   return 0; /* errno is set here */
-# if HAVE_STRFTIME_LZ
+#  if HAVE_STRFTIME_LZ
 len = strftime_lz (tz, ubuf, sizeof ubuf, ufmt, tp, locale);
-# else
+#  else
 len = strftime_l (ubuf, sizeof ubuf, ufmt, tp, locale);
-# endif
+#  endif
 # else
 #  if HAVE_STRFTIME_Z
 len = strftime_z (tz, ubuf, sizeof ubuf, ufmt, tp);






Re: [PATCH 6/7] nstrftime, time_rz: don’t depend on tzname

2024-06-17 Thread Paul Eggert

On 2024-06-17 07:51, Bruno Haible wrote:

After the Solaris crash fix, the nstrftime tests still fail, due to this
output:

<-00>0: expected "1970-01-01 00:00:00 - (-00)", got "1970-01-01 00:00:00 + 
(-00)"
<-00>0: expected "1985-11-05 00:53:21 - (-00)", got "1985-11-05 00:53:21 + 
(-00)"
<-00>0: expected "2001-09-09 01:46:42 - (-00)", got "2001-09-09 01:46:42 + 
(-00)"

Can you please look into that? I cannot judge whether - and +
should be treated as equivalent or not.


"-" signals "I don't know what the time zone is, so I'm using UTC". 
I installed the attached to try to fix that issue. Thanks for reporting it.From 55bd47e8ef7d6282c4405652c37a52d1c999b464 Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Mon, 17 Jun 2024 20:47:09 -0700
Subject: [PATCH] nstrftime: fix bug with - on Solaris 11
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Problem reported by Bruno Haible in:
https://lists.gnu.org/r/bug-gnulib/2024-06/msg00201.html
* lib/strftime.c (strftime) [!_LIBC]: Move #undef up.
(underlying_strftime) [!_LIBC]: New function, containing most of
what __strftime_internal used to do at the underlying_strftime label.
(get_tm_zone): New function, containing much of what
__strftime_internal used to do for %Z.
Be consistent about using "UTC" rather than "GMT";
this changes behavior only on platforms lacking tm_zone.
(__strftime_internal): Use them to compute time zone abbreviation
when needed.  Make ‘zone’ more local, and compute it only if
needed.  Simplify by removing set_and_revert_tz local var and its
uses; no longer needed now that we have get_tm_zone.  Do not
assume %EZ and %OZ are equivalent to %Z.
---
 ChangeLog  |  18 +++
 lib/strftime.c | 315 +
 2 files changed, 233 insertions(+), 100 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9dc5edff7e..553f1aa896 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2024-06-17  Paul Eggert  
+
+	nstrftime: fix bug with - on Solaris 11
+	Problem reported by Bruno Haible in:
+	https://lists.gnu.org/r/bug-gnulib/2024-06/msg00201.html
+	* lib/strftime.c (strftime) [!_LIBC]: Move #undef up.
+	(underlying_strftime) [!_LIBC]: New function, containing most of
+	what __strftime_internal used to do at the underlying_strftime label.
+	(get_tm_zone): New function, containing much of what
+	__strftime_internal used to do for %Z.
+	Be consistent about using "UTC" rather than "GMT";
+	this changes behavior only on platforms lacking tm_zone.
+	(__strftime_internal): Use them to compute time zone abbreviation
+	when needed.  Make ‘zone’ more local, and compute it only if
+	needed.  Simplify by removing set_and_revert_tz local var and its
+	uses; no longer needed now that we have get_tm_zone.  Do not
+	assume %EZ and %OZ are equivalent to %Z.
+
 2024-06-17  Bruno Haible  
 
 	nstrftime: Correct indentation.
diff --git a/lib/strftime.c b/lib/strftime.c
index db59d65d05..ff52fc8119 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -837,6 +837,190 @@ static size_t __strftime_internal (STREAM_OR_CHAR_T *, STRFTIME_ARG (size_t)
bool, enum pad_style, int, bool *
extra_args_spec LOCALE_PARAM);
 
+#ifndef _LIBC
+
+/* Make sure we're calling the actual underlying strftime.
+   In some cases, time.h contains something like
+   "#define strftime rpl_strftime".  */
+# ifdef strftime
+#  undef strftime
+# endif
+
+/* Assuming the time zone is TZ, store into UBUF, of size UBUFSIZE, a
+   ' ' followed by the result of calling strftime with the format
+   "%MF" where M is MODIFIER (or is omitted if !MODIFIER) and F is
+   FORMAT_CHAR, along with the time information specified by *TP.
+   Return the number of bytes stored if successful, zero otherwise.  */
+static size_t
+underlying_strftime (timezone_t tz, char *ubuf, size_t ubufsize,
+ char modifier, char format_char, struct tm const *tp)
+{
+  /* The relevant information is available only via the
+ underlying strftime implementation, so use that.  */
+  char ufmt[5];
+  char *u = ufmt;
+
+  /* The space helps distinguish strftime failure from empty
+ output.  */
+  *u++ = ' ';
+  *u++ = '%';
+  *u = modifier;
+  u += !!modifier;
+  *u++ = format_char;
+  *u = '\0';
+
+#if !HAVE_NATIVE_TIME_Z
+  if (tz && tz != local_tz)
+{
+  tz = set_tz (tz);
+  if (!tz)
+return 0;
+}
+#endif
+
+  size_t len;
+# if USE_C_LOCALE && (HAVE_STRFTIME_L || HAVE_STRFTIME_LZ)
+  locale_t locale = c_locale ();
+  if (!locale)
+return 0; /* errno is set here */
+#  if HAVE_STRFTIME_LZ
+  len = strftime_lz (tz, ubuf, ubufsize, ufmt, tp, locale);
+#  else
+  len = strftime_l (ubuf, ubufsize, ufmt, tp, locale);
+#  endif
+# else
+#  if HAVE_STRFTIME_Z
+  len = strftime_z (tz, ubuf, ubufsize, ufmt, tp);
+#  else
+  len = strftime (ubuf, ubufsize, ufmt, tp);
+#  endif
+# endif
+
+# if !HAVE_N

Re: configure output from largefile.m4

2024-06-17 Thread Paul Eggert
Thanks, I installed the attached which I hope is good enough. It's also 
in Autoconf master now.From 247f06bd6f6a3a637442060d4ad20907778e88cd Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Mon, 17 Jun 2024 21:08:29 -0700
Subject: [PATCH] Improve wording for Y2038 and largefile probes

This change syncs from Autoconf master.
Problem reported by Bruno Haible in:
https://lists.gnu.org/r/bug-gnulib/2024-06/msg00181.html
* m4/largefile.m4 (_AC_SYS_YEAR2038_PROBE)
(_AC_SYS_LARGEFILE_PROBE): Improve wording of chatter.
---
 ChangeLog   | 7 +++
 m4/largefile.m4 | 6 +++---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 553f1aa896..75f06623d6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2024-06-17  Paul Eggert  
 
+	Improve wording for Y2038 and largefile probes
+	This change syncs from Autoconf master.
+	Problem reported by Bruno Haible in:
+	https://lists.gnu.org/r/bug-gnulib/2024-06/msg00181.html
+	* m4/largefile.m4 (_AC_SYS_YEAR2038_PROBE)
+	(_AC_SYS_LARGEFILE_PROBE): Improve wording of chatter.
+
 	nstrftime: fix bug with - on Solaris 11
 	Problem reported by Bruno Haible in:
 	https://lists.gnu.org/r/bug-gnulib/2024-06/msg00201.html
diff --git a/m4/largefile.m4 b/m4/largefile.m4
index 2f824089b0..2881348359 100644
--- a/m4/largefile.m4
+++ b/m4/largefile.m4
@@ -1,5 +1,5 @@
 # largefile.m4
-# serial 1
+# serial 2
 dnl Copyright 1992-1996, 1998-2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -88,7 +88,7 @@ m4_define([_AC_SYS_YEAR2038_OPTIONS], m4_normalize(
 # If you change this macro you may also need to change
 # _AC_SYS_YEAR2038_OPTIONS.
 AC_DEFUN([_AC_SYS_YEAR2038_PROBE],
-[AC_CACHE_CHECK([for $CPPFLAGS option for timestamps after 2038],
+[AC_CACHE_CHECK([for $CC option to support timestamps after 2038],
   [ac_cv_sys_year2038_opts],
   [ac_save_CPPFLAGS="$CPPFLAGS"
   ac_opt_found=no
@@ -234,7 +234,7 @@ m4_define([_AC_SYS_LARGEFILE_OPTIONS], m4_normalize(
 # If you change this macro you may also need to change
 # _AC_SYS_LARGEFILE_OPTIONS.
 AC_DEFUN([_AC_SYS_LARGEFILE_PROBE],
-[AC_CACHE_CHECK([for $CPPFLAGS option for large files],
+[AC_CACHE_CHECK([for $CC option to support large files],
   [ac_cv_sys_largefile_opts],
   [ac_save_CPPFLAGS=$CPPFLAGS
   ac_opt_found=no
-- 
2.43.0