Thanks, I installed that and am marking this bug report as done.
I used the opportunity to sync GNU diff with current Gnulib, causing a
few minor changes to Gnulib.
I also installed the attached patch, to work around more the places
where Gnulib drags in some multithreading and/or locale code that GNU
diff (which is single-threaded and not that picky about locales) doesn't
need. Not sure if these suggest any Gnulib changes.From e124541148d38cd8b7f962aceb72fb44e7cc0aab Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Fri, 5 Sep 2025 09:56:13 -0700
Subject: [PATCH] maint: reduce Gnulib module usage
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Recentish changes to Gnulib have pulled in more dependencies
on multithreading, locking, and whatnot. Revamp to remove
these unwanted dependencies.
* bootstrap.conf: Also avoid hard-locale, localcharset,
localename-unsafe, localename-unsafe-limited.
Stop avoiding localename.
(avoided_gnulib_tests): New var. Avoid these tests too.
(gnulib-modules): Remove hard-locale, nstrftime.
Add nstrftime-limited.
* configure.ac (gl_cv_func_mbrtowc_C_locale_sans_EILSEQ)
(gl_cv_func_mbrtoc32_C_locale_sans_EILSEQ):
New vars, so that we do not worry about multibyte C locales.
(gl_THREADLIB_DEFAULT_NO): New macro.
Not sure how much it helps, but it can’t hurt.
(SUPPORT_NON_GREG_CALENDARS_IN_STRFTIME): New macro.
* src/cmp.c: Do not include hard-locale.h.
(hard_locale_LC_MESSAGES): Assume that LC_MESSAGES is hard
if and only if "(C)" gets translated. This drags in fewer
dependencies than calling hard_locale.
* src/diff.c: Include strftime.h instead of hard-locale.h.
(hard_locale_LC_TIME): New function, that uses nstrftime
to infer whether the time locale is hard.
(main): Use it instead of hard_locale.
maint: default Gnulib to no multithreading
* configure.ac: Define gl_THREADLIB_DEFAULT_NO
so that Gnulib defaults to no multithreading.
---
bootstrap.conf | 26 +++++++++++++++++++++++---
configure.ac | 14 ++++++++++++++
src/cmp.c | 4 ++--
src/diff.c | 19 +++++++++++++++++--
4 files changed, 56 insertions(+), 7 deletions(-)
diff --git a/bootstrap.conf b/bootstrap.conf
index 73cc160..427a5f7 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -16,12 +16,32 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
avoided_gnulib_modules='
- --avoid=localename
+ --avoid=hard-locale
+ --avoid=localcharset
+ --avoid=localename-unsafe
+ --avoid=localename-unsafe-limited
--avoid=lock-tests
--avoid=mbuiter
--avoid=mbuiterf
--avoid=setlocale
'
+# These tests depend on localcharset, which we avoid.
+avoided_gnulib_tests='
+ --avoid=c32width-tests
+ --avoid=quotearg-simple-tests
+ --avoid=regex-tests
+ --avoid=wcwidth-tests
+'
+# These test whether all bytes are valid in the C locale,
+# which we don't care about.
+avoided_gnulib_tests=$avoided_gnulib_tests'
+ --avoid=btoc32-tests
+ --avoid=btowc-tests
+ --avoid=mbrtoc32-tests
+ --avoid=mbrtowc-tests
+ --avoid=mbsrtoc32s-tests
+ --avoid=mbsrtowcs-tests
+'
# gnulib modules used by this package.
gnulib_modules='
@@ -66,7 +86,6 @@ gnu-make
gnu-web-doc-update
gnumakefile
gnupload
-hard-locale
ialloc
idx
intprops
@@ -81,7 +100,7 @@ mempcpy
minmax
mkstemp
mktime
-nstrftime
+nstrftime-limited
nullptr
openat
pclose
@@ -149,6 +168,7 @@ gnulib_tool_option_extras="--tests-base=gnulib-tests
--symlink
--makefile-name=gnulib.mk
$avoided_gnulib_modules
+ $avoided_gnulib_tests
"
# Build prerequisites
diff --git a/configure.ac b/configure.ac
index 7640124..aec74ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -37,6 +37,18 @@ AC_PROG_AWK
AC_PROG_CC
AM_MISSING_PROG([HELP2MAN], [help2man])
AC_PROG_RANLIB
+
+# Do not worry about multibyte C locales.
+# This removes dependencies on hard-locale etc.
+gl_cv_func_mbrtowc_C_locale_sans_EILSEQ="guessing yes"
+gl_cv_func_mbrtoc32_C_locale_sans_EILSEQ="guessing yes"
+
+# Default Gnulib configuration to no multithreading,
+# since diffutils is single-threaded.
+# Although the builder can override this with the --enable-threads option
+# of 'configure', diffutils does not support that on all platforms.
+m4_define([gl_THREADLIB_DEFAULT_NO])
+
gl_EARLY
gl_USE_SYSTEM_EXTENSIONS
gl_INIT
@@ -61,6 +73,8 @@ AC_DEFINE([GNULIB_MBRTOC32_REGULAR], [1],
AC_DEFINE([REQUIRE_GNUISH_STRFTIME_AM_PM], [0],
[Do not worry about GNU strftime behavior for AM and PM indicators.])
+AC_DEFINE([SUPPORT_NON_GREG_CALENDARS_IN_STRFTIME], [false],
+ [Do not worry about GNU strftime behavior for non-Gregorian calendars.])
AC_C_INLINE
diff --git a/src/cmp.c b/src/cmp.c
index 2482708..0c4c80c 100644
--- a/src/cmp.c
+++ b/src/cmp.c
@@ -28,7 +28,6 @@
#include <exitfail.h>
#include <file-type.h>
#include <getopt.h>
-#include <hard-locale.h>
#include <progname.h>
#include <quote.h>
#include <unlocked-io.h>
@@ -50,7 +49,8 @@ static bool
hard_locale_LC_MESSAGES (void)
{
#if defined LC_MESSAGES && ENABLE_NLS
- return hard_locale (LC_MESSAGES);
+ static char const copyright_string[] = "(C)";
+ return gettext (copyright_string) != copyright_string;
#else
return false;
#endif
diff --git a/src/diff.c b/src/diff.c
index 241e17c..8fd2e1a 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -35,7 +35,7 @@
#include <filenamecat.h>
#include <fnmatch.h>
#include <getopt.h>
-#include <hard-locale.h>
+#include <strftime.h>
#include <progname.h>
#include <quote.h>
#include <sh-quote.h>
@@ -293,6 +293,21 @@ exclude_options (void)
{
return EXCLUDE_WILDCARDS | (ignore_file_name_case ? FNM_CASEFOLD : 0);
}
+
+/* Return true if in a hard LC_TIME locale. */
+static bool
+hard_locale_LC_TIME (void)
+{
+ /* Use the heuristic that %c has its usual POSIX meaning.
+ This is good enough in practice. */
+ static struct tm const tm
+ = { .tm_year = 1970 - 1900, .tm_mon = 0, .tm_mday = 1,
+ .tm_hour = 23, .tm_min = 59, .tm_sec = 59 };
+ static char const expected[] = "Thu Jan 1 23:59:59 1970";
+ char buf[sizeof expected];
+ return (nstrftime (buf, sizeof buf, "%c", &tm, 0, 0) == sizeof buf - 1
+ && memcmp (buf, expected, sizeof buf) == 0);
+}
int
main (int argc, char **argv)
@@ -747,7 +762,7 @@ main (int argc, char **argv)
specify_style (OUTPUT_NORMAL);
}
- if (output_style != OUTPUT_CONTEXT || hard_locale (LC_TIME))
+ if (output_style != OUTPUT_CONTEXT || hard_locale_LC_TIME ())
{
#if defined STAT_TIMESPEC || defined STAT_TIMESPEC_NS
time_format = "%Y-%m-%d %H:%M:%S.%N %z";
--
2.48.1