bug#79118: CI test failures

Bruno Haible via GNU coreutils Bug Reports <[email protected]>
Newsgroups gmane.comp.gnu.core-utils.bugs
Organization GNU
Message-ID <5081977.tIAgqjz4sF@nimes>
Collin Funk wrote in 
https://lists.gnu.org/archive/html/bug-gnulib/2025-07/msg00214.html:

> This part of the function body of
> gl_locale_name_environ should make it clear:
> 
>     /* Setting of LC_ALL overrides all other. */
>     retval = getenv ("LC_ALL");
>     if (retval != NULL && retval[0] != '\0')
>       return retval;
>     /* Next comes the name of the desired category. */
>     retval = getenv (categoryname);
>     if (retval != NULL && retval[0] != '\0')
>       return retval;
> 
> So, despite setting 'setlocale (LC_TIME, "C")' when doing
> 'LC_ALL=am_ET.UTF-8 date --iso-8601=hours' we will receive the value
> from LC_ALL in the environment.

There are basically two ways to fix this:
  (a) set the appropriate environment variables (instead of setlocale calls),
  (b) add an nstrftime_l and fprintftime_l variant and pass a locale that
      has "C" for the LC_TIME category.

(b) is more hairy, when it comes to the "underlying strftime" delegation in
gnulib/lib/strftime.c.

Therefore here is a proposed fix according to (a). It fixes the test failures
on macOS and OpenBSD. It also passes "make syntax-check".
0001-date-Fix-calendar-related-test-failures-on-macOS-and.patch (text/x-patch, 4.2 KB)
From 781de8e4b032a710e524ae488204502724956701 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Thu, 31 Jul 2025 18:42:02 +0200
Subject: [PATCH] date: Fix calendar-related test failures on macOS and OpenBSD

Reported at <https://bugs.gnu.org/79118>.

* bootstrap.conf (gnulib_modules): Add xsetenv.
* src/date.c: Include xsetenv.h.
(set_LC_TIME): New function.
(show_date_helper): Call set_LC_TIME instead of setlocale.
* po/POTFILES.in: Add lib/xsetenv.c.
---
 bootstrap.conf |  1 +
 gnulib         |  2 +-
 po/POTFILES.in |  1 +
 src/date.c     | 59 +++++++++++++++++++++++++++++++++++++++++++++-----
 4 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/bootstrap.conf b/bootstrap.conf
index 72aafddaf..7577cffd5 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -309,6 +309,7 @@ gnulib_modules="
   xprintf
   xprintf-posix
   xreadlink
+  xsetenv
   xstrtod
   xstrtoimax
   xstrtol
diff --git a/gnulib b/gnulib
index 84ddfc7bd..caf768863 160000
--- a/gnulib
+++ b/gnulib
@@ -1 +1 @@
-Subproject commit 84ddfc7bd29853ed91cdd65c7ce818072959f974
+Subproject commit caf768863e2a411ede373164e861b0bf6b707bcc
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 95e325336..8e8fb056c 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -29,6 +29,7 @@ lib/xalloc-die.c
 lib/xbinary-io.c
 lib/xmemcoll.c
 lib/xprintf.c
+lib/xsetenv.c
 lib/xstrtol-error.c
 
 # Package source files
diff --git a/src/date.c b/src/date.c
index 6979399c3..4a8dabc2e 100644
--- a/src/date.c
+++ b/src/date.c
@@ -31,6 +31,7 @@
 #include "quote.h"
 #include "show-date.h"
 #include "stat-time.h"
+#include "xsetenv.h"
 
 /* The official name of this program (e.g., no 'g' prefix).  */
 #define PROGRAM_NAME "date"
@@ -330,6 +331,48 @@ adjust_resolution (char const *format)
   return copy;
 }
 
+/* Set the LC_TIME category of the current locale.
+   Return the previous value of the LC_TIME category, as a freshly allocated
+   string or null.  */
+
+static char *
+set_LC_TIME (char const *locale)
+{
+  /* It is not sufficient to do
+       setlocale (LC_TIME, locale);
+     because show_date relies on fprintftime, that uses the Gnulib module
+     'localename-unsafe', that looks at the values of the environment variables
+     (in order to distinguish the default locale from the C locale on platforms
+     like macOS).  */
+  char const *all = getenv ("LC_ALL");
+  if (all != nullptr && *all != '\0')
+    {
+      /* Setting LC_TIME when LC_ALL is set would have no effect.  Therefore we
+         have to unset LC_ALL and sets its value to all locale categories that
+         are relevant for this program.  */
+      xsetenv ("LC_CTYPE", all, 1);          /* definitely needed */
+      xsetenv ("LC_TIME", all, 1);           /* definitely needed */
+      xsetenv ("LC_MESSAGES", all, 1);       /* definitely needed */
+      xsetenv ("LC_NUMERIC", all, 1);        /* possibly needed */
+      /* xsetenv ("LC_COLLATE", all, 1); */  /* not needed */
+      /* xsetenv ("LC_MONETARY", all, 1); */ /* not needed */
+      unsetenv ("LC_ALL");
+    }
+
+  /* Set LC_TIME as an environment variable.  */
+  char const *value = getenv ("LC_TIME");
+  char *ret = (value == nullptr || *value == '\0' ? nullptr : xstrdup (value));
+  if (locale != nullptr)
+    xsetenv ("LC_TIME", locale, 1);
+  else
+    unsetenv ("LC_TIME");
+
+  /* Update the current locale accordingly.  */
+  setlocale (LC_TIME, "");
+
+  return ret;
+}
+
 /* Parse each line in INPUT_FILENAME as with --date and display each
    resulting time and date.  If the file cannot be opened, tell why
    then exit.  Issue a diagnostic for any lines that cannot be parsed.
@@ -662,13 +705,17 @@ show_date_helper (char const *format, bool use_c_locale,
   if (parse_datetime_flags & PARSE_DATETIME_DEBUG)
     error (0, 0, _("output format: %s"), quote (format));
 
+  bool ok;
   if (use_c_locale)
-    setlocale (LC_TIME, "C");
-
-  bool ok = show_date (format, when, tz);
-
-  if (use_c_locale)
-    setlocale (LC_TIME, "");
+    {
+      char *old_locale_category = set_LC_TIME ("C");
+      ok = show_date (format, when, tz);
+      char *new_locale_category = set_LC_TIME (old_locale_category);
+      free (new_locale_category);
+      free (old_locale_category);
+    }
+  else
+    ok = show_date (format, when, tz);
 
   putchar ('\n');
   return ok;
-- 
2.50.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.