diff --git a/tools/gnulib/Makefile b/tools/gnulib/Makefile index 1237fad46e1..30c070eeb92 100644 --- a/tools/gnulib/Makefile +++ b/tools/gnulib/Makefile @@ -4,9 +4,9 @@ PKG_NAME:=gnulib PKG_CPE_ID:=cpe:/a:gnu:$(PKG_NAME) PKG_SOURCE_URL=git://git.git.savannah.gnu.org/$(PKG_NAME).git -PKG_SOURCE_DATE:=2025-07-01 -PKG_SOURCE_VERSION:=a3151d456d6919c9066b54dc6f680452168165cf# # stable-202501 -PKG_MIRROR_HASH:=b695d96e915ecd6c4551436f417cb2c0879aef4ef6318721c8d5cc86cb44ba9d +PKG_SOURCE_DATE:=2026-07-04 +PKG_SOURCE_VERSION:=b22f5a3037712a3c957a03071ce0b219cef4d65b# # stable-202507 +PKG_MIRROR_HASH:=d1423a784794e3e08bd03b397544821ece257aa748566386bd97219d1edf98d5 include $(INCLUDE_DIR)/host-build.mk diff --git a/tools/gnulib/patches/000-bootstrap.patch b/tools/gnulib/patches/000-bootstrap.patch index 8d032ac080d..71ae8c3047d 100644 --- a/tools/gnulib/patches/000-bootstrap.patch +++ b/tools/gnulib/patches/000-bootstrap.patch @@ -1,6 +1,6 @@ --- a/build-aux/bootstrap +++ b/build-aux/bootstrap -@@ -237,14 +237,14 @@ test -r "$conffile" && . "$conffile" +@@ -241,14 +241,14 @@ test -r "$conffile" && . "$conffile" check_exists() { if test "$1" = "--verbose"; then @@ -18,7 +18,7 @@ fi test $? -lt 126 -@@ -309,7 +309,7 @@ p +@@ -313,7 +313,7 @@ p q' get_version() { @@ -27,7 +27,7 @@ $app --version >/dev/null 2>&1 || { $app --version; return 1; } -@@ -366,13 +366,13 @@ check_versions() { +@@ -370,13 +370,13 @@ check_versions() { if [ "$req_ver" = "-" ]; then # Merely require app to exist; not all prereq apps are well-behaved # so we have to rely on $? rather than get_version. @@ -43,7 +43,7 @@ if [ ! "$inst_ver" ]; then warn_ "Error: '$app' not found" ret=1 -@@ -1205,7 +1205,7 @@ autogen() +@@ -1223,7 +1223,7 @@ autogen() # two just-pre-run programs. # Import from gettext. diff --git a/tools/gnulib/patches/010-autoconf-version.patch b/tools/gnulib/patches/010-autoconf-version.patch index ff0d795a614..ced2c7189b0 100644 --- a/tools/gnulib/patches/010-autoconf-version.patch +++ b/tools/gnulib/patches/010-autoconf-version.patch @@ -35,7 +35,7 @@ # func_version # outputs to stdout the --version message. func_version () -@@ -1666,6 +1694,9 @@ func_determine_path_separator +@@ -1673,6 +1701,9 @@ func_determine_path_separator fi case "$autoconf_minversion" in 1.* | 2.[0-5]* | 2.6[0-3]*) diff --git a/tools/gnulib/patches/120-unmangle-darwin-fts-h.patch b/tools/gnulib/patches/120-unmangle-darwin-fts-h.patch index 19e46b91038..70f54136df1 100644 --- a/tools/gnulib/patches/120-unmangle-darwin-fts-h.patch +++ b/tools/gnulib/patches/120-unmangle-darwin-fts-h.patch @@ -1,19 +1,53 @@ ---- /dev/null -+++ b/lib/fts.h -@@ -0,0 +1,6 @@ -+#ifdef __APPLE__ -+# define _FTS_H_ 1 -+# include -+#else -+# include_next -+#endif +--- a/lib/fts.c ++++ b/lib/fts.c +@@ -50,7 +50,7 @@ + static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94"; + #endif + +-#include "fts_.h" ++#include "fts.h" + + #if HAVE_SYS_PARAM_H || defined _LIBC + # include +--- a/lib/fts.in.h ++++ b/lib/fts.in.h +@@ -48,6 +48,11 @@ + + #ifndef _FTS_H + # define _FTS_H 1 ++# ifdef __APPLE__ ++# ifndef _FTS_H_ ++# define _FTS_H_ 1 ++# endif ++# endif + + /* This file uses _GL_ATTRIBUTE_DEALLOC, _GL_ATTRIBUTE_NODISCARD. */ + # if !_LIBC && !_GL_CONFIG_H_INCLUDED --- a/modules/fts +++ b/modules/fts -@@ -2,6 +2,7 @@ Description: - Traverse a file hierarchy. +@@ -48,21 +48,21 @@ dnl NetBSD versions have bugs and/or unn + gl_CONDITIONAL([GL_COND_OBJ_FTS], [true]) - Files: -+lib/fts.h - lib/fts_.h - lib/fts.c - lib/fts-cycle.c + Makefile.am: +-BUILT_SOURCES += fts_.h ++BUILT_SOURCES += fts.h + if GL_COND_OBJ_FTS + lib_SOURCES += fts.c + endif + +-fts_.h: fts.in.h ++fts.h: fts.in.h + @NMD@ $(AM_V_GEN)$(MKDIR_P) '%reldir%' + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''HAVE_SYS_CDEFS_H''@|$(HAVE_SYS_CDEFS_H)|g' \ + $(srcdir)/fts.in.h > $@-t + $(AM_V_at)mv $@-t $@ +-MOSTLYCLEANFILES += fts_.h fts_.h-t ++MOSTLYCLEANFILES += fts.h fts.h-t + + Include: +-"fts_.h" ++"fts.h" + + License: + GPL diff --git a/tools/gnulib/patches/160-flag-reallocarray.patch b/tools/gnulib/patches/160-flag-reallocarray.patch index 7c88c0de374..67a5f51b087 100644 --- a/tools/gnulib/patches/160-flag-reallocarray.patch +++ b/tools/gnulib/patches/160-flag-reallocarray.patch @@ -20,7 +20,7 @@ #endif --- a/lib/xmalloc.c +++ b/lib/xmalloc.c -@@ -51,12 +51,16 @@ ximalloc (idx_t s) +@@ -57,12 +57,16 @@ ximalloc (idx_t s) return check_nonnull (imalloc (s)); } @@ -37,7 +37,7 @@ /* Change the size of an allocated block of memory P to S bytes, with error checking. */ -@@ -75,6 +79,8 @@ xirealloc (void *p, idx_t s) +@@ -81,6 +85,8 @@ xirealloc (void *p, idx_t s) return check_nonnull (irealloc (p, s)); } @@ -46,7 +46,7 @@ /* Change the size of an allocated block of memory P to an array of N objects each of S bytes, with error checking. */ -@@ -205,6 +211,8 @@ x2nrealloc (void *p, size_t *pn, size_t +@@ -211,6 +217,8 @@ x2nrealloc (void *p, size_t *pn, size_t return p; } @@ -139,7 +139,7 @@ static void addtok_wc (struct dfa *dfa, wint_t wc); /* Add the given token to the parse tree, maintaining the depth count and -@@ -2934,6 +2938,8 @@ dfaanalyze (struct dfa *d, bool searchfl +@@ -2935,6 +2939,8 @@ dfaanalyze (struct dfa *d, bool searchfl free (tmp.elems); } @@ -148,7 +148,7 @@ /* Make sure D's state arrays are large enough to hold NEW_STATE. */ static void realloc_trans_if_necessary (struct dfa *d) -@@ -2969,6 +2975,8 @@ realloc_trans_if_necessary (struct dfa * +@@ -2970,6 +2976,8 @@ realloc_trans_if_necessary (struct dfa * } } @@ -157,7 +157,7 @@ /* Calculate the transition table for a new state derived from state s for a compiled dfa d after input character uc, and return the new -@@ -4010,6 +4018,8 @@ freelist (char **cpp) +@@ -4011,6 +4019,8 @@ freelist (char **cpp) free (*cpp++); } @@ -166,7 +166,7 @@ static char ** enlistnew (char **cpp, char *new) { -@@ -4046,6 +4056,8 @@ enlist (char **cpp, char const *str, idx +@@ -4047,6 +4057,8 @@ enlist (char **cpp, char const *str, idx return enlistnew (cpp, ximemdup0 (str, len)); } diff --git a/tools/gnulib/patches/200-force-disable-after-configure.patch b/tools/gnulib/patches/200-force-disable-after-configure.patch index 082820a3446..92590a4e6e8 100644 --- a/tools/gnulib/patches/200-force-disable-after-configure.patch +++ b/tools/gnulib/patches/200-force-disable-after-configure.patch @@ -1,6 +1,6 @@ --- a/lib/fcntl.c +++ b/lib/fcntl.c -@@ -198,6 +198,8 @@ static int klibc_fcntl (int fd, int acti +@@ -197,6 +197,8 @@ static int klibc_fcntl (int fd, int acti FD_CLOEXEC is portable, but other flags may be present); otherwise return -1 and set errno. */ @@ -9,7 +9,7 @@ int fcntl (int fd, int action, /* arg */...) #undef fcntl -@@ -443,6 +445,8 @@ fcntl (int fd, int action, /* arg */...) +@@ -442,6 +444,8 @@ fcntl (int fd, int action, /* arg */...) return result; } @@ -20,7 +20,7 @@ { --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h -@@ -1549,11 +1549,17 @@ _GL_FUNCDECL_RPL (reallocarray, void *, +@@ -1577,11 +1577,17 @@ _GL_FUNCDECL_RPL (reallocarray, void *, _GL_ATTRIBUTE_NODISCARD); _GL_CXXALIAS_RPL (reallocarray, void *, (void *ptr, size_t nmemb, size_t size)); diff --git a/tools/gnulib/patches/320-modules-fallocate-posix.patch b/tools/gnulib/patches/320-modules-fallocate-posix.patch index 4cfd5bdcd64..5391f8aca5a 100644 --- a/tools/gnulib/patches/320-modules-fallocate-posix.patch +++ b/tools/gnulib/patches/320-modules-fallocate-posix.patch @@ -127,7 +127,7 @@ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ --- a/lib/fcntl.in.h +++ b/lib/fcntl.in.h -@@ -241,6 +241,33 @@ _GL_WARN_ON_USE (openat, "openat is not +@@ -249,6 +249,33 @@ _GL_WARN_ON_USE (openat, "openat is not # endif #endif diff --git a/tools/gnulib/patches/640-mem-hash-map.patch b/tools/gnulib/patches/640-mem-hash-map.patch deleted file mode 100644 index aaebe545fa9..00000000000 --- a/tools/gnulib/patches/640-mem-hash-map.patch +++ /dev/null @@ -1,494 +0,0 @@ -From 5a842672e79a7a5f6be837c483be4f9901a4ecc0 Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Wed, 30 Apr 2025 03:19:10 +0200 -Subject: [PATCH] New module mem-hash-map. - -* lib/mem-hash-map.h: New file, from GNU gettext. -* lib/mem-hash-map.c: New file, from GNU gettext. -* modules/mem-hash-map: New file, from GNU gettext. ---- - ChangeLog | 7 + - lib/mem-hash-map.c | 352 +++++++++++++++++++++++++++++++++++++++++++ - lib/mem-hash-map.h | 90 +++++++++++ - modules/mem-hash-map | 25 +++ - 4 files changed, 474 insertions(+) - create mode 100644 lib/mem-hash-map.c - create mode 100644 lib/mem-hash-map.h - create mode 100644 modules/mem-hash-map - ---- /dev/null -+++ b/lib/mem-hash-map.c -@@ -0,0 +1,352 @@ -+/* Simple hash table (no removals) where the keys are memory blocks. -+ Copyright (C) 1994-2025 Free Software Foundation, Inc. -+ Written by Ulrich Drepper , October 1994. -+ -+ This file 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 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 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 . */ -+ -+#include -+ -+/* Specification. */ -+#include "mem-hash-map.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "next-prime.h" -+ -+/* Since this simple implementation of hash tables allows only insertion, no -+ removal of entries, the right data structure for the memory holding all keys -+ is an obstack. */ -+#include "obstack.h" -+ -+/* Use checked memory allocation. */ -+#include "xalloc.h" -+ -+#define obstack_chunk_alloc xmalloc -+#define obstack_chunk_free free -+ -+ -+typedef struct hash_entry -+{ -+ size_t used; /* Hash code of the key, or 0 for an unused entry. */ -+ const void *key; /* Key. */ -+ size_t keylen; -+ void *data; /* Value. */ -+ struct hash_entry *next; -+} -+hash_entry; -+ -+ -+/* Initialize a hash table. INIT_SIZE > 1 is the initial number of available -+ entries. -+ Return 0 always. */ -+int -+hash_init (hash_table *htab, size_t init_size) -+{ -+ /* We need the size to be a prime. */ -+ init_size = next_prime (init_size); -+ -+ /* Initialize the data structure. */ -+ htab->size = init_size; -+ htab->filled = 0; -+ htab->first = NULL; -+ htab->table = XCALLOC (init_size + 1, hash_entry); -+ -+ obstack_init (&htab->mem_pool); -+ -+ return 0; -+} -+ -+ -+/* Delete a hash table's contents. -+ Return 0 always. */ -+int -+hash_destroy (hash_table *htab) -+{ -+ free (htab->table); -+ obstack_free (&htab->mem_pool, NULL); -+ return 0; -+} -+ -+ -+/* Compute a hash code for a key consisting of KEYLEN bytes starting at KEY -+ in memory. */ -+static size_t -+compute_hashval (const void *key, size_t keylen) -+{ -+ size_t cnt; -+ size_t hval; -+ -+ /* Compute the hash value for the given string. The algorithm -+ is taken from [Aho,Sethi,Ullman], fixed according to -+ https://haible.de/bruno/hashfunc.html. */ -+ cnt = 0; -+ hval = keylen; -+ while (cnt < keylen) -+ { -+ hval = (hval << 9) | (hval >> (sizeof (size_t) * CHAR_BIT - 9)); -+ hval += (size_t) *(((const char *) key) + cnt++); -+ } -+ return hval != 0 ? hval : ~((size_t) 0); -+} -+ -+ -+/* References: -+ [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986 -+ [Knuth] The Art of Computer Programming, part3 (6.4) */ -+ -+/* Look up a given key in the hash table. -+ Return the index of the entry, if present, or otherwise the index a free -+ entry where it could be inserted. */ -+static size_t -+lookup (const hash_table *htab, -+ const void *key, size_t keylen, -+ size_t hval) -+{ -+ size_t hash; -+ size_t idx; -+ hash_entry *table = htab->table; -+ -+ /* First hash function: simply take the modul but prevent zero. */ -+ hash = 1 + hval % htab->size; -+ -+ idx = hash; -+ -+ if (table[idx].used) -+ { -+ if (table[idx].used == hval && table[idx].keylen == keylen -+ && memcmp (table[idx].key, key, keylen) == 0) -+ return idx; -+ -+ /* Second hash function as suggested in [Knuth]. */ -+ hash = 1 + hval % (htab->size - 2); -+ -+ do -+ { -+ if (idx <= hash) -+ idx = htab->size + idx - hash; -+ else -+ idx -= hash; -+ -+ /* If entry is found use it. */ -+ if (table[idx].used == hval && table[idx].keylen == keylen -+ && memcmp (table[idx].key, key, keylen) == 0) -+ return idx; -+ } -+ while (table[idx].used); -+ } -+ return idx; -+} -+ -+ -+/* Look up the value of a key in the given table. -+ If found, return 0 and set *RESULT to it. Otherwise return -1. */ -+int -+hash_find_entry (const hash_table *htab, const void *key, size_t keylen, -+ void **result) -+{ -+ hash_entry *table = htab->table; -+ size_t idx = lookup (htab, key, keylen, compute_hashval (key, keylen)); -+ -+ if (table[idx].used == 0) -+ return -1; -+ -+ *result = table[idx].data; -+ return 0; -+} -+ -+ -+/* Insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table at index IDX. -+ HVAL is the key's hash code. IDX depends on it. The table entry at index -+ IDX is known to be unused. */ -+static void -+insert_entry_2 (hash_table *htab, -+ const void *key, size_t keylen, -+ size_t hval, size_t idx, void *data) -+{ -+ hash_entry *table = htab->table; -+ -+ table[idx].used = hval; -+ table[idx].key = key; -+ table[idx].keylen = keylen; -+ table[idx].data = data; -+ -+ /* List the new value in the list. */ -+ if (htab->first == NULL) -+ { -+ table[idx].next = &table[idx]; -+ htab->first = &table[idx]; -+ } -+ else -+ { -+ table[idx].next = htab->first->next; -+ htab->first->next = &table[idx]; -+ htab->first = &table[idx]; -+ } -+ -+ ++htab->filled; -+} -+ -+ -+/* Grow the hash table. */ -+static void -+resize (hash_table *htab) -+{ -+ size_t old_size = htab->size; -+ hash_entry *table = htab->table; -+ size_t idx; -+ -+ htab->size = next_prime (htab->size * 2); -+ htab->filled = 0; -+ htab->first = NULL; -+ htab->table = XCALLOC (1 + htab->size, hash_entry); -+ -+ for (idx = 1; idx <= old_size; ++idx) -+ if (table[idx].used) -+ insert_entry_2 (htab, table[idx].key, table[idx].keylen, -+ table[idx].used, -+ lookup (htab, table[idx].key, table[idx].keylen, -+ table[idx].used), -+ table[idx].data); -+ -+ free (table); -+} -+ -+ -+/* Try to insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table. -+ Return non-NULL (more precisely, the address of the KEY inside the table's -+ memory pool) if successful, or NULL if there is already an entry with the -+ given key. */ -+const void * -+hash_insert_entry (hash_table *htab, -+ const void *key, size_t keylen, -+ void *data) -+{ -+ size_t hval = compute_hashval (key, keylen); -+ hash_entry *table = htab->table; -+ size_t idx = lookup (htab, key, keylen, hval); -+ -+ if (table[idx].used) -+ /* We don't want to overwrite the old value. */ -+ return NULL; -+ else -+ { -+ /* An empty bucket has been found. */ -+ void *keycopy = obstack_copy (&htab->mem_pool, key, keylen); -+ insert_entry_2 (htab, keycopy, keylen, hval, idx, data); -+ if (100 * htab->filled > 75 * htab->size) -+ /* Table is filled more than 75%. Resize the table. */ -+ resize (htab); -+ return keycopy; -+ } -+} -+ -+ -+/* Insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table. -+ Return 0. */ -+int -+hash_set_value (hash_table *htab, -+ const void *key, size_t keylen, -+ void *data) -+{ -+ size_t hval = compute_hashval (key, keylen); -+ hash_entry *table = htab->table; -+ size_t idx = lookup (htab, key, keylen, hval); -+ -+ if (table[idx].used) -+ { -+ /* Overwrite the old value. */ -+ table[idx].data = data; -+ return 0; -+ } -+ else -+ { -+ /* An empty bucket has been found. */ -+ void *keycopy = obstack_copy (&htab->mem_pool, key, keylen); -+ insert_entry_2 (htab, keycopy, keylen, hval, idx, data); -+ if (100 * htab->filled > 75 * htab->size) -+ /* Table is filled more than 75%. Resize the table. */ -+ resize (htab); -+ return 0; -+ } -+} -+ -+ -+/* Steps *PTR forward to the next used entry in the given hash table. *PTR -+ should be initially set to NULL. Store information about the next entry -+ in *KEY, *KEYLEN, *DATA. -+ Return 0 normally, -1 when the whole hash table has been traversed. */ -+int -+hash_iterate (hash_table *htab, void **ptr, const void **key, size_t *keylen, -+ void **data) -+{ -+ hash_entry *curr; -+ -+ if (*ptr == NULL) -+ { -+ if (htab->first == NULL) -+ return -1; -+ curr = htab->first; -+ } -+ else -+ { -+ if (*ptr == htab->first) -+ return -1; -+ curr = (hash_entry *) *ptr; -+ } -+ curr = curr->next; -+ *ptr = (void *) curr; -+ -+ *key = curr->key; -+ *keylen = curr->keylen; -+ *data = curr->data; -+ return 0; -+} -+ -+ -+/* Steps *PTR forward to the next used entry in the given hash table. *PTR -+ should be initially set to NULL. Store information about the next entry -+ in *KEY, *KEYLEN, *DATAP. *DATAP is set to point to the storage of the -+ value; modifying **DATAP will modify the value of the entry. -+ Return 0 normally, -1 when the whole hash table has been traversed. */ -+int -+hash_iterate_modify (hash_table *htab, void **ptr, -+ const void **key, size_t *keylen, -+ void ***datap) -+{ -+ hash_entry *curr; -+ -+ if (*ptr == NULL) -+ { -+ if (htab->first == NULL) -+ return -1; -+ curr = htab->first; -+ } -+ else -+ { -+ if (*ptr == htab->first) -+ return -1; -+ curr = (hash_entry *) *ptr; -+ } -+ curr = curr->next; -+ *ptr = (void *) curr; -+ -+ *key = curr->key; -+ *keylen = curr->keylen; -+ *datap = &curr->data; -+ return 0; -+} ---- /dev/null -+++ b/lib/mem-hash-map.h -@@ -0,0 +1,90 @@ -+/* Simple hash table (no removals) where the keys are memory blocks. -+ Copyright (C) 1995-2025 Free Software Foundation, Inc. -+ -+ This file 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 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 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 . */ -+ -+#ifndef _GL_MEM_HASH_MAP_H -+#define _GL_MEM_HASH_MAP_H -+ -+#include -+ -+#include "obstack.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+struct hash_entry; -+ -+typedef struct hash_table -+{ -+ size_t size; /* Number of allocated entries. */ -+ size_t filled; /* Number of used entries. */ -+ struct hash_entry *first; /* Pointer to head of list of entries. */ -+ struct hash_entry *table; /* Pointer to array of entries. */ -+ struct obstack mem_pool; /* Memory pool holding the keys. */ -+} -+hash_table; -+ -+/* Initialize a hash table. INIT_SIZE > 1 is the initial number of available -+ entries. -+ Return 0 always. */ -+extern int hash_init (hash_table *htab, size_t init_size); -+ -+/* Delete a hash table's contents. -+ Return 0 always. */ -+extern int hash_destroy (hash_table *htab); -+ -+/* Look up the value of a key in the given table. -+ If found, return 0 and set *RESULT to it. Otherwise return -1. */ -+extern int hash_find_entry (const hash_table *htab, -+ const void *key, size_t keylen, -+ void **result); -+ -+/* Try to insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table. -+ Return non-NULL (more precisely, the address of the KEY inside the table's -+ memory pool) if successful, or NULL if there is already an entry with the -+ given key. */ -+extern const void * hash_insert_entry (hash_table *htab, -+ const void *key, size_t keylen, -+ void *data); -+ -+/* Insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table. -+ Return 0. */ -+extern int hash_set_value (hash_table *htab, -+ const void *key, size_t keylen, -+ void *data); -+ -+/* Steps *PTR forward to the next used entry in the given hash table. *PTR -+ should be initially set to NULL. Store information about the next entry -+ in *KEY, *KEYLEN, *DATA. -+ Return 0 normally, -1 when the whole hash table has been traversed. */ -+extern int hash_iterate (hash_table *htab, void **ptr, -+ const void **key, size_t *keylen, -+ void **data); -+ -+/* Steps *PTR forward to the next used entry in the given hash table. *PTR -+ should be initially set to NULL. Store information about the next entry -+ in *KEY, *KEYLEN, *DATAP. *DATAP is set to point to the storage of the -+ value; modifying **DATAP will modify the value of the entry. -+ Return 0 normally, -1 when the whole hash table has been traversed. */ -+extern int hash_iterate_modify (hash_table *htab, void **ptr, -+ const void **key, size_t *keylen, -+ void ***datap); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* not _GL_MEM_HASH_MAP_H */ ---- /dev/null -+++ b/modules/mem-hash-map -@@ -0,0 +1,25 @@ -+Description: -+Simple hash table (no removals) where the keys are memory blocks. -+ -+Files: -+lib/mem-hash-map.h -+lib/mem-hash-map.c -+ -+Depends-on: -+next-prime -+obstack -+xalloc -+ -+configure.ac: -+ -+Makefile.am: -+lib_SOURCES += mem-hash-map.h mem-hash-map.c -+ -+Include: -+"mem-hash-map.h" -+ -+License: -+GPL -+ -+Maintainer: -+Bruno Haible diff --git a/tools/gnulib/patches/645-next-prime.patch b/tools/gnulib/patches/645-next-prime.patch deleted file mode 100644 index 66f482f5ec5..00000000000 --- a/tools/gnulib/patches/645-next-prime.patch +++ /dev/null @@ -1,218 +0,0 @@ -From 0b953ba82830f51ce9b939700705d238f9b0c0ba Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Wed, 30 Apr 2025 01:52:17 +0200 -Subject: [PATCH] New module next-prime. - -* lib/next-prime.h: New file, based on lib/hash.c. -* lib/next-prime.c: New file, based on lib/hash.c. -* modules/next-prime: New file. -* lib/hash.c: Include next-prime.h. -(is_prime, next_prime): Remove functions. -* modules/hash (Depends-on): Add next-prime. ---- - ChangeLog | 10 +++++++++ - lib/hash.c | 39 +------------------------------- - lib/next-prime.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ - lib/next-prime.h | 41 +++++++++++++++++++++++++++++++++ - modules/hash | 1 + - modules/next-prime | 24 ++++++++++++++++++++ - 6 files changed, 133 insertions(+), 38 deletions(-) - create mode 100644 lib/next-prime.c - create mode 100644 lib/next-prime.h - create mode 100644 modules/next-prime - ---- a/lib/hash.c -+++ b/lib/hash.c -@@ -27,6 +27,7 @@ - #include "hash.h" - - #include "bitrotate.h" -+#include "next-prime.h" - #include "xalloc-oversized.h" - - #include -@@ -390,44 +391,6 @@ hash_string (const char *string, size_t - - #endif /* not USE_DIFF_HASH */ - --/* Return true if CANDIDATE is a prime number. CANDIDATE should be an odd -- number at least equal to 11. */ -- --static bool _GL_ATTRIBUTE_CONST --is_prime (size_t candidate) --{ -- size_t divisor = 3; -- size_t square = divisor * divisor; -- -- while (square < candidate && (candidate % divisor)) -- { -- divisor++; -- square += 4 * divisor; -- divisor++; -- } -- -- return (candidate % divisor ? true : false); --} -- --/* Round a given CANDIDATE number up to the nearest prime, and return that -- prime. Primes lower than 10 are merely skipped. */ -- --static size_t _GL_ATTRIBUTE_CONST --next_prime (size_t candidate) --{ -- /* Skip small primes. */ -- if (candidate < 10) -- candidate = 10; -- -- /* Make it definitely odd. */ -- candidate |= 1; -- -- while (SIZE_MAX != candidate && !is_prime (candidate)) -- candidate += 2; -- -- return candidate; --} -- - void - hash_reset_tuning (Hash_tuning *tuning) - { ---- /dev/null -+++ b/lib/next-prime.c -@@ -0,0 +1,56 @@ -+/* Finding the next prime >= a given small integer. -+ Copyright (C) 1995-2025 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 2.1 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 . */ -+ -+#include -+ -+/* Specification. */ -+#include "next-prime.h" -+ -+#include /* for SIZE_MAX */ -+ -+/* Return true if CANDIDATE is a prime number. CANDIDATE should be an odd -+ number at least equal to 11. */ -+static bool _GL_ATTRIBUTE_CONST -+is_prime (size_t candidate) -+{ -+ size_t divisor = 3; -+ size_t square = divisor * divisor; -+ -+ while (square < candidate && (candidate % divisor)) -+ { -+ divisor++; -+ square += 4 * divisor; -+ divisor++; -+ } -+ -+ return (candidate % divisor ? true : false); -+} -+ -+size_t _GL_ATTRIBUTE_CONST -+next_prime (size_t candidate) -+{ -+ /* Skip small primes. */ -+ if (candidate < 10) -+ candidate = 10; -+ -+ /* Make it definitely odd. */ -+ candidate |= 1; -+ -+ while (SIZE_MAX != candidate && !is_prime (candidate)) -+ candidate += 2; -+ -+ return candidate; -+} ---- /dev/null -+++ b/lib/next-prime.h -@@ -0,0 +1,41 @@ -+/* Finding the next prime >= a given small integer. -+ Copyright (C) 1995-2025 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 2.1 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 . */ -+ -+#ifndef _GL_NEXT_PRIME_H -+#define _GL_NEXT_PRIME_H -+ -+/* This file uses _GL_ATTRIBUTE_CONST. */ -+#if !_GL_CONFIG_H_INCLUDED -+ #error "Please include config.h first." -+#endif -+ -+#include -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+ -+/* Round a given CANDIDATE number up to the nearest prime, and return that -+ prime. Primes lower than 10 are merely skipped. */ -+extern size_t _GL_ATTRIBUTE_CONST next_prime (size_t candidate); -+ -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* _GL_NEXT_PRIME_H */ ---- a/modules/hash -+++ b/modules/hash -@@ -10,6 +10,7 @@ bitrotate - calloc-posix - free-posix - malloc-posix -+next-prime - bool - stdint-h - xalloc-oversized ---- /dev/null -+++ b/modules/next-prime -@@ -0,0 +1,24 @@ -+Description: -+Finding the next prime >= a given small integer. -+ -+Files: -+lib/next-prime.h -+lib/next-prime.c -+ -+Depends-on: -+bool -+stdint-h -+ -+configure.ac: -+ -+Makefile.am: -+lib_SOURCES += next-prime.h next-prime.c -+ -+Include: -+"next-prime.h" -+ -+License: -+LGPLv2+ -+ -+Maintainer: -+all diff --git a/tools/gnulib/patches/646-hashcode-string.patch b/tools/gnulib/patches/646-hashcode-string.patch deleted file mode 100644 index ee2ebd237f1..00000000000 --- a/tools/gnulib/patches/646-hashcode-string.patch +++ /dev/null @@ -1,294 +0,0 @@ -From 64042bb91aea5f854ca8a8938e2b3f7d1935e4f1 Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Wed, 30 Apr 2025 12:47:37 +0200 -Subject: [PATCH] New module hashcode-string1. - -* lib/hashcode-string1.h: New file. -* lib/hashcode-string1.c: New file, based on lib/hash.c. -* modules/hashcode-string1: New file. -* lib/hash.h: Include hashcode-string1.h. -(hash_string): Remove declaration. -* lib/hash.c (hash_string): Remove function. -* modules/hash (Depends-on): Add hashcode-string1. -* lib/exclude.c: Include hashcode-string1.h. -* modules/exclude (Depends-on): Add hashcode-string1. ---- - ChangeLog | 13 +++++++++ - lib/exclude.c | 1 + - lib/hash.c | 59 ++++++-------------------------------- - lib/hash.h | 11 +++---- - lib/hashcode-string1.c | 62 ++++++++++++++++++++++++++++++++++++++++ - lib/hashcode-string1.h | 38 ++++++++++++++++++++++++ - modules/exclude | 1 + - modules/hash | 1 + - modules/hashcode-string1 | 24 ++++++++++++++++ - 9 files changed, 154 insertions(+), 56 deletions(-) - create mode 100644 lib/hashcode-string1.c - create mode 100644 lib/hashcode-string1.h - create mode 100644 modules/hashcode-string1 - ---- a/lib/exclude.c -+++ b/lib/exclude.c -@@ -36,6 +36,7 @@ - #include "filename.h" - #include - #include "hash.h" -+#include "hashcode-string1.h" - #if GNULIB_MCEL_PREFER - # include "mcel.h" - #else ---- a/lib/hash.c -+++ b/lib/hash.c -@@ -345,57 +345,6 @@ hash_do_for_each (const Hash_table *tabl - return counter; - } - --/* Allocation and clean-up. */ -- --#if USE_DIFF_HASH -- --/* About hashings, Paul Eggert writes to me (FP), on 1994-01-01: "Please see -- B. J. McKenzie, R. Harries & T. Bell, Selecting a hashing algorithm, -- Software--practice & experience 20, 2 (Feb 1990), 209-224. Good hash -- algorithms tend to be domain-specific, so what's good for [diffutils'] io.c -- may not be good for your application." */ -- --size_t --hash_string (const char *string, size_t n_buckets) --{ --# define HASH_ONE_CHAR(Value, Byte) \ -- ((Byte) + rotl_sz (Value, 7)) -- -- size_t value = 0; -- unsigned char ch; -- -- for (; (ch = *string); string++) -- value = HASH_ONE_CHAR (value, ch); -- return value % n_buckets; -- --# undef HASH_ONE_CHAR --} -- --#else /* not USE_DIFF_HASH */ -- --/* This one comes from 'recode', and performs a bit better than the above as -- per a few experiments. It is inspired from a hashing routine found in the -- very old Cyber 'snoop', itself written in typical Greg Mansfield style. -- (By the way, what happened to this excellent man? Is he still alive?) */ -- --size_t --hash_string (const char *string, size_t n_buckets) --{ -- size_t value = 0; -- unsigned char ch; -- -- for (; (ch = *string); string++) -- value = (value * 31 + ch) % n_buckets; -- return value; --} -- --#endif /* not USE_DIFF_HASH */ -- --void --hash_reset_tuning (Hash_tuning *tuning) --{ -- *tuning = default_tuning; --} - - /* If the user passes a NULL hasher, we hash the raw pointer. */ - static size_t -@@ -418,6 +367,14 @@ raw_comparator (const void *a, const voi - } - - -+/* Allocation and clean-up. */ -+ -+void -+hash_reset_tuning (Hash_tuning *tuning) -+{ -+ *tuning = default_tuning; -+} -+ - /* For the given hash TABLE, check the user supplied tuning structure for - reasonable values, and return true if there is no gross error with it. - Otherwise, definitively reset the TUNING field to some acceptable default ---- a/lib/hash.h -+++ b/lib/hash.h -@@ -134,11 +134,6 @@ extern size_t hash_do_for_each (const Ha - * Allocation and clean-up. - */ - --/* Return a hash index for a NUL-terminated STRING between 0 and N_BUCKETS-1. -- This is a convenience routine for constructing other hashing functions. */ --extern size_t hash_string (const char *string, size_t n_buckets) -- _GL_ATTRIBUTE_PURE; -- - extern void hash_reset_tuning (Hash_tuning *tuning); - - typedef size_t (*Hash_hasher) (const void *entry, size_t table_size); -@@ -266,6 +261,12 @@ extern void *hash_remove (Hash_table *ta - _GL_ATTRIBUTE_DEPRECATED - extern void *hash_delete (Hash_table *table, const void *entry); - -+ -+# if GNULIB_HASHCODE_STRING1 -+/* Include declarations of module 'hashcode-string1'. */ -+# include "hashcode-string1.h" -+# endif -+ - # ifdef __cplusplus - } - # endif ---- /dev/null -+++ b/lib/hashcode-string1.c -@@ -0,0 +1,62 @@ -+/* hashcode-string1.c -- compute a hash value from a NUL-terminated string. -+ -+ Copyright (C) 1998-2004, 2006-2007, 2009-2025 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 2.1 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 . */ -+ -+#include -+ -+/* Specification. */ -+#include "hashcode-string1.h" -+ -+#if USE_DIFF_HASH -+ -+# include "bitrotate.h" -+ -+/* About hashings, Paul Eggert writes to me (FP), on 1994-01-01: "Please see -+ B. J. McKenzie, R. Harries & T. Bell, Selecting a hashing algorithm, -+ Software--practice & experience 20, 2 (Feb 1990), 209-224. Good hash -+ algorithms tend to be domain-specific, so what's good for [diffutils'] io.c -+ may not be good for your application." */ -+ -+size_t -+hash_string (const char *string, size_t tablesize) -+{ -+ size_t value = 0; -+ unsigned char ch; -+ -+ for (; (ch = *string); string++) -+ value = ch + rotl_sz (value, 7); -+ return value % tablesize; -+} -+ -+#else /* not USE_DIFF_HASH */ -+ -+/* This one comes from 'recode', and performs a bit better than the above as -+ per a few experiments. It is inspired from a hashing routine found in the -+ very old Cyber 'snoop', itself written in typical Greg Mansfield style. -+ (By the way, what happened to this excellent man? Is he still alive?) */ -+ -+size_t -+hash_string (const char *string, size_t tablesize) -+{ -+ size_t value = 0; -+ unsigned char ch; -+ -+ for (; (ch = *string); string++) -+ value = (value * 31 + ch) % tablesize; -+ return value; -+} -+ -+#endif /* not USE_DIFF_HASH */ ---- /dev/null -+++ b/lib/hashcode-string1.h -@@ -0,0 +1,38 @@ -+/* hashcode-string1.h -- declaration for a simple hash function -+ Copyright (C) 1998-2004, 2006-2007, 2009-2025 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 2.1 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 . */ -+ -+/* This file uses _GL_ATTRIBUTE_PURE. */ -+#if !_GL_CONFIG_H_INCLUDED -+ #error "Please include config.h first." -+#endif -+ -+#include -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+ -+/* Compute a hash code for a NUL-terminated string S, -+ and return the hash code modulo TABLESIZE. -+ The result is platform dependent: it depends on the size of the 'size_t' -+ type. */ -+extern size_t hash_string (char const *s, size_t tablesize) _GL_ATTRIBUTE_PURE; -+ -+ -+#ifdef __cplusplus -+} -+#endif ---- a/modules/exclude -+++ b/modules/exclude -@@ -12,6 +12,7 @@ filename - fnmatch - fopen-gnu - hash -+hashcode-string1 - mbscasecmp - mbuiter [test "$GNULIB_MCEL_PREFER" != yes] - nullptr ---- a/modules/hash -+++ b/modules/hash -@@ -14,6 +14,7 @@ next-prime - bool - stdint-h - xalloc-oversized -+hashcode-string1 - - configure.ac: - ---- /dev/null -+++ b/modules/hashcode-string1 -@@ -0,0 +1,24 @@ -+Description: -+Compute a hash value for a NUL-terminated string. -+ -+Files: -+lib/hashcode-string1.h -+lib/hashcode-string1.c -+ -+Depends-on: -+bitrotate -+ -+configure.ac: -+gl_MODULE_INDICATOR([hashcode-string1]) -+ -+Makefile.am: -+lib_SOURCES += hashcode-string1.h hashcode-string1.c -+ -+Include: -+"hashcode-string1.h" -+ -+License: -+LGPLv2+ -+ -+Maintainer: -+Jim Meyering diff --git a/tools/gnulib/patches/647-hashkey-string.patch b/tools/gnulib/patches/647-hashkey-string.patch deleted file mode 100644 index d0cd0a6311a..00000000000 --- a/tools/gnulib/patches/647-hashkey-string.patch +++ /dev/null @@ -1,215 +0,0 @@ -From 52738dcd0f522b16653cc8b21adfcb758702f2ab Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Wed, 30 Apr 2025 01:20:17 +0200 -Subject: [PATCH] New module hashkey-string. - -* lib/hashkey-string.h: New file. -* lib/hashkey-string.c: New file, based on lib/clean-temp-simple.c. -* modules/hashkey-string: New file. -* lib/clean-temp-simple.c: Include hashkey-string.h. Don't include -. -(clean_temp_string_equals, clean_temp_string_hash): Remove functions. -(SIZE_BITS): Remove macro. -(register_temporary_file): Use hashkey_string_equals and -hashkey_string_hash. -* modules/clean-temp-simple (Depends-on): Add hashkey-string. ---- - ChangeLog | 14 ++++++++++++ - lib/clean-temp-simple.c | 33 +++------------------------ - lib/hashkey-string.c | 48 +++++++++++++++++++++++++++++++++++++++ - lib/hashkey-string.h | 35 ++++++++++++++++++++++++++++ - modules/clean-temp-simple | 1 + - modules/hashkey-string | 23 +++++++++++++++++++ - 6 files changed, 124 insertions(+), 30 deletions(-) - create mode 100644 lib/hashkey-string.c - create mode 100644 lib/hashkey-string.h - create mode 100644 modules/hashkey-string - ---- a/lib/clean-temp-simple.c -+++ b/lib/clean-temp-simple.c -@@ -22,7 +22,6 @@ - #include "clean-temp-private.h" - - #include --#include - #include - #include - #include -@@ -36,6 +35,7 @@ - #include "thread-optim.h" - #include "gl_list.h" - #include "gl_linkedhash_list.h" -+#include "hashkey-string.h" - #include "gettext.h" - - #define _(msgid) dgettext ("gnulib", msgid) -@@ -106,33 +106,6 @@ gl_list_t /* */ volatil - asynchronous signal. - */ - --/* String equality and hash code functions used by the lists. */ -- --bool --clean_temp_string_equals (const void *x1, const void *x2) --{ -- const char *s1 = (const char *) x1; -- const char *s2 = (const char *) x2; -- return strcmp (s1, s2) == 0; --} -- --#define SIZE_BITS (sizeof (size_t) * CHAR_BIT) -- --/* A hash function for NUL-terminated char* strings using -- the method described by Bruno Haible. -- See https://www.haible.de/bruno/hashfunc.html. */ --size_t --clean_temp_string_hash (const void *x) --{ -- const char *s = (const char *) x; -- size_t h = 0; -- -- for (; *s; s++) -- h = *s + ((h << 9) | (h >> (SIZE_BITS - 9))); -- -- return h; --} -- - - /* The set of fatal signal handlers. - Cached here because we are not allowed to call get_fatal_signal_set () -@@ -326,8 +299,8 @@ register_temporary_file (const char *abs - } - file_cleanup_list = - gl_list_nx_create_empty (GL_LINKEDHASH_LIST, -- clean_temp_string_equals, -- clean_temp_string_hash, -+ hashkey_string_equals, -+ hashkey_string_hash, - NULL, false); - if (file_cleanup_list == NULL) - { ---- /dev/null -+++ b/lib/hashkey-string.c -@@ -0,0 +1,48 @@ -+/* Support for using a string as a hash key. -+ Copyright (C) 2006-2025 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 2.1 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 . */ -+ -+#include -+ -+/* Specification. */ -+#include "hashkey-string.h" -+ -+#include -+#include -+ -+bool -+hashkey_string_equals (const void *x1, const void *x2) -+{ -+ const char *s1 = (const char *) x1; -+ const char *s2 = (const char *) x2; -+ return strcmp (s1, s2) == 0; -+} -+ -+#define SIZE_BITS (sizeof (size_t) * CHAR_BIT) -+ -+/* A hash function for NUL-terminated 'const char *' strings using -+ the method described by Bruno Haible. -+ See https://www.haible.de/bruno/hashfunc.html. */ -+size_t -+hashkey_string_hash (const void *x) -+{ -+ const char *s = (const char *) x; -+ size_t h = 0; -+ -+ for (; *s; s++) -+ h = *s + ((h << 9) | (h >> (SIZE_BITS - 9))); -+ -+ return h; -+} ---- /dev/null -+++ b/lib/hashkey-string.h -@@ -0,0 +1,35 @@ -+/* Support for using a string as a hash key. -+ Copyright (C) 2006-2025 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 2.1 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 . */ -+ -+#ifndef _GL_HASHKEY_STRING_H -+#define _GL_HASHKEY_STRING_H -+ -+#include -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* String equality and hash code functions that operate on plain C strings -+ ('const char *'). */ -+extern bool hashkey_string_equals (const void *x1, const void *x2); -+extern size_t hashkey_string_hash (const void *x); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* _GL_HASHKEY_STRING_H */ ---- a/modules/clean-temp-simple -+++ b/modules/clean-temp-simple -@@ -19,6 +19,7 @@ error - fatal-signal - rmdir - linkedhash-list -+hashkey-string - gettext-h - gnulib-i18n - ---- /dev/null -+++ b/modules/hashkey-string -@@ -0,0 +1,23 @@ -+Description: -+Support for using a string as a hash key in the hash-set and hash-map modules. -+ -+Files: -+lib/hashkey-string.h -+lib/hashkey-string.c -+ -+Depends-on: -+bool -+ -+configure.ac: -+ -+Makefile.am: -+lib_SOURCES += hashkey-string.h hashkey-string.c -+ -+Include: -+"hashkey-string.h" -+ -+License: -+LGPLv2+ -+ -+Maintainer: -+all diff --git a/tools/gnulib/patches/650-package-version.patch b/tools/gnulib/patches/650-package-version.patch deleted file mode 100644 index 2e3e0467361..00000000000 --- a/tools/gnulib/patches/650-package-version.patch +++ /dev/null @@ -1,176 +0,0 @@ -From e518788ad085e02b046e42889039a1f671e4619a Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Wed, 22 Jan 2025 21:21:59 +0100 -Subject: New module 'package-version'. - -* m4/init-package-version.m4: New file, from GNU libunistring. -* modules/package-version: New file. -* modules/git-version-gen (Depends-on): Add it. ---- - ChangeLog | 7 +++ - m4/init-package-version.m4 | 124 +++++++++++++++++++++++++++++++++++++++++++++ - modules/git-version-gen | 1 + - modules/package-version | 19 +++++++ - 4 files changed, 151 insertions(+) - create mode 100644 m4/init-package-version.m4 - create mode 100644 modules/package-version - ---- /dev/null -+++ b/m4/init-package-version.m4 -@@ -0,0 +1,124 @@ -+# init-package-version.m4 -+# serial 3 -+dnl Copyright (C) 1992-2025 Free Software Foundation, Inc. -+dnl This file is free software, distributed under the terms of the GNU -+dnl General Public License. As a special exception to the GNU General -+dnl Public License, this file may be distributed as part of a program -+dnl that contains a configuration script generated by Autoconf, under -+dnl the same distribution terms as the rest of that program. -+ -+# Make it possible to pass version numbers extracted from a file in -+# $(srcdir) to autoconf. -+# -+# Autoconf insists on passing the package name and version number to -+# every generated .h file and every Makefile. This was a reasonable -+# design at times when a version number was changed only once a month. -+# Nowadays, people often assign a new version number once a week, or -+# even change it each time a 'git' commit is made. Regenerating all -+# the files that depend on configure.ac (aclocal.m4, configure, -+# config.status, config.h, all Makefiles) may take 15 minutes. These -+# delays can severely hamper development. -+# -+# An alternative is to store the version number in a file in $(srcdir) -+# that is separate from configure.ac. It can be a data file, a shell -+# script, a .m4 file, or other. The essential point is that the maintainer -+# is responsible for creating Makefile dependencies to this version file -+# for every file that needs to be rebuilt when the version changes. This -+# typically includes -+# - distributable documentation files that carry the version number, -+# but does not include -+# - aclocal.m4, configure, config.status, config.h, all Makefiles, -+# - executables. -+# -+# autoconf and automake make it hard to follow this approach: -+# -+# - If AC_INIT is used with arguments, there is a chicken-and-egg problem: -+# The arguments need to be read from a file in $(srcdir). The location -+# of $(srcdir) is only determined by AC_CONFIG_SRCDIR. AC_CONFIG_SRCDIR -+# can only appear after AC_INIT (otherwise aclocal gives an error: -+# "error: m4_defn: undefined macro: _m4_divert_diversion"). -+# Furthermore, the arguments passed to AC_INIT must be literals; for -+# example, the assignment to PACKAGE_VERSION looks like this: -+# [PACKAGE_VERSION=']AC_PACKAGE_VERSION['] -+# -+# - If AC_INIT is used without arguments: -+# Automake provides its own variables, PACKAGE and VERSION, and uses them -+# instead of PACKAGE_NAME and PACKAGE_VERSION that come from Autoconf. -+# - If AM_INIT_AUTOMAKE is used with two arguments, automake options -+# like 'silent-rules' cannot be specified. -+# - If AM_INIT_AUTOMAKE is used in its one-argument form or without -+# arguments at all, it triggers an error -+# "error: AC_INIT should be called with package and version arguments". -+# - If AM_INIT_AUTOMAKE is used in its one-argument form or without -+# arguments at all, and _AC_INIT_PACKAGE is used before it, with -+# the package and version number from the file as arguments, we get -+# a warning: "warning: AC_INIT: not a literal: $VERSION_NUMBER". -+# The arguments passed to _AC_INIT_PACKAGE must be literals. -+# -+# With the macro defined in this file, the approach can be coded like this: -+# -+# AC_INIT -+# AC_CONFIG_SRCDIR(WITNESS) -+# . $srcdir/../version.sh -+# gl_INIT_PACKAGE(PACKAGE, $VERSION_NUMBER) -+# AM_INIT_AUTOMAKE([OPTIONS]) -+# -+# and after changing version.sh, the developer can directly configure and build: -+# -+# make distclean -+# ./configure -+# make -+# -+# Some other packages use another approach: -+# -+# AC_INIT(PACKAGE, -+# m4_normalize(m4_esyscmd([. ./version.sh; echo $VERSION_NUMBER]))) -+# AC_CONFIG_SRCDIR(WITNESS) -+# AM_INIT_AUTOMAKE([OPTIONS]) -+# -+# but here, after changing version.sh, the developer must first regenerate the -+# configure file: -+# -+# make distclean -+# ./autogen.sh --skip-gnulib -+# ./configure -+# make -+# -+ -+# gl_INIT_PACKAGE(PACKAGE-NAME, VERSION) -+# -------------------------------------- -+# followed by an AM_INIT_AUTOMAKE invocation, -+# is like calling AM_INIT_AUTOMAKE(PACKAGE-NAME, VERSION) -+# except that it can use computed non-literal arguments. -+AC_DEFUN([gl_INIT_PACKAGE], -+[ -+ AC_BEFORE([$0], [AM_INIT_AUTOMAKE]) -+ dnl Redefine AM_INIT_AUTOMAKE. -+ m4_define([gl_AM_INIT_AUTOMAKE], -+ m4_bpatsubst(m4_dquote( -+ m4_bpatsubst(m4_dquote( -+ m4_bpatsubst(m4_dquote( -+ m4_defn([AM_INIT_AUTOMAKE])), -+ [AC_PACKAGE_NAME], [gl_INIT_DUMMY])), -+ [AC_PACKAGE_TARNAME], [gl_INIT_EMPTY])), -+ [AC_PACKAGE_VERSION], [gl_INIT_DUMMY]) -+ [AC_SUBST([PACKAGE], [$1]) -+ AC_SUBST([VERSION], [$2]) -+ ]) -+ m4_define([AM_INIT_AUTOMAKE], -+ m4_defn([gl_RPL_INIT_AUTOMAKE])) -+]) -+m4_define([gl_INIT_EMPTY], []) -+dnl Automake 1.16.4 no longer accepts an empty value for gl_INIT_DUMMY. -+dnl But a macro that later expands to empty works. -+m4_define([gl_INIT_DUMMY], [gl_INIT_DUMMY2]) -+m4_define([gl_INIT_DUMMY2], []) -+AC_DEFUN([gl_RPL_INIT_AUTOMAKE], [ -+ m4_ifval([$2], -+ [m4_fatal([After gl_INIT_PACKAGE, the two-argument form of AM_INIT_AUTOMAKE cannot be used.])]) -+ gl_AM_INIT_AUTOMAKE([$1 no-define]) -+ m4_if(m4_index([ $1 ], [ no-define ]), [-1], -+ [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) -+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]) -+ ]) -+]) ---- a/modules/git-version-gen -+++ b/modules/git-version-gen -@@ -5,6 +5,7 @@ Files: - build-aux/git-version-gen - - Depends-on: -+package-version - - configure.ac: - ---- /dev/null -+++ b/modules/package-version -@@ -0,0 +1,19 @@ -+Description: -+Support for a computed version string. -+ -+Files: -+m4/init-package-version.m4 -+ -+Depends-on: -+ -+configure.ac: -+ -+Makefile.am: -+ -+Include: -+ -+License: -+GPLed build tool -+ -+Maintainer: -+Bruno Haible diff --git a/tools/gnulib/patches/651-package-version-simplify.patch b/tools/gnulib/patches/651-package-version-simplify.patch deleted file mode 100644 index bed3e65c415..00000000000 --- a/tools/gnulib/patches/651-package-version-simplify.patch +++ /dev/null @@ -1,66 +0,0 @@ -From bb0f82be83d43db9cd77049be32ffd0b92ab5bb7 Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Fri, 24 Jan 2025 22:03:29 +0100 -Subject: package-version: Simplify its use. - -Reported by Basil L. Contovounesios in -. - -* doc/package-version.texi (Propagating the package version): Recommend -to pass the usual arguments to AC_INIT. -* m4/init-package-version.m4: Likewise. -(gl_INIT_PACKAGE): Define PACKAGE_VERSION and PACKAGE_STRING as needed. -(gl_RPL_INIT_AUTOMAKE): Improve quoting. ---- - ChangeLog | 11 +++++++++++ - doc/package-version.texi | 2 +- - m4/init-package-version.m4 | 20 ++++++++++++++------ - 3 files changed, 26 insertions(+), 7 deletions(-) - ---- a/m4/init-package-version.m4 -+++ b/m4/init-package-version.m4 -@@ -1,5 +1,5 @@ - # init-package-version.m4 --# serial 3 -+# serial 4 - dnl Copyright (C) 1992-2025 Free Software Foundation, Inc. - dnl This file is free software, distributed under the terms of the GNU - dnl General Public License. As a special exception to the GNU General -@@ -57,7 +57,7 @@ dnl the same distribution terms as the r - # - # With the macro defined in this file, the approach can be coded like this: - # --# AC_INIT -+# AC_INIT(PACKAGE, [dummy], [MORE OPTIONS]) - # AC_CONFIG_SRCDIR(WITNESS) - # . $srcdir/../version.sh - # gl_INIT_PACKAGE(PACKAGE, $VERSION_NUMBER) -@@ -102,8 +102,16 @@ AC_DEFUN([gl_INIT_PACKAGE], - [AC_PACKAGE_NAME], [gl_INIT_DUMMY])), - [AC_PACKAGE_TARNAME], [gl_INIT_EMPTY])), - [AC_PACKAGE_VERSION], [gl_INIT_DUMMY]) -- [AC_SUBST([PACKAGE], [$1]) -- AC_SUBST([VERSION], [$2]) -+ [dnl Set variables documented in Automake. -+ AC_SUBST([PACKAGE], [$1]) -+ AC_SUBST([VERSION], ["$2"]) -+ dnl Set variables documented in Autoconf. -+ AC_SUBST([PACKAGE_VERSION], ["$2"]) -+ AC_SUBST([PACKAGE_STRING], ["$1 $2"]) -+ AC_DEFINE_UNQUOTED([PACKAGE_VERSION], ["$2"], -+ [Define to the version of this package.]) -+ AC_DEFINE_UNQUOTED([PACKAGE_STRING], ["$1 $2"], -+ [Define to the full name and version of this package.]) - ]) - m4_define([AM_INIT_AUTOMAKE], - m4_defn([gl_RPL_INIT_AUTOMAKE])) -@@ -118,7 +126,7 @@ AC_DEFUN([gl_RPL_INIT_AUTOMAKE], [ - [m4_fatal([After gl_INIT_PACKAGE, the two-argument form of AM_INIT_AUTOMAKE cannot be used.])]) - gl_AM_INIT_AUTOMAKE([$1 no-define]) - m4_if(m4_index([ $1 ], [ no-define ]), [-1], -- [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) -- AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]) -+ [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) -+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package]) - ]) - ]) diff --git a/tools/gnulib/patches/652-package-version-simplify-further.patch b/tools/gnulib/patches/652-package-version-simplify-further.patch deleted file mode 100644 index 54589182469..00000000000 --- a/tools/gnulib/patches/652-package-version-simplify-further.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 48648b4b9b3fd79a5c68913deb28678bd9d8eb34 Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Sat, 25 Jan 2025 04:07:32 +0100 -Subject: package-version: Simplify further. - -* doc/package-version.texi (Propagating the package version): Recommend -use of gl_INIT_PACKAGE_VERSION instead of gl_INIT_PACKAGE. -* build-aux/git-version-gen: Likewise. -* m4/init-package-version.m4: Likewise. -(gl_INIT_PACKAGE_VERSION): Renamed from gl_INIT_PACKAGE. Take only one -argument. Don't fiddle with AC_PACKAGE_NAME, AC_PACKAGE_TARNAME, -PACKAGE. -(gl_RPL_INIT_AUTOMAKE): Update. ---- - ChangeLog | 10 ++++++++++ - build-aux/git-version-gen | 4 ++-- - doc/package-version.texi | 4 ++-- - m4/init-package-version.m4 | 30 ++++++++++++------------------ - 4 files changed, 26 insertions(+), 22 deletions(-) - ---- a/m4/init-package-version.m4 -+++ b/m4/init-package-version.m4 -@@ -1,5 +1,5 @@ - # init-package-version.m4 --# serial 4 -+# serial 5 - dnl Copyright (C) 1992-2025 Free Software Foundation, Inc. - dnl This file is free software, distributed under the terms of the GNU - dnl General Public License. As a special exception to the GNU General -@@ -60,7 +60,7 @@ dnl the same distribution terms as the r - # AC_INIT(PACKAGE, [dummy], [MORE OPTIONS]) - # AC_CONFIG_SRCDIR(WITNESS) - # . $srcdir/../version.sh --# gl_INIT_PACKAGE(PACKAGE, $VERSION_NUMBER) -+# gl_INIT_PACKAGE_VERSION($VERSION_NUMBER) - # AM_INIT_AUTOMAKE([OPTIONS]) - # - # and after changing version.sh, the developer can directly configure and build: -@@ -85,32 +85,26 @@ dnl the same distribution terms as the r - # make - # - --# gl_INIT_PACKAGE(PACKAGE-NAME, VERSION) --# -------------------------------------- -+# gl_INIT_PACKAGE_VERSION(VERSION) -+# -------------------------------- - # followed by an AM_INIT_AUTOMAKE invocation, - # is like calling AM_INIT_AUTOMAKE(PACKAGE-NAME, VERSION) - # except that it can use computed non-literal arguments. --AC_DEFUN([gl_INIT_PACKAGE], -+AC_DEFUN([gl_INIT_PACKAGE_VERSION], - [ - AC_BEFORE([$0], [AM_INIT_AUTOMAKE]) - dnl Redefine AM_INIT_AUTOMAKE. - m4_define([gl_AM_INIT_AUTOMAKE], -- m4_bpatsubst(m4_dquote( -- m4_bpatsubst(m4_dquote( -- m4_bpatsubst(m4_dquote( -- m4_defn([AM_INIT_AUTOMAKE])), -- [AC_PACKAGE_NAME], [gl_INIT_DUMMY])), -- [AC_PACKAGE_TARNAME], [gl_INIT_EMPTY])), -+ m4_bpatsubst(m4_dquote(m4_defn([AM_INIT_AUTOMAKE])), - [AC_PACKAGE_VERSION], [gl_INIT_DUMMY]) - [dnl Set variables documented in Automake. -- AC_SUBST([PACKAGE], [$1]) -- AC_SUBST([VERSION], ["$2"]) -+ AC_SUBST([VERSION], ["$1"]) - dnl Set variables documented in Autoconf. -- AC_SUBST([PACKAGE_VERSION], ["$2"]) -- AC_SUBST([PACKAGE_STRING], ["$1 $2"]) -- AC_DEFINE_UNQUOTED([PACKAGE_VERSION], ["$2"], -+ AC_SUBST([PACKAGE_VERSION], ["$1"]) -+ AC_SUBST([PACKAGE_STRING], ["AC_PACKAGE_NAME $1"]) -+ AC_DEFINE_UNQUOTED([PACKAGE_VERSION], ["$1"], - [Define to the version of this package.]) -- AC_DEFINE_UNQUOTED([PACKAGE_STRING], ["$1 $2"], -+ AC_DEFINE_UNQUOTED([PACKAGE_STRING], ["AC_PACKAGE_NAME $1"], - [Define to the full name and version of this package.]) - ]) - m4_define([AM_INIT_AUTOMAKE], -@@ -123,7 +117,7 @@ m4_define([gl_INIT_DUMMY], [gl_INIT_DUMM - m4_define([gl_INIT_DUMMY2], []) - AC_DEFUN([gl_RPL_INIT_AUTOMAKE], [ - m4_ifval([$2], -- [m4_fatal([After gl_INIT_PACKAGE, the two-argument form of AM_INIT_AUTOMAKE cannot be used.])]) -+ [m4_fatal([After gl_INIT_PACKAGE_VERSION, the two-argument form of AM_INIT_AUTOMAKE cannot be used.])]) - gl_AM_INIT_AUTOMAKE([$1 no-define]) - m4_if(m4_index([ $1 ], [ no-define ]), [-1], - [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) diff --git a/tools/gnulib/patches/653-package-version-warning.patch b/tools/gnulib/patches/653-package-version-warning.patch deleted file mode 100644 index 4baa21ce654..00000000000 --- a/tools/gnulib/patches/653-package-version-warning.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 2e46209809f751087ca27523283bd5c3e9071d31 Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Sun, 26 Jan 2025 13:26:35 +0100 -Subject: package-version: Avoid compiler warnings in config.log. - -* m4/init-package-version.m4 (gl_INIT_PACKAGE_VERSION): Undefine -PACKAGE_VERSION and PACKAGE_STRING before redefining them. ---- - ChangeLog | 6 ++++++ - m4/init-package-version.m4 | 4 +++- - 2 files changed, 9 insertions(+), 1 deletion(-) - ---- a/m4/init-package-version.m4 -+++ b/m4/init-package-version.m4 -@@ -1,5 +1,5 @@ - # init-package-version.m4 --# serial 5 -+# serial 6 - dnl Copyright (C) 1992-2025 Free Software Foundation, Inc. - dnl This file is free software, distributed under the terms of the GNU - dnl General Public License. As a special exception to the GNU General -@@ -102,8 +102,10 @@ AC_DEFUN([gl_INIT_PACKAGE_VERSION], - dnl Set variables documented in Autoconf. - AC_SUBST([PACKAGE_VERSION], ["$1"]) - AC_SUBST([PACKAGE_STRING], ["AC_PACKAGE_NAME $1"]) -+ _AC_DEFINE([#undef PACKAGE_VERSION]) - AC_DEFINE_UNQUOTED([PACKAGE_VERSION], ["$1"], - [Define to the version of this package.]) -+ _AC_DEFINE([#undef PACKAGE_STRING]) - AC_DEFINE_UNQUOTED([PACKAGE_STRING], ["AC_PACKAGE_NAME $1"], - [Define to the full name and version of this package.]) - ]) diff --git a/tools/gnulib/patches/660-version-stamp.patch b/tools/gnulib/patches/660-version-stamp.patch deleted file mode 100644 index d85c0455cf2..00000000000 --- a/tools/gnulib/patches/660-version-stamp.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 85599643e2fbf70f7f0bd58831993132ef335705 Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Wed, 22 Jan 2025 21:25:27 +0100 -Subject: New module 'version-stamp'. - -* m4/version-stamp.m4: New file. -* modules/version-stamp: New file. ---- - ChangeLog | 6 ++++++ - m4/version-stamp.m4 | 35 +++++++++++++++++++++++++++++++++++ - modules/version-stamp | 19 +++++++++++++++++++ - 3 files changed, 60 insertions(+) - create mode 100644 m4/version-stamp.m4 - create mode 100644 modules/version-stamp - ---- /dev/null -+++ b/m4/version-stamp.m4 -@@ -0,0 +1,35 @@ -+# version-stamp.m4 -+# serial 1 -+dnl Copyright (C) 2025 Free Software Foundation, Inc. -+dnl This file is free software, distributed under the terms of the GNU -+dnl General Public License. As a special exception to the GNU General -+dnl Public License, this file may be distributed as part of a program -+dnl that contains a configuration script generated by Autoconf, under -+dnl the same distribution terms as the rest of that program. -+ -+# Manages a stamp file, that keeps track when $(VERSION) was last changed. -+# -+# gl_CONFIG_VERSION_STAMP -+# needs to be invoked near the end of the package's top-level configure.ac, -+# before AC_OUTPUT. -+# It makes sure that during the build, -+# - $(top_srcdir)/.version exists, and -+# - when $(VERSION) is changed, $(top_srcdir)/.version gets modified. -+# -+# $(top_srcdir)/.version is a stamp file. Its contents wouldn't matter, -+# except that for detecting the change, we store the value of $(VERSION) -+# in it (but we could just as well store it in a different file). -+AC_DEFUN([gl_CONFIG_VERSION_STAMP], -+[ -+ AC_CONFIG_COMMANDS([version-timestamp], -+ [if test -f "$ac_top_srcdir/.version" \ -+ && test `cat "$ac_top_srcdir/.version"` = "$gl_version"; then -+ # The value of $(VERSION) is the same as last time. -+ : -+ else -+ # The value of $(VERSION) has changed. Update the stamp. -+ echo "$gl_version" > "$ac_top_srcdir/.version" -+ fi -+ ], -+ [gl_version="$VERSION"]) -+]) ---- /dev/null -+++ b/modules/version-stamp -@@ -0,0 +1,19 @@ -+Description: -+Optimized rebuilding of artifacts that depend on $(VERSION). -+ -+Files: -+m4/version-stamp.m4 -+ -+Depends-on: -+ -+configure.ac: -+ -+Makefile.am: -+ -+Include: -+ -+License: -+GPLed build tool -+ -+Maintainer: -+Bruno Haible diff --git a/tools/gnulib/patches/689-vc-mtime.patch b/tools/gnulib/patches/689-vc-mtime.patch deleted file mode 100644 index 62638d7ff44..00000000000 --- a/tools/gnulib/patches/689-vc-mtime.patch +++ /dev/null @@ -1,366 +0,0 @@ -From 701d20aaf579bb71f35209dd63a272c3d9d21096 Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Mon, 24 Feb 2025 19:03:17 +0100 -Subject: [PATCH] vc-mtime: New module. - -* lib/vc-mtime.h: New file. -* lib/vc-mtime.c: New file. -* modules/vc-mtime: New file. ---- - ChangeLog | 7 ++ - lib/vc-mtime.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++ - lib/vc-mtime.h | 97 ++++++++++++++++++++++ - modules/vc-mtime | 34 ++++++++ - 4 files changed, 346 insertions(+) - create mode 100644 lib/vc-mtime.c - create mode 100644 lib/vc-mtime.h - create mode 100644 modules/vc-mtime - ---- /dev/null -+++ b/lib/vc-mtime.c -@@ -0,0 +1,208 @@ -+/* Return the version-control based modification time of a file. -+ Copyright (C) 2025 Free Software Foundation, Inc. -+ -+ 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 3 of the License, or -+ (at your option) any later version. -+ -+ This program 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. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . */ -+ -+/* Written by Bruno Haible , 2025. */ -+ -+#include -+ -+/* Specification. */ -+#include "vc-mtime.h" -+ -+#include -+#include -+ -+#include -+#include "spawn-pipe.h" -+#include "wait-process.h" -+#include "execute.h" -+#include "safe-read.h" -+#include "xstrtol.h" -+#include "stat-time.h" -+#include "gettext.h" -+ -+#define _(msgid) dgettext ("gnulib", msgid) -+ -+ -+/* Determines whether the specified file is under version control. */ -+static bool -+git_vc_controlled (const char *filename) -+{ -+ /* Run "git ls-files FILENAME" and return true if the exit code is 0 -+ and the output is non-empty. */ -+ const char *argv[4]; -+ pid_t child; -+ int fd[1]; -+ -+ argv[0] = "git"; -+ argv[1] = "ls-files"; -+ argv[2] = filename; -+ argv[3] = NULL; -+ child = create_pipe_in ("git", "git", argv, NULL, NULL, -+ DEV_NULL, true, true, false, fd); -+ if (child == -1) -+ return false; -+ -+ /* Read the subprocess output, and test whether it is non-empty. */ -+ size_t count = 0; -+ char c; -+ -+ while (safe_read (fd[0], &c, 1) > 0) -+ count++; -+ -+ close (fd[0]); -+ -+ /* Remove zombie process from process list, and retrieve exit status. */ -+ int exitstatus = -+ wait_subprocess (child, "git", false, true, true, false, NULL); -+ return (exitstatus == 0 && count > 0); -+} -+ -+/* Determines whether the specified file is unmodified, compared to the -+ last version in version control. */ -+static bool -+git_unmodified (const char *filename) -+{ -+ /* Run "git diff --quiet -- HEAD FILENAME" -+ (or "git diff --quiet HEAD FILENAME") -+ and return true if the exit code is 0. -+ The '--' option is for the case that the specified file was removed. */ -+ const char *argv[7]; -+ int exitstatus; -+ -+ argv[0] = "git"; -+ argv[1] = "diff"; -+ argv[2] = "--quiet"; -+ argv[3] = "--"; -+ argv[4] = "HEAD"; -+ argv[5] = filename; -+ argv[6] = NULL; -+ exitstatus = execute ("git", "git", argv, NULL, NULL, -+ false, false, true, true, -+ true, false, NULL); -+ return (exitstatus == 0); -+} -+ -+/* Stores in *MTIME the time of last modification in version control of the -+ specified file, and returns 0. -+ Upon failure, it returns -1. */ -+static int -+git_mtime (struct timespec *mtime, const char *filename) -+{ -+ /* Run "git log -1 --format=%ct -- FILENAME". It prints the time of last -+ modification, as the number of seconds since the Epoch. -+ The '--' option is for the case that the specified file was removed. */ -+ const char *argv[7]; -+ pid_t child; -+ int fd[1]; -+ -+ argv[0] = "git"; -+ argv[1] = "log"; -+ argv[2] = "-1"; -+ argv[3] = "--format=%ct"; -+ argv[4] = "--"; -+ argv[5] = filename; -+ argv[6] = NULL; -+ child = create_pipe_in ("git", "git", argv, NULL, NULL, -+ DEV_NULL, true, true, false, fd); -+ if (child == -1) -+ return -1; -+ -+ /* Retrieve its result. */ -+ FILE *fp; -+ char *line; -+ size_t linesize; -+ size_t linelen; -+ -+ fp = fdopen (fd[0], "r"); -+ if (fp == NULL) -+ error (EXIT_FAILURE, errno, _("fdopen() failed")); -+ -+ line = NULL; linesize = 0; -+ linelen = getline (&line, &linesize, fp); -+ if (linelen == (size_t)(-1)) -+ { -+ error (0, 0, _("%s subprocess I/O error"), "git"); -+ fclose (fp); -+ wait_subprocess (child, "git", true, false, true, false, NULL); -+ } -+ else -+ { -+ int exitstatus; -+ -+ if (linelen > 0 && line[linelen - 1] == '\n') -+ line[linelen - 1] = '\0'; -+ -+ fclose (fp); -+ -+ /* Remove zombie process from process list, and retrieve exit status. */ -+ exitstatus = -+ wait_subprocess (child, "git", true, false, true, false, NULL); -+ if (exitstatus == 0) -+ { -+ char *endptr; -+ unsigned long git_log_time; -+ if (xstrtoul (line, &endptr, 10, &git_log_time, NULL) == LONGINT_OK -+ && endptr == line + strlen (line)) -+ { -+ mtime->tv_sec = git_log_time; -+ mtime->tv_nsec = 0; -+ free (line); -+ return 0; -+ } -+ } -+ } -+ free (line); -+ return -1; -+} -+ -+int -+vc_mtime (struct timespec *mtime, const char *filename) -+{ -+ static bool git_tested; -+ static bool git_present; -+ -+ if (!git_tested) -+ { -+ /* Test for presence of git: -+ "git --version >/dev/null 2>/dev/null" */ -+ const char *argv[3]; -+ int exitstatus; -+ -+ argv[0] = "git"; -+ argv[1] = "--version"; -+ argv[2] = NULL; -+ exitstatus = execute ("git", "git", argv, NULL, NULL, -+ false, false, true, true, -+ true, false, NULL); -+ git_present = (exitstatus == 0); -+ git_tested = true; -+ } -+ -+ if (git_present -+ && git_vc_controlled (filename) -+ && git_unmodified (filename)) -+ { -+ if (git_mtime (mtime, filename) == 0) -+ return 0; -+ } -+ struct stat statbuf; -+ if (stat (filename, &statbuf) == 0) -+ { -+ *mtime = get_stat_mtime (&statbuf); -+ return 0; -+ } -+ return -1; -+} ---- /dev/null -+++ b/lib/vc-mtime.h -@@ -0,0 +1,97 @@ -+/* Return the version-control based modification time of a file. -+ Copyright (C) 2025 Free Software Foundation, Inc. -+ -+ 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 3 of the License, or -+ (at your option) any later version. -+ -+ This program 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. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . */ -+ -+/* Written by Bruno Haible , 2025. */ -+ -+#ifndef _VC_MTIME_H -+#define _VC_MTIME_H -+ -+/* Get struct timespec. */ -+#include -+ -+/* The "version-controlled modification time" vc_mtime(F) of a file F -+ is defined as: -+ - If F is under version control and not modified locally: -+ the time of the last change of F in the version control system. -+ - Otherwise: The modification time of F on disk. -+ -+ For now, the only VCS supported by this module is git. (hg and svn are -+ hardly in use any more.) -+ -+ This has the properties that: -+ - Different users who have checked out the same git repo on different -+ machines, at different times, and not done local modifications, -+ get the same vc_mtime(F). -+ - If a user has modified F locally, the modification time of that file -+ counts. -+ - If that user then reverts the modification, they then again get the -+ same vc_mtime(F) as everyone else. -+ - Different users who have unpacked the same tarball (without .git -+ directory) on different machines, at different times, also get the same -+ vc_mtime(F) [but possibly a different one than when the .git directory -+ was present]. (Assuming a POSIX compliant file system.) -+ - When a user commits local modifications into git, this only increases -+ (not decreases) the vc_mtime(F). -+ -+ The purpose of the version-controlled modification time is to produce a -+ reproducible timestamp(Z) of a file Z that depends on files X1, ..., Xn, -+ in such a way that -+ - timestamp(Z) is reproducible, that is, different users on different -+ machines get the same value. -+ - timestamp(Z) is related to reality. It's not just a dummy, like what -+ is suggested in . -+ - One can arrange for timestamp(Z) to respect the modification time -+ relations of a build system. -+ -+ There are two uses of such a timestamp: -+ - It can be set as the modification time of file Z in a file system, or -+ - It can be embedded in Z, with the purpose of telling a user how old -+ the file Z is. For example, in PDF files or in generated documentation, -+ such a time is embedded in a special place. -+ -+ The simplest example is a file Z that depends on files X1, ..., Xn. -+ Generally one will define -+ timestamp(Z) = max (vc_mtime(X1), ..., vc_mtime(Xn)) -+ for an embedded timestamp, or -+ timestamp(Z) = max (vc_mtime(X1), ..., vc_mtime(Xn)) + 1 second -+ for a time stamp in a file system. The added second -+ 1. accounts for fractional seconds in mtime(X1), ..., mtime(Xn), -+ 2. allows for 'make' implementation that attempt to rebuild Z -+ if mtime(Z) == mtime(Xi). -+ -+ A more complicated example is when there are intermediate built files, not -+ under version control. For example, if the build process produces -+ X1, X2 -> Y1 -+ X3, X4 -> Y2 -+ Y1, Y2, X5 -> Z -+ where Y1 and Y2 are intermediate built files, you should ignore the -+ mtime(Y1), mtime(Y2), and consider only the vc_mtime(X1), ..., vc_mtime(X5). -+ */ -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* Determines the version-controlled modification time of FILENAME, stores it -+ in *MTIME, and returns 0. -+ Upon failure, it returns -1. */ -+extern int vc_mtime (struct timespec *mtime, const char *filename); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* _VC_MTIME_H */ ---- /dev/null -+++ b/modules/vc-mtime -@@ -0,0 +1,34 @@ -+Description: -+Returns the version-control based modification time of a file. -+ -+Files: -+lib/vc-mtime.h -+lib/vc-mtime.c -+ -+Depends-on: -+time-h -+bool -+spawn-pipe -+wait-process -+execute -+safe-read -+error -+getline -+xstrtol -+stat-time -+gettext-h -+gnulib-i18n -+ -+configure.ac: -+ -+Makefile.am: -+lib_SOURCES += vc-mtime.c -+ -+Include: -+"vm-mtime.h" -+ -+License: -+GPL -+ -+Maintainer: -+Bruno Haible diff --git a/tools/gnulib/patches/755-clean-temp-hashkey.patch b/tools/gnulib/patches/755-clean-temp-hashkey.patch deleted file mode 100644 index 7a4774c9b31..00000000000 --- a/tools/gnulib/patches/755-clean-temp-hashkey.patch +++ /dev/null @@ -1,64 +0,0 @@ -From f47c5f2e21d0ccedb271b406e35b6963b23a64c4 Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Wed, 30 Apr 2025 13:11:01 +0200 -Subject: [PATCH] clean-temp: Fix link error (regression yesterday). - -* lib/clean-temp.c: Include hashkey-string.h. -(create_temp_dir): Use hashkey_string_* functions instead of -clean_temp_string_*. -* lib/clean-temp-private.h (clean_temp_string_equals, -clean_temp_string_hash): Remove declarations. -* modules/clean-temp (Depends-on): Add hashkey-string. ---- - ChangeLog | 10 ++++++++++ - lib/clean-temp-private.h | 3 --- - lib/clean-temp.c | 5 +++-- - modules/clean-temp | 1 + - 4 files changed, 14 insertions(+), 5 deletions(-) - ---- a/lib/clean-temp-private.h -+++ b/lib/clean-temp-private.h -@@ -68,9 +68,6 @@ struct closeable_fd - #define descriptors clean_temp_descriptors - extern gl_list_t /* */ volatile descriptors; - --extern bool clean_temp_string_equals (const void *x1, const void *x2); --extern size_t clean_temp_string_hash (const void *x); -- - extern _GL_ASYNC_SAFE int clean_temp_asyncsafe_close (struct closeable_fd *element); - extern void clean_temp_init_asyncsafe_close (void); - ---- a/lib/clean-temp.c -+++ b/lib/clean-temp.c -@@ -45,6 +45,7 @@ - #include "xmalloca.h" - #include "glthread/lock.h" - #include "thread-optim.h" -+#include "hashkey-string.h" - #include "gl_xlist.h" - #include "gl_linkedhash_list.h" - #include "gl_linked_list.h" -@@ -221,11 +222,11 @@ create_temp_dir (const char *prefix, con - tmpdir->cleanup_verbose = cleanup_verbose; - tmpdir->subdirs = - gl_list_create_empty (GL_LINKEDHASH_LIST, -- clean_temp_string_equals, clean_temp_string_hash, -+ hashkey_string_equals, hashkey_string_hash, - NULL, false); - tmpdir->files = - gl_list_create_empty (GL_LINKEDHASH_LIST, -- clean_temp_string_equals, clean_temp_string_hash, -+ hashkey_string_equals, hashkey_string_hash, - NULL, false); - - /* Create the temporary directory. */ ---- a/modules/clean-temp -+++ b/modules/clean-temp -@@ -24,6 +24,7 @@ rmdir - xalloc - xalloc-die - xmalloca -+hashkey-string - linkedhash-list - linked-list - xlist diff --git a/tools/gnulib/patches/795-string-desc-rename-functions.patch b/tools/gnulib/patches/795-string-desc-rename-functions.patch deleted file mode 100644 index 032545b063c..00000000000 --- a/tools/gnulib/patches/795-string-desc-rename-functions.patch +++ /dev/null @@ -1,1137 +0,0 @@ -From 9a26e7043fa95b4c9ee4576ce8c0ac15668e695e Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Thu, 2 Jan 2025 13:54:54 +0100 -Subject: [PATCH] string-desc, xstring-desc, string-desc-quotearg: Rename - functions. - -* lib/string-desc.h (sd_equals): Renamed from string_desc_equals. -(sd_startswith): Renamed from string_desc_startswith. -(sd_endswith): Renamed from string_desc_endswith. -(sd_cmp): Renamed from string_desc_cmp. -(sd_c_casecmp): Renamed from string_desc_c_casecmp. -(sd_index): Renamed from string_desc_index. -(sd_last_index): Renamed from string_desc_last_index. -(sd_contains): Renamed from string_desc_contains. -(sd_new_empty): Renamed from string_desc_new_empty. -(sd_new_addr): Renamed from string_desc_new_addr. -(sd_from_c): Renamed from string_desc_from_c. -(sd_substring): Renamed from string_desc_substring. -(sd_write): Renamed from string_desc_write. -(sd_fwrite): Renamed from string_desc_fwrite. -(sd_new): Renamed from string_desc_new. -(sd_new_filled): Renamed from string_desc_new_filled. -(sd_copy): Renamed from string_desc_copy. -(sd_concat): Renamed from string_desc_concat. -(sd_c): Renamed from string_desc_c. -(sd_set_char_at): Renamed from string_desc_set_char_at. -(sd_fill): Renamed from string_desc_fill. -(sd_overwrite): Renamed from string_desc_overwrite. -(sd_free): Renamed from string_desc_free. -(sd_length): Renamed from string_desc_length. -(sd_char_at): Renamed from string_desc_char_at. -(sd_data): Renamed from string_desc_data. -(sd_is_empty): Renamed from string_desc_is_empty. -* lib/string-desc.c (sd_equals): Renamed from string_desc_equals. -(sd_startswith): Renamed from string_desc_startswith. -(sd_endswith): Renamed from string_desc_endswith. -(sd_cmp): Renamed from string_desc_cmp. -(sd_c_casecmp): Renamed from string_desc_c_casecmp. -(sd_index): Renamed from string_desc_index. -(sd_last_index): Renamed from string_desc_last_index. -(sd_new_empty): Renamed from string_desc_new_empty. -(sd_new_addr): Renamed from string_desc_new_addr. -(sd_from_c): Renamed from string_desc_from_c. -(sd_substring): Renamed from string_desc_substring. -(sd_write): Renamed from string_desc_write. -(sd_fwrite): Renamed from string_desc_fwrite. -(sd_new): Renamed from string_desc_new. -(sd_new_filled): Renamed from string_desc_new_filled. -(sd_copy): Renamed from string_desc_copy. -(sd_concat): Renamed from string_desc_concat. -(sd_c): Renamed from string_desc_c. -(sd_set_char_at): Renamed from string_desc_set_char_at. -(sd_fill): Renamed from string_desc_fill. -(sd_overwrite): Renamed from string_desc_overwrite. -(sd_free): Renamed from string_desc_free. -* lib/xstring-desc.h (xsd_concat): Renamed from xstring_desc_concat. -(xsd_new): Renamed from xstring_desc_new. -(xsd_new_filled): Renamed from xstring_desc_new_filled. -(xsd_copy): Renamed from xstring_desc_copy. -(xsd_c): Renamed from xstring_desc_c. -* lib/xstring-desc.c (xsd_concat): Renamed from xstring_desc_concat. -* lib/string-desc-quotearg.h (sd_quotearg_buffer): Renamed from -string_desc_quotearg_buffer. -(sd_quotearg_alloc): Renamed from string_desc_quotearg_alloc. -(sd_quotearg_n): Renamed from string_desc_quotearg_n. -(sd_quotearg): Renamed from string_desc_quotearg. -(sd_quotearg_n_style): Renamed from string_desc_quotearg_n_style. -(sd_quotearg_style): Renamed from string_desc_quotearg_style. -(sd_quotearg_char): Renamed from string_desc_quotearg_char. -(sd_quotearg_colon): Renamed from string_desc_quotearg_colon. -(sd_quotearg_n_custom): Renamed from string_desc_quotearg_n_custom. -(sd_quotearg_custom): Renamed from sd_quotearg_n_custom. -* lib/string-desc-contains.c (sd_contains): Renamed from -string_desc_contains. -* lib/string-buffer.h: Update. -* lib/string-buffer.c (sb_append_desc, sb_contents, sb_dupfree): Update. -* lib/xstring-buffer.c (sb_xdupfree): Update. -* lib/sf-istream.c (sf_istream_init_from_string_desc): Update. -* tests/test-string-desc.c (main): Update. -* tests/test-string-desc.sh: Update. -* tests/test-xstring-desc.c (main): Update. -* tests/test-string-desc-quotearg.c (main): Update. -* tests/test-string-buffer.c (main): Update. -* tests/test-sf-istream.c (main): Update. -* tests/test-sfl-istream.c (main): Update. -* doc/string-desc.texi: Update. -* doc/strings.texi: Update. -* NEWS: Mention the change. ---- - ChangeLog | 86 +++++++++ - NEWS | 4 + - doc/string-desc.texi | 4 +- - doc/strings.texi | 18 +- - lib/sf-istream.c | 4 +- - lib/string-buffer.c | 12 +- - lib/string-buffer.h | 4 +- - lib/string-desc-contains.c | 2 +- - lib/string-desc-quotearg.h | 114 ++++++------ - lib/string-desc.c | 52 +++--- - lib/string-desc.h | 62 +++---- - lib/xstring-buffer.c | 4 +- - lib/xstring-desc.c | 2 +- - lib/xstring-desc.h | 26 +-- - tests/test-sf-istream.c | 4 +- - tests/test-sfl-istream.c | 4 +- - tests/test-string-buffer.c | 18 +- - tests/test-string-desc-quotearg.c | 44 ++--- - tests/test-string-desc.c | 296 +++++++++++++++--------------- - tests/test-string-desc.sh | 4 +- - tests/test-xstring-desc.c | 68 +++---- - 21 files changed, 461 insertions(+), 371 deletions(-) - ---- a/lib/sf-istream.c -+++ b/lib/sf-istream.c -@@ -46,8 +46,8 @@ sf_istream_init_from_string_desc (sf_ist - string_desc_t input) - { - stream->fp = NULL; -- stream->input = string_desc_data (input); -- stream->input_end = stream->input + string_desc_length (input); -+ stream->input = sd_data (input); -+ stream->input_end = stream->input + sd_length (input); - } - - int ---- a/lib/string-buffer.c -+++ b/lib/string-buffer.c -@@ -101,13 +101,13 @@ sb_append1 (struct string_buffer *buffer - int - sb_append_desc (struct string_buffer *buffer, string_desc_t s) - { -- size_t len = string_desc_length (s); -+ size_t len = sd_length (s); - if (sb_ensure_more_bytes (buffer, len) < 0) - { - buffer->error = true; - return -1; - } -- memcpy (buffer->data + buffer->length, string_desc_data (s), len); -+ memcpy (buffer->data + buffer->length, sd_data (s), len); - buffer->length += len; - return 0; - } -@@ -136,7 +136,7 @@ sb_free (struct string_buffer *buffer) - string_desc_t - sb_contents (struct string_buffer *buffer) - { -- return string_desc_new_addr (buffer->length, buffer->data); -+ return sd_new_addr (buffer->length, buffer->data); - } - - const char * -@@ -162,7 +162,7 @@ sb_dupfree (struct string_buffer *buffer - if (copy == NULL) - goto fail; - memcpy (copy, buffer->data, length); -- return string_desc_new_addr (length, copy); -+ return sd_new_addr (length, copy); - } - else - { -@@ -174,12 +174,12 @@ sb_dupfree (struct string_buffer *buffer - if (contents == NULL) - goto fail; - } -- return string_desc_new_addr (length, contents); -+ return sd_new_addr (length, contents); - } - - fail: - sb_free (buffer); -- return string_desc_new_addr (0, NULL); -+ return sd_new_addr (0, NULL); - } - - char * ---- a/lib/string-buffer.h -+++ b/lib/string-buffer.h -@@ -115,7 +115,7 @@ extern const char * sb_contents_c (struc - - /* Returns the contents of BUFFER and frees all other memory held by BUFFER. - Returns NULL upon failure or if there was an error earlier. -- It is the responsibility of the caller to string_desc_free() the result. */ -+ It is the responsibility of the caller to sd_free() the result. */ - extern string_desc_t sb_dupfree (struct string_buffer *buffer) - _GL_ATTRIBUTE_RELEASE_CAPABILITY (buffer->data); - -@@ -182,7 +182,7 @@ extern const char * sb_xcontents_c (stru - - /* Returns the contents of BUFFER and frees all other memory held by BUFFER. - Returns (0, NULL) if there was an error earlier. -- It is the responsibility of the caller to string_desc_free() the result. */ -+ It is the responsibility of the caller to sd_free() the result. */ - extern string_desc_t sb_xdupfree (struct string_buffer *buffer) - _GL_ATTRIBUTE_RELEASE_CAPABILITY (buffer->data); - ---- a/lib/string-desc-contains.c -+++ b/lib/string-desc-contains.c -@@ -31,7 +31,7 @@ - which — depending on platforms — costs up to 2 KB of binary code. */ - - ptrdiff_t --string_desc_contains (string_desc_t haystack, string_desc_t needle) -+sd_contains (string_desc_t haystack, string_desc_t needle) - { - if (needle._nbytes == 0) - return 0; ---- a/lib/string-desc-quotearg.h -+++ b/lib/string-desc-quotearg.h -@@ -50,22 +50,22 @@ extern "C" { - does not use backslash escapes and the flags of O do not request - elision of null bytes. */ - #if 0 --extern size_t string_desc_quotearg_buffer (char *restrict buffer, -- size_t buffersize, -- string_desc_t arg, -- struct quoting_options const *o); -+extern size_t sd_quotearg_buffer (char *restrict buffer, -+ size_t buffersize, -+ string_desc_t arg, -+ struct quoting_options const *o); - #endif - --/* Like string_desc_quotearg_buffer, except return the result in a newly -+/* Like sd_quotearg_buffer, except return the result in a newly - allocated buffer and store its length, excluding the terminating null - byte, in *SIZE. It is the caller's responsibility to free the result. - The result might contain embedded null bytes if the style of O does - not use backslash escapes and the flags of O do not request elision - of null bytes. */ - #if 0 --extern char *string_desc_quotearg_alloc (string_desc_t arg, -- size_t *size, -- struct quoting_options const *o) -+extern char *sd_quotearg_alloc (string_desc_t arg, -+ size_t *size, -+ struct quoting_options const *o) - _GL_ATTRIBUTE_NONNULL ((2)) - _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE - _GL_ATTRIBUTE_RETURNS_NONNULL; -@@ -77,68 +77,68 @@ extern char *string_desc_quotearg_alloc - reused by the next call to this function with the same value of N. - N must be nonnegative. */ - #if 0 --extern char *string_desc_quotearg_n (int n, string_desc_t arg); -+extern char *sd_quotearg_n (int n, string_desc_t arg); - #endif - --/* Equivalent to string_desc_quotearg_n (0, ARG). */ -+/* Equivalent to sd_quotearg_n (0, ARG). */ - #if 0 --extern char *string_desc_quotearg (string_desc_t arg); -+extern char *sd_quotearg (string_desc_t arg); - #endif - - /* Use style S and storage slot N to return a quoted version of the string ARG. -- This is like string_desc_quotearg_n (N, ARG), except that it uses S -+ This is like sd_quotearg_n (N, ARG), except that it uses S - with no other options to specify the quoting method. */ - #if 0 --extern char *string_desc_quotearg_n_style (int n, enum quoting_style s, -- string_desc_t arg); -+extern char *sd_quotearg_n_style (int n, enum quoting_style s, -+ string_desc_t arg); - #endif - --/* Equivalent to string_desc_quotearg_n_style (0, S, ARG). */ -+/* Equivalent to sd_quotearg_n_style (0, S, ARG). */ - #if 0 --extern char *string_desc_quotearg_style (enum quoting_style s, -- string_desc_t arg); -+extern char *sd_quotearg_style (enum quoting_style s, -+ string_desc_t arg); - #endif - --/* Like string_desc_quotearg (ARG), except also quote any instances of CH. -+/* Like sd_quotearg (ARG), except also quote any instances of CH. - See set_char_quoting for a description of acceptable CH values. */ - #if 0 --extern char *string_desc_quotearg_char (string_desc_t arg, char ch); -+extern char *sd_quotearg_char (string_desc_t arg, char ch); - #endif - --/* Equivalent to string_desc_quotearg_char (ARG, ':'). */ -+/* Equivalent to sd_quotearg_char (ARG, ':'). */ - #if 0 --extern char *string_desc_quotearg_colon (string_desc_t arg); -+extern char *sd_quotearg_colon (string_desc_t arg); - #endif - --/* Like string_desc_quotearg_n_style (N, S, ARG) but with S as -+/* Like sd_quotearg_n_style (N, S, ARG) but with S as - custom_quoting_style with left quote as LEFT_QUOTE and right quote - as RIGHT_QUOTE. See set_custom_quoting for a description of acceptable - LEFT_QUOTE and RIGHT_QUOTE values. */ - #if 0 --extern char *string_desc_quotearg_n_custom (int n, -- char const *left_quote, -- char const *right_quote, -- string_desc_t arg); -+extern char *sd_quotearg_n_custom (int n, -+ char const *left_quote, -+ char const *right_quote, -+ string_desc_t arg); - #endif - - /* Equivalent to -- string_desc_quotearg_n_custom (0, LEFT_QUOTE, RIGHT_QUOTE, ARG). */ -+ sd_quotearg_n_custom (0, LEFT_QUOTE, RIGHT_QUOTE, ARG). */ - #if 0 --extern char *string_desc_quotearg_custom (char const *left_quote, -- char const *right_quote, -- string_desc_t arg); -+extern char *sd_quotearg_custom (char const *left_quote, -+ char const *right_quote, -+ string_desc_t arg); - #endif - - - /* ==== Inline function definitions ==== */ - - GL_STRING_DESC_QUOTEARG_INLINE size_t --string_desc_quotearg_buffer (char *restrict buffer, size_t buffersize, -- string_desc_t arg, -- struct quoting_options const *o) -+sd_quotearg_buffer (char *restrict buffer, size_t buffersize, -+ string_desc_t arg, -+ struct quoting_options const *o) - { - return quotearg_buffer (buffer, buffersize, -- string_desc_data (arg), string_desc_length (arg), -+ sd_data (arg), sd_length (arg), - o); - } - -@@ -147,69 +147,69 @@ _GL_ATTRIBUTE_NONNULL ((2)) - _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE - _GL_ATTRIBUTE_RETURNS_NONNULL - char * --string_desc_quotearg_alloc (string_desc_t arg, -- size_t *size, -- struct quoting_options const *o) -+sd_quotearg_alloc (string_desc_t arg, -+ size_t *size, -+ struct quoting_options const *o) - { -- return quotearg_alloc_mem (string_desc_data (arg), string_desc_length (arg), -+ return quotearg_alloc_mem (sd_data (arg), sd_length (arg), - size, - o); - } - - GL_STRING_DESC_QUOTEARG_INLINE char * --string_desc_quotearg_n (int n, string_desc_t arg) -+sd_quotearg_n (int n, string_desc_t arg) - { -- return quotearg_n_mem (n, string_desc_data (arg), string_desc_length (arg)); -+ return quotearg_n_mem (n, sd_data (arg), sd_length (arg)); - } - - GL_STRING_DESC_QUOTEARG_INLINE char * --string_desc_quotearg (string_desc_t arg) -+sd_quotearg (string_desc_t arg) - { -- return quotearg_mem (string_desc_data (arg), string_desc_length (arg)); -+ return quotearg_mem (sd_data (arg), sd_length (arg)); - } - - GL_STRING_DESC_QUOTEARG_INLINE char * --string_desc_quotearg_n_style (int n, enum quoting_style s, string_desc_t arg) -+sd_quotearg_n_style (int n, enum quoting_style s, string_desc_t arg) - { - return quotearg_n_style_mem (n, s, -- string_desc_data (arg), string_desc_length (arg)); -+ sd_data (arg), sd_length (arg)); - } - - GL_STRING_DESC_QUOTEARG_INLINE char * --string_desc_quotearg_style (enum quoting_style s, string_desc_t arg) -+sd_quotearg_style (enum quoting_style s, string_desc_t arg) - { - return quotearg_style_mem (s, -- string_desc_data (arg), string_desc_length (arg)); -+ sd_data (arg), sd_length (arg)); - } - - GL_STRING_DESC_QUOTEARG_INLINE char * --string_desc_quotearg_char (string_desc_t arg, char ch) -+sd_quotearg_char (string_desc_t arg, char ch) - { -- return quotearg_char_mem (string_desc_data (arg), string_desc_length (arg), -+ return quotearg_char_mem (sd_data (arg), sd_length (arg), - ch); - } - - GL_STRING_DESC_QUOTEARG_INLINE char * --string_desc_quotearg_colon (string_desc_t arg) -+sd_quotearg_colon (string_desc_t arg) - { -- return quotearg_colon_mem (string_desc_data (arg), string_desc_length (arg)); -+ return quotearg_colon_mem (sd_data (arg), sd_length (arg)); - } - - GL_STRING_DESC_QUOTEARG_INLINE char * --string_desc_quotearg_n_custom (int n, -- char const *left_quote, char const *right_quote, -- string_desc_t arg) -+sd_quotearg_n_custom (int n, -+ char const *left_quote, char const *right_quote, -+ string_desc_t arg) - { - return quotearg_n_custom_mem (n, left_quote, right_quote, -- string_desc_data (arg), string_desc_length (arg)); -+ sd_data (arg), sd_length (arg)); - } - - GL_STRING_DESC_QUOTEARG_INLINE char * --string_desc_quotearg_custom (char const *left_quote, char const *right_quote, -- string_desc_t arg) -+sd_quotearg_custom (char const *left_quote, char const *right_quote, -+ string_desc_t arg) - { - return quotearg_custom_mem (left_quote, right_quote, -- string_desc_data (arg), string_desc_length (arg)); -+ sd_data (arg), sd_length (arg)); - } - - ---- a/lib/string-desc.c -+++ b/lib/string-desc.c -@@ -39,14 +39,14 @@ - - /* Return true if A and B are equal. */ - bool --string_desc_equals (string_desc_t a, string_desc_t b) -+sd_equals (string_desc_t a, string_desc_t b) - { - return (a._nbytes == b._nbytes - && (a._nbytes == 0 || memcmp (a._data, b._data, a._nbytes) == 0)); - } - - bool --string_desc_startswith (string_desc_t s, string_desc_t prefix) -+sd_startswith (string_desc_t s, string_desc_t prefix) - { - return (s._nbytes >= prefix._nbytes - && (prefix._nbytes == 0 -@@ -54,7 +54,7 @@ string_desc_startswith (string_desc_t s, - } - - bool --string_desc_endswith (string_desc_t s, string_desc_t suffix) -+sd_endswith (string_desc_t s, string_desc_t suffix) - { - return (s._nbytes >= suffix._nbytes - && (suffix._nbytes == 0 -@@ -63,7 +63,7 @@ string_desc_endswith (string_desc_t s, s - } - - int --string_desc_cmp (string_desc_t a, string_desc_t b) -+sd_cmp (string_desc_t a, string_desc_t b) - { - if (a._nbytes > b._nbytes) - { -@@ -86,14 +86,14 @@ string_desc_cmp (string_desc_t a, string - } - - int --string_desc_c_casecmp (string_desc_t a, string_desc_t b) -+sd_c_casecmp (string_desc_t a, string_desc_t b) - { - /* Don't use memcasecmp here, since it uses the current locale, not the - "C" locale. */ -- idx_t an = string_desc_length (a); -- idx_t bn = string_desc_length (b); -- const char *ap = string_desc_data (a); -- const char *bp = string_desc_data (b); -+ idx_t an = sd_length (a); -+ idx_t bn = sd_length (b); -+ const char *ap = sd_data (a); -+ const char *bp = sd_data (b); - idx_t n = (an < bn ? an : bn); - idx_t i; - for (i = 0; i < n; i++) -@@ -108,7 +108,7 @@ string_desc_c_casecmp (string_desc_t a, - } - - ptrdiff_t --string_desc_index (string_desc_t s, char c) -+sd_index (string_desc_t s, char c) - { - if (s._nbytes > 0) - { -@@ -120,7 +120,7 @@ string_desc_index (string_desc_t s, char - } - - ptrdiff_t --string_desc_last_index (string_desc_t s, char c) -+sd_last_index (string_desc_t s, char c) - { - if (s._nbytes > 0) - { -@@ -132,7 +132,7 @@ string_desc_last_index (string_desc_t s, - } - - string_desc_t --string_desc_new_empty (void) -+sd_new_empty (void) - { - string_desc_t result; - -@@ -144,7 +144,7 @@ string_desc_new_empty (void) - } - - string_desc_t --string_desc_new_addr (idx_t n, char *addr) -+sd_new_addr (idx_t n, char *addr) - { - string_desc_t result; - -@@ -158,7 +158,7 @@ string_desc_new_addr (idx_t n, char *add - } - - string_desc_t --string_desc_from_c (const char *s) -+sd_from_c (const char *s) - { - string_desc_t result; - -@@ -169,7 +169,7 @@ string_desc_from_c (const char *s) - } - - string_desc_t --string_desc_substring (string_desc_t s, idx_t start, idx_t end) -+sd_substring (string_desc_t s, idx_t start, idx_t end) - { - string_desc_t result; - -@@ -184,7 +184,7 @@ string_desc_substring (string_desc_t s, - } - - int --string_desc_write (int fd, string_desc_t s) -+sd_write (int fd, string_desc_t s) - { - if (s._nbytes > 0) - if (full_write (fd, s._data, s._nbytes) != s._nbytes) -@@ -194,7 +194,7 @@ string_desc_write (int fd, string_desc_t - } - - int --string_desc_fwrite (FILE *fp, string_desc_t s) -+sd_fwrite (FILE *fp, string_desc_t s) - { - if (s._nbytes > 0) - if (fwrite (s._data, 1, s._nbytes, fp) != s._nbytes) -@@ -206,7 +206,7 @@ string_desc_fwrite (FILE *fp, string_des - /* ==== Memory-allocating operations on string descriptors ==== */ - - int --string_desc_new (string_desc_t *resultp, idx_t n) -+sd_new (string_desc_t *resultp, idx_t n) - { - string_desc_t result; - -@@ -230,7 +230,7 @@ string_desc_new (string_desc_t *resultp, - } - - int --string_desc_new_filled (string_desc_t *resultp, idx_t n, char c) -+sd_new_filled (string_desc_t *resultp, idx_t n, char c) - { - string_desc_t result; - -@@ -251,7 +251,7 @@ string_desc_new_filled (string_desc_t *r - } - - int --string_desc_copy (string_desc_t *resultp, string_desc_t s) -+sd_copy (string_desc_t *resultp, string_desc_t s) - { - string_desc_t result; - idx_t n = s._nbytes; -@@ -273,7 +273,7 @@ string_desc_copy (string_desc_t *resultp - } - - int --string_desc_concat (string_desc_t *resultp, idx_t n, string_desc_t string1, ...) -+sd_concat (string_desc_t *resultp, idx_t n, string_desc_t string1, ...) - { - if (n <= 0) - /* Invalid argument. */ -@@ -327,7 +327,7 @@ string_desc_concat (string_desc_t *resul - } - - char * --string_desc_c (string_desc_t s) -+sd_c (string_desc_t s) - { - idx_t n = s._nbytes; - char *result = (char *) imalloc (n + 1); -@@ -345,7 +345,7 @@ string_desc_c (string_desc_t s) - /* ==== Operations with side effects on string descriptors ==== */ - - void --string_desc_set_char_at (string_desc_t s, idx_t i, char c) -+sd_set_char_at (string_desc_t s, idx_t i, char c) - { - if (!(i >= 0 && i < s._nbytes)) - /* Invalid argument. */ -@@ -354,7 +354,7 @@ string_desc_set_char_at (string_desc_t s - } - - void --string_desc_fill (string_desc_t s, idx_t start, idx_t end, char c) -+sd_fill (string_desc_t s, idx_t start, idx_t end, char c) - { - if (!(start >= 0 && start <= end)) - /* Invalid arguments. */ -@@ -365,7 +365,7 @@ string_desc_fill (string_desc_t s, idx_t - } - - void --string_desc_overwrite (string_desc_t s, idx_t start, string_desc_t t) -+sd_overwrite (string_desc_t s, idx_t start, string_desc_t t) - { - if (!(start >= 0 && start + t._nbytes <= s._nbytes)) - /* Invalid arguments. */ -@@ -376,7 +376,7 @@ string_desc_overwrite (string_desc_t s, - } - - void --string_desc_free (string_desc_t s) -+sd_free (string_desc_t s) - { - free (s._data); - } ---- a/lib/string-desc.h -+++ b/lib/string-desc.h -@@ -69,82 +69,82 @@ struct string_desc_t - - /* Return the length of the string S. */ - #if 0 /* Defined inline below. */ --extern idx_t string_desc_length (string_desc_t s); -+extern idx_t sd_length (string_desc_t s); - #endif - - /* Return the byte at index I of string S. - I must be < length(S). */ - #if 0 /* Defined inline below. */ --extern char string_desc_char_at (string_desc_t s, idx_t i); -+extern char sd_char_at (string_desc_t s, idx_t i); - #endif - - /* Return a read-only view of the bytes of S. */ - #if 0 /* Defined inline below. */ --extern const char * string_desc_data (string_desc_t s); -+extern const char * sd_data (string_desc_t s); - #endif - - /* Return true if S is the empty string. */ - #if 0 /* Defined inline below. */ --extern bool string_desc_is_empty (string_desc_t s); -+extern bool sd_is_empty (string_desc_t s); - #endif - - /* Return true if A and B are equal. */ --extern bool string_desc_equals (string_desc_t a, string_desc_t b); -+extern bool sd_equals (string_desc_t a, string_desc_t b); - - /* Return true if S starts with PREFIX. */ --extern bool string_desc_startswith (string_desc_t s, string_desc_t prefix); -+extern bool sd_startswith (string_desc_t s, string_desc_t prefix); - - /* Return true if S ends with SUFFIX. */ --extern bool string_desc_endswith (string_desc_t s, string_desc_t suffix); -+extern bool sd_endswith (string_desc_t s, string_desc_t suffix); - - /* Return > 0, == 0, or < 0 if A > B, A == B, A < B. - This uses a lexicographic ordering, where the bytes are compared as - 'unsigned char'. */ --extern int string_desc_cmp (string_desc_t a, string_desc_t b); -+extern int sd_cmp (string_desc_t a, string_desc_t b); - - /* Return > 0, == 0, or < 0 if A > B, A == B, A < B. - Either A or B must be entirely ASCII. - This uses a lexicographic ordering, where the bytes are compared as - 'unsigned char', ignoring case, in the "C" locale. */ --extern int string_desc_c_casecmp (string_desc_t a, string_desc_t b); -+extern int sd_c_casecmp (string_desc_t a, string_desc_t b); - - /* Return the index of the first occurrence of C in S, - or -1 if there is none. */ --extern ptrdiff_t string_desc_index (string_desc_t s, char c); -+extern ptrdiff_t sd_index (string_desc_t s, char c); - - /* Return the index of the last occurrence of C in S, - or -1 if there is none. */ --extern ptrdiff_t string_desc_last_index (string_desc_t s, char c); -+extern ptrdiff_t sd_last_index (string_desc_t s, char c); - - /* Return the index of the first occurrence of NEEDLE in HAYSTACK, - or -1 if there is none. */ --extern ptrdiff_t string_desc_contains (string_desc_t haystack, string_desc_t needle); -+extern ptrdiff_t sd_contains (string_desc_t haystack, string_desc_t needle); - - /* Return an empty string. */ --extern string_desc_t string_desc_new_empty (void); -+extern string_desc_t sd_new_empty (void); - - /* Construct and return a string of length N, at the given memory address. */ --extern string_desc_t string_desc_new_addr (idx_t n, char *addr); -+extern string_desc_t sd_new_addr (idx_t n, char *addr); - - /* Return a string that represents the C string S, of length strlen (S). */ --extern string_desc_t string_desc_from_c (const char *s); -+extern string_desc_t sd_from_c (const char *s); - - /* Return the substring of S, starting at offset START and ending at offset END. - START must be <= END. - The result is of length END - START. - The result must not be freed (since its storage is part of the storage - of S). */ --extern string_desc_t string_desc_substring (string_desc_t s, idx_t start, idx_t end); -+extern string_desc_t sd_substring (string_desc_t s, idx_t start, idx_t end); - - /* Output S to the file descriptor FD. - Return 0 if successful. - Upon error, return -1 with errno set. */ --extern int string_desc_write (int fd, string_desc_t s); -+extern int sd_write (int fd, string_desc_t s); - - /* Output S to the FILE stream FP. - Return 0 if successful. - Upon error, return -1. */ --extern int string_desc_fwrite (FILE *fp, string_desc_t s); -+extern int sd_fwrite (FILE *fp, string_desc_t s); - - - /* ==== Memory-allocating operations on string descriptors ==== */ -@@ -153,61 +153,61 @@ extern int string_desc_fwrite (FILE *fp, - Return 0 if successful. - Upon error, return -1 with errno set. */ - _GL_ATTRIBUTE_NODISCARD --extern int string_desc_new (string_desc_t *resultp, idx_t n); -+extern int sd_new (string_desc_t *resultp, idx_t n); - - /* Construct a string of length N, filled with C. - Return 0 if successful. - Upon error, return -1 with errno set. */ - _GL_ATTRIBUTE_NODISCARD --extern int string_desc_new_filled (string_desc_t *resultp, idx_t n, char c); -+extern int sd_new_filled (string_desc_t *resultp, idx_t n, char c); - - /* Construct a copy of string S. - Return 0 if successful. - Upon error, return -1 with errno set. */ - _GL_ATTRIBUTE_NODISCARD --extern int string_desc_copy (string_desc_t *resultp, string_desc_t s); -+extern int sd_copy (string_desc_t *resultp, string_desc_t s); - - /* Construct the concatenation of N strings. N must be > 0. - Return 0 if successful. - Upon error, return -1 with errno set. */ - _GL_ATTRIBUTE_NODISCARD --extern int string_desc_concat (string_desc_t *resultp, idx_t n, string_desc_t string1, ...); -+extern int sd_concat (string_desc_t *resultp, idx_t n, string_desc_t string1, ...); - - /* Construct a copy of string S, as a NUL-terminated C string. - Return it is successful. - Upon error, return NULL with errno set. */ --extern char * string_desc_c (string_desc_t s) _GL_ATTRIBUTE_DEALLOC_FREE; -+extern char * sd_c (string_desc_t s) _GL_ATTRIBUTE_DEALLOC_FREE; - - - /* ==== Operations with side effects on string descriptors ==== */ - - /* Overwrite the byte at index I of string S with C. - I must be < length(S). */ --extern void string_desc_set_char_at (string_desc_t s, idx_t i, char c); -+extern void sd_set_char_at (string_desc_t s, idx_t i, char c); - - /* Fill part of S, starting at offset START and ending at offset END, - with copies of C. - START must be <= END. */ --extern void string_desc_fill (string_desc_t s, idx_t start, idx_t end, char c); -+extern void sd_fill (string_desc_t s, idx_t start, idx_t end, char c); - - /* Overwrite part of S with T, starting at offset START. - START + length(T) must be <= length (S). */ --extern void string_desc_overwrite (string_desc_t s, idx_t start, string_desc_t t); -+extern void sd_overwrite (string_desc_t s, idx_t start, string_desc_t t); - - /* Free S. */ --extern void string_desc_free (string_desc_t s); -+extern void sd_free (string_desc_t s); - - - /* ==== Inline function definitions ==== */ - - GL_STRING_DESC_INLINE idx_t --string_desc_length (string_desc_t s) -+sd_length (string_desc_t s) - { - return s._nbytes; - } - - GL_STRING_DESC_INLINE char --string_desc_char_at (string_desc_t s, idx_t i) -+sd_char_at (string_desc_t s, idx_t i) - { - if (!(i >= 0 && i < s._nbytes)) - /* Invalid argument. */ -@@ -216,13 +216,13 @@ string_desc_char_at (string_desc_t s, id - } - - GL_STRING_DESC_INLINE const char * --string_desc_data (string_desc_t s) -+sd_data (string_desc_t s) - { - return s._data; - } - - GL_STRING_DESC_INLINE bool --string_desc_is_empty (string_desc_t s) -+sd_is_empty (string_desc_t s) - { - return s._nbytes == 0; - } ---- a/lib/xstring-buffer.c -+++ b/lib/xstring-buffer.c -@@ -59,10 +59,10 @@ sb_xdupfree (struct string_buffer *buffe - if (buffer->error) - { - sb_free (buffer); -- return string_desc_new_addr (0, NULL); -+ return sd_new_addr (0, NULL); - } - string_desc_t contents = sb_dupfree (buffer); -- if (string_desc_data (contents) == NULL) -+ if (sd_data (contents) == NULL) - xalloc_die (); - return contents; - } ---- a/lib/xstring-desc.c -+++ b/lib/xstring-desc.c -@@ -22,7 +22,7 @@ - #include "ialloc.h" - - string_desc_t --xstring_desc_concat (idx_t n, string_desc_t string1, ...) -+xsd_concat (idx_t n, string_desc_t string1, ...) - { - if (n <= 0) - /* Invalid argument. */ ---- a/lib/xstring-desc.h -+++ b/lib/xstring-desc.h -@@ -43,53 +43,53 @@ extern "C" { - - /* Return a string of length N, with uninitialized contents. */ - #if 0 /* Defined inline below. */ --extern string_desc_t xstring_desc_new (idx_t n); -+extern string_desc_t xsd_new (idx_t n); - #endif - - /* Return a string of length N, filled with C. */ - #if 0 /* Defined inline below. */ --extern string_desc_t xstring_desc_new_filled (idx_t n, char c); -+extern string_desc_t xsd_new_filled (idx_t n, char c); - #endif - - /* Return a copy of string S. */ - #if 0 /* Defined inline below. */ --extern string_desc_t xstring_desc_copy (string_desc_t s); -+extern string_desc_t xsd_copy (string_desc_t s); - #endif - - /* Return the concatenation of N strings. N must be > 0. */ --extern string_desc_t xstring_desc_concat (idx_t n, string_desc_t string1, ...); -+extern string_desc_t xsd_concat (idx_t n, string_desc_t string1, ...); - - /* Construct and return a copy of string S, as a NUL-terminated C string. */ - #if 0 /* Defined inline below. */ --extern char * xstring_desc_c (string_desc_t s) _GL_ATTRIBUTE_DEALLOC_FREE; -+extern char * xsd_c (string_desc_t s) _GL_ATTRIBUTE_DEALLOC_FREE; - #endif - - - /* ==== Inline function definitions ==== */ - - GL_XSTRING_DESC_INLINE string_desc_t --xstring_desc_new (idx_t n) -+xsd_new (idx_t n) - { - string_desc_t result; -- if (string_desc_new (&result, n) < 0) -+ if (sd_new (&result, n) < 0) - xalloc_die (); - return result; - } - - GL_XSTRING_DESC_INLINE string_desc_t --xstring_desc_new_filled (idx_t n, char c) -+xsd_new_filled (idx_t n, char c) - { - string_desc_t result; -- if (string_desc_new_filled (&result, n, c) < 0) -+ if (sd_new_filled (&result, n, c) < 0) - xalloc_die (); - return result; - } - - GL_XSTRING_DESC_INLINE string_desc_t --xstring_desc_copy (string_desc_t s) -+xsd_copy (string_desc_t s) - { - string_desc_t result; -- if (string_desc_copy (&result, s) < 0) -+ if (sd_copy (&result, s) < 0) - xalloc_die (); - return result; - } -@@ -97,9 +97,9 @@ xstring_desc_copy (string_desc_t s) - GL_XSTRING_DESC_INLINE - _GL_ATTRIBUTE_DEALLOC_FREE - char * --xstring_desc_c (string_desc_t s) -+xsd_c (string_desc_t s) - { -- char *result = string_desc_c (s); -+ char *result = sd_c (s); - if (result == NULL) - xalloc_die (); - return result; ---- a/tests/test-string-desc-quotearg.c -+++ b/tests/test-string-desc-quotearg.c -@@ -28,75 +28,75 @@ - int - main (void) - { -- string_desc_t s1 = string_desc_from_c ("Hello world!"); -- string_desc_t s2 = string_desc_new_addr (21, "The\0quick\0brown\0\0fox"); -+ string_desc_t s1 = sd_from_c ("Hello world!"); -+ string_desc_t s2 = sd_new_addr (21, "The\0quick\0brown\0\0fox"); - -- /* Test string_desc_quotearg_buffer. */ -+ /* Test sd_quotearg_buffer. */ - { - char buf[80]; -- size_t n = string_desc_quotearg_buffer (buf, sizeof (buf), s2, NULL); -+ size_t n = sd_quotearg_buffer (buf, sizeof (buf), s2, NULL); - ASSERT (n == 21); - ASSERT (memcmp (buf, "The\0quick\0brown\0\0fox", n) == 0); - } - -- /* Test string_desc_quotearg_alloc. */ -+ /* Test sd_quotearg_alloc. */ - { - size_t n; -- char *ret = string_desc_quotearg_alloc (s2, &n, NULL); -+ char *ret = sd_quotearg_alloc (s2, &n, NULL); - ASSERT (n == 21); - ASSERT (memcmp (ret, "The\0quick\0brown\0\0fox", n) == 0); - free (ret); - } - -- /* Test string_desc_quotearg_n. */ -+ /* Test sd_quotearg_n. */ - { -- char *ret = string_desc_quotearg_n (1, s2); -+ char *ret = sd_quotearg_n (1, s2); - ASSERT (memcmp (ret, "Thequickbrownfox", 16 + 1) == 0); - } - -- /* Test string_desc_quotearg. */ -+ /* Test sd_quotearg. */ - { -- char *ret = string_desc_quotearg (s2); -+ char *ret = sd_quotearg (s2); - ASSERT (memcmp (ret, "Thequickbrownfox", 16 + 1) == 0); - } - -- /* Test string_desc_quotearg_n_style. */ -+ /* Test sd_quotearg_n_style. */ - { -- char *ret = string_desc_quotearg_n_style (1, clocale_quoting_style, s2); -+ char *ret = sd_quotearg_n_style (1, clocale_quoting_style, s2); - ASSERT (memcmp (ret, "\"The\\0quick\\0brown\\0\\0fox\\0\"", 28 + 1) == 0 - || /* if the locale has UTF-8 encoding */ - memcmp (ret, "\342\200\230The\\0quick\\0brown\\0\\0fox\\0\342\200\231", 32 + 1) == 0); - } - -- /* Test string_desc_quotearg_style. */ -+ /* Test sd_quotearg_style. */ - { -- char *ret = string_desc_quotearg_style (clocale_quoting_style, s2); -+ char *ret = sd_quotearg_style (clocale_quoting_style, s2); - ASSERT (memcmp (ret, "\"The\\0quick\\0brown\\0\\0fox\\0\"", 28 + 1) == 0 - || /* if the locale has UTF-8 encoding */ - memcmp (ret, "\342\200\230The\\0quick\\0brown\\0\\0fox\\0\342\200\231", 32 + 1) == 0); - } - -- /* Test string_desc_quotearg_char. */ -+ /* Test sd_quotearg_char. */ - { -- char *ret = string_desc_quotearg_char (s1, ' '); -+ char *ret = sd_quotearg_char (s1, ' '); - ASSERT (memcmp (ret, "Hello world!", 12 + 1) == 0); /* ' ' not quoted?! */ - } - -- /* Test string_desc_quotearg_colon. */ -+ /* Test sd_quotearg_colon. */ - { -- char *ret = string_desc_quotearg_colon (string_desc_from_c ("a:b")); -+ char *ret = sd_quotearg_colon (sd_from_c ("a:b")); - ASSERT (memcmp (ret, "a:b", 3 + 1) == 0); /* ':' not quoted?! */ - } - -- /* Test string_desc_quotearg_n_custom. */ -+ /* Test sd_quotearg_n_custom. */ - { -- char *ret = string_desc_quotearg_n_custom (2, "<", ">", s1); -+ char *ret = sd_quotearg_n_custom (2, "<", ">", s1); - ASSERT (memcmp (ret, "", 14 + 1) == 0); - } - -- /* Test string_desc_quotearg_n_custom. */ -+ /* Test sd_quotearg_n_custom. */ - { -- char *ret = string_desc_quotearg_custom ("[[", "]]", s1); -+ char *ret = sd_quotearg_custom ("[[", "]]", s1); - ASSERT (memcmp (ret, "[[Hello world!]]", 16 + 1) == 0); - } - ---- a/tests/test-string-desc.sh -+++ b/tests/test-string-desc.sh -@@ -6,7 +6,7 @@ ${CHECKER} test-string-desc${EXEEXT} tes - printf 'Hello world!The\0quick\0brown\0\0fox\0' > test-string-desc.ok - - : "${DIFF=diff}" --${DIFF} test-string-desc.ok test-string-desc-1.tmp || { echo "string_desc_fwrite KO" 1>&2; Exit 1; } --${DIFF} test-string-desc.ok test-string-desc-3.tmp || { echo "string_desc_write KO" 1>&2; Exit 1; } -+${DIFF} test-string-desc.ok test-string-desc-1.tmp || { echo "sd_fwrite KO" 1>&2; Exit 1; } -+${DIFF} test-string-desc.ok test-string-desc-3.tmp || { echo "sd_write KO" 1>&2; Exit 1; } - - Exit 0 ---- a/tests/test-xstring-desc.c -+++ b/tests/test-xstring-desc.c -@@ -28,53 +28,53 @@ - int - main (void) - { -- string_desc_t s0 = string_desc_new_empty (); -- string_desc_t s1 = string_desc_from_c ("Hello world!"); -- string_desc_t s2 = string_desc_new_addr (21, "The\0quick\0brown\0\0fox"); -+ string_desc_t s0 = sd_new_empty (); -+ string_desc_t s1 = sd_from_c ("Hello world!"); -+ string_desc_t s2 = sd_new_addr (21, "The\0quick\0brown\0\0fox"); - -- /* Test xstring_desc_new. */ -- string_desc_t s4 = xstring_desc_new (5); -- string_desc_set_char_at (s4, 0, 'H'); -- string_desc_set_char_at (s4, 4, 'o'); -- string_desc_set_char_at (s4, 1, 'e'); -- string_desc_fill (s4, 2, 4, 'l'); -- ASSERT (string_desc_length (s4) == 5); -- ASSERT (string_desc_startswith (s1, s4)); -+ /* Test xsd_new. */ -+ string_desc_t s4 = xsd_new (5); -+ sd_set_char_at (s4, 0, 'H'); -+ sd_set_char_at (s4, 4, 'o'); -+ sd_set_char_at (s4, 1, 'e'); -+ sd_fill (s4, 2, 4, 'l'); -+ ASSERT (sd_length (s4) == 5); -+ ASSERT (sd_startswith (s1, s4)); - -- /* Test xstring_desc_new_filled. */ -- string_desc_t s5 = xstring_desc_new_filled (5, 'l'); -- string_desc_set_char_at (s5, 0, 'H'); -- string_desc_set_char_at (s5, 4, 'o'); -- string_desc_set_char_at (s5, 1, 'e'); -- ASSERT (string_desc_length (s5) == 5); -- ASSERT (string_desc_startswith (s1, s5)); -+ /* Test xsd_new_filled. */ -+ string_desc_t s5 = xsd_new_filled (5, 'l'); -+ sd_set_char_at (s5, 0, 'H'); -+ sd_set_char_at (s5, 4, 'o'); -+ sd_set_char_at (s5, 1, 'e'); -+ ASSERT (sd_length (s5) == 5); -+ ASSERT (sd_startswith (s1, s5)); - -- /* Test xstring_desc_copy. */ -+ /* Test xsd_copy. */ - { -- string_desc_t s6 = xstring_desc_copy (s0); -- ASSERT (string_desc_is_empty (s6)); -- string_desc_free (s6); -+ string_desc_t s6 = xsd_copy (s0); -+ ASSERT (sd_is_empty (s6)); -+ sd_free (s6); - } - { -- string_desc_t s6 = xstring_desc_copy (s2); -- ASSERT (string_desc_equals (s6, s2)); -- string_desc_free (s6); -+ string_desc_t s6 = xsd_copy (s2); -+ ASSERT (sd_equals (s6, s2)); -+ sd_free (s6); - } - -- /* Test xstring_desc_concat. */ -+ /* Test xsd_concat. */ - { - string_desc_t s8 = -- xstring_desc_concat (3, string_desc_new_addr (10, "The\0quick"), -- string_desc_new_addr (7, "brown\0"), -- string_desc_new_addr (4, "fox"), -- string_desc_new_addr (7, "unused")); -- ASSERT (string_desc_equals (s8, s2)); -- string_desc_free (s8); -+ xsd_concat (3, sd_new_addr (10, "The\0quick"), -+ sd_new_addr (7, "brown\0"), -+ sd_new_addr (4, "fox"), -+ sd_new_addr (7, "unused")); -+ ASSERT (sd_equals (s8, s2)); -+ sd_free (s8); - } - -- /* Test xstring_desc_c. */ -+ /* Test xsd_c. */ - { -- char *ptr = xstring_desc_c (s2); -+ char *ptr = xsd_c (s2); - ASSERT (ptr != NULL); - ASSERT (memcmp (ptr, "The\0quick\0brown\0\0fox\0", 22) == 0); - free (ptr); diff --git a/tools/gnulib/patches/796-vc-mtime-less-read.patch b/tools/gnulib/patches/796-vc-mtime-less-read.patch deleted file mode 100644 index 3fabe103695..00000000000 --- a/tools/gnulib/patches/796-vc-mtime-less-read.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 60cd34886c2c9f509974239fcf64a61f9a507d14 Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Tue, 25 Feb 2025 09:04:28 +0100 -Subject: [PATCH] vc-mtime: Reduce number of read() system calls. - -* lib/vc-mtime.c: Include . -(git_vc_controlled): Read bytes into a buffer, not one-by-one. ---- - ChangeLog | 6 ++++++ - lib/vc-mtime.c | 15 +++++++++++---- - 2 files changed, 17 insertions(+), 4 deletions(-) - ---- a/lib/vc-mtime.c -+++ b/lib/vc-mtime.c -@@ -21,6 +21,7 @@ - /* Specification. */ - #include "vc-mtime.h" - -+#include - #include - #include - -@@ -56,11 +57,17 @@ git_vc_controlled (const char *filename) - return false; - - /* Read the subprocess output, and test whether it is non-empty. */ -- size_t count = 0; -- char c; -+ ptrdiff_t count = 0; - -- while (safe_read (fd[0], &c, 1) > 0) -- count++; -+ for (;;) -+ { -+ char buf[1024]; -+ ptrdiff_t n = safe_read (fd[0], buf, sizeof (buf)); -+ if (n > 0) -+ count += n; -+ else -+ break; -+ } - - close (fd[0]); - diff --git a/tools/gnulib/patches/797-vc-mtime-add-api.patch b/tools/gnulib/patches/797-vc-mtime-add-api.patch deleted file mode 100644 index eeb6636e674..00000000000 --- a/tools/gnulib/patches/797-vc-mtime-add-api.patch +++ /dev/null @@ -1,968 +0,0 @@ -From 78269749030dde23182c29376d1410592436eb5d Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Thu, 1 May 2025 17:26:27 +0200 -Subject: [PATCH] vc-mtime: Add API for more efficient use of git. - -Reported by Serhii Tereshchenko, Arthur, Adam YS, Foucauld Degeorges -at . - -* lib/vc-mtime.h (max_vc_mtime): New declaration. -* lib/vc-mtime.c: Include , , , filename.h, -xalloc.h, xgetcwd.h, xvasprintf.h, gl_map.h, gl_xmap.h, gl_hash_map.h, -hashkey-string.h, unlocked-io.h. -(is_git_present): New function, extracted from vc_mtime. -(vc_mtime): Invoke it. -(MAX_COMMAND_LENGTH, MAX_CMD_LEN): New macros. -(abs_git_checkout): New function, based on execute_and_read_line in -lib/javacomp.c. -(ancestor_level, relativize): New functions. -(struct accumulator): New type. -(accumulate): New function. -(max_vc_mtime): New function. -(test_ancestor_level, test_relativize, main) [TEST]: New functions. -* modules/vc-mtime (Depends-on): Add filename, xalloc, xgetcwd, -canonicalize-lgpl, xvasprintf, str_startswith, map, xmap, hash-map, -hashkey-string, getdelim. ---- - ChangeLog | 23 ++ - lib/vc-mtime.c | 866 +++++++++++++++++++++++++++++++++++++++++++++-- - lib/vc-mtime.h | 7 + - modules/vc-mtime | 11 + - 4 files changed, 886 insertions(+), 21 deletions(-) - ---- a/lib/vc-mtime.c -+++ b/lib/vc-mtime.c -@@ -21,8 +21,11 @@ - /* Specification. */ - #include "vc-mtime.h" - -+#include - #include -+#include - #include -+#include - #include - - #include -@@ -32,11 +35,51 @@ - #include "safe-read.h" - #include "xstrtol.h" - #include "stat-time.h" -+#include "filename.h" -+#include "xalloc.h" -+#include "xgetcwd.h" -+#include "xvasprintf.h" -+#include "gl_map.h" -+#include "gl_xmap.h" -+#include "gl_hash_map.h" -+#include "hashkey-string.h" -+#if USE_UNLOCKED_IO -+# include "unlocked-io.h" -+#endif - #include "gettext.h" - - #define _(msgid) dgettext ("gnulib", msgid) - - -+/* ========================================================================== */ -+ -+/* Determines whether git is present. */ -+static bool -+is_git_present (void) -+{ -+ static bool git_tested; -+ static bool git_present; -+ -+ if (!git_tested) -+ { -+ /* Test for presence of git: -+ "git --version >/dev/null 2>/dev/null" */ -+ const char *argv[3]; -+ int exitstatus; -+ -+ argv[0] = "git"; -+ argv[1] = "--version"; -+ argv[2] = NULL; -+ exitstatus = execute ("git", "git", argv, NULL, NULL, -+ false, false, true, true, -+ true, false, NULL); -+ git_present = (exitstatus == 0); -+ git_tested = true; -+ } -+ -+ return git_present; -+} -+ - /* Determines whether the specified file is under version control. */ - static bool - git_vc_controlled (const char *filename) -@@ -178,27 +221,7 @@ git_mtime (struct timespec *mtime, const - int - vc_mtime (struct timespec *mtime, const char *filename) - { -- static bool git_tested; -- static bool git_present; -- -- if (!git_tested) -- { -- /* Test for presence of git: -- "git --version >/dev/null 2>/dev/null" */ -- const char *argv[3]; -- int exitstatus; -- -- argv[0] = "git"; -- argv[1] = "--version"; -- argv[2] = NULL; -- exitstatus = execute ("git", "git", argv, NULL, NULL, -- false, false, true, true, -- true, false, NULL); -- git_present = (exitstatus == 0); -- git_tested = true; -- } -- -- if (git_present -+ if (is_git_present () - && git_vc_controlled (filename) - && git_unmodified (filename)) - { -@@ -213,3 +236,804 @@ vc_mtime (struct timespec *mtime, const - } - return -1; - } -+ -+/* ========================================================================== */ -+ -+/* Maximum length of a command that is guaranteed to work. */ -+#if defined _WIN32 || defined __CYGWIN__ -+/* Windows */ -+# define MAX_COMMAND_LENGTH 8192 -+#else -+/* Unix platforms */ -+# define MAX_COMMAND_LENGTH 32768 -+#endif -+/* Keep some safe distance to this maximum. */ -+#define MAX_CMD_LEN ((int) (MAX_COMMAND_LENGTH * 0.8)) -+ -+/* Returns the directory name of the git checkout that contains tha current -+ directory, as an absolute file name, or NULL if the current directory is -+ not in a git checkout. */ -+static char * -+abs_git_checkout (void) -+{ -+ /* Run "git rev-parse --show-toplevel 2>/dev/null" and return its output, -+ without the trailing newline. */ -+ const char *argv[4]; -+ pid_t child; -+ int fd[1]; -+ -+ argv[0] = "git"; -+ argv[1] = "rev-parse"; -+ argv[2] = "--show-toplevel"; -+ argv[3] = NULL; -+ child = create_pipe_in ("git", "git", argv, NULL, NULL, -+ DEV_NULL, true, true, false, fd); -+ -+ if (child == -1) -+ return NULL; -+ -+ /* Retrieve its result. */ -+ FILE *fp = fdopen (fd[0], "r"); -+ if (fp == NULL) -+ error (EXIT_FAILURE, errno, _("fdopen() failed")); -+ -+ char *line = NULL; -+ size_t linesize = 0; -+ size_t linelen = getline (&line, &linesize, fp); -+ if (linelen == (size_t)(-1)) -+ { -+ fclose (fp); -+ wait_subprocess (child, "git", true, true, true, false, NULL); -+ return NULL; -+ } -+ else -+ { -+ int exitstatus; -+ -+ if (linelen > 0 && line[linelen - 1] == '\n') -+ line[linelen - 1] = '\0'; -+ -+ /* Read until EOF (otherwise the child process may get a SIGPIPE signal). */ -+ while (getc (fp) != EOF) -+ ; -+ -+ fclose (fp); -+ -+ /* Remove zombie process from process list, and retrieve exit status. */ -+ exitstatus = -+ wait_subprocess (child, "git", true, true, true, false, NULL); -+ if (exitstatus == 0) -+ return line; -+ } -+ free (line); -+ return NULL; -+} -+ -+/* Given an absolute canonicalized directory DIR1 and an absolute canonicalized -+ directory DIR2, returns N where DIR1 = DIR2 "/.." ... "/.." with N times -+ "/..", or -1 if DIR1 is not an ancestor directory of DIR2. */ -+static long -+ancestor_level (const char *dir1, const char *dir2) -+{ -+ if (strcmp (dir1, "/") == 0) -+ dir1 = ""; -+ if (strcmp (dir2, "/") == 0) -+ dir2 = ""; -+ size_t dir1_len = strlen (dir1); -+ if (strncmp (dir1, dir2, dir1_len) == 0) -+ { -+ /* DIR2 starts with DIR1. */ -+ const char *p = dir2 + dir1_len; -+ if (*p == '\0') -+ /* DIR2 and DIR1 are the same. */ -+ return 0; -+ if (ISSLASH (*p)) -+ { -+ /* Return the number of slashes in the tail of DIR2 that starts -+ at P. */ -+ long n = 1; -+ p++; -+ for (; *p != '\0'; p++) -+ if (ISSLASH (*p)) -+ n++; -+ return n; -+ } -+ } -+ return -1; -+} -+ -+/* Given an absolute canolicalized FILENAME that starts with DIR1, returns the -+ same file name relative to DIR2, where DIR1 = DIR2 "/.." ... "/.." with -+ N times "/..", as a freshly allocated string. */ -+static char * -+relativize (const char *filename, -+ unsigned long n, const char *dir1, const char *dir2) -+{ -+ if (strcmp (dir1, "/") == 0) -+ dir1 = ""; -+ size_t dir1_len = strlen (dir1); -+ if (!(strncmp (filename, dir1, dir1_len) == 0 -+ && (filename[dir1_len] == '\0' || ISSLASH (filename[dir1_len])))) -+ /* Invalid argument. */ -+ abort (); -+ if (strcmp (dir2, "/") == 0) -+ dir2 = ""; -+ -+ dir2 += dir1_len; -+ filename += dir1_len; -+ for (;;) -+ { -+ /* Invariant: The result will be N times "../" followed by FILENAME. */ -+ if (*filename == '\0') -+ break; -+ if (!ISSLASH (*filename)) -+ abort (); -+ filename++; -+ if (*dir2 == '\0') -+ break; -+ if (!ISSLASH (*dir2)) -+ abort (); -+ dir2++; -+ /* Skip one component in DIR2. */ -+ const char *dir2_s; -+ for (dir2_s = dir2; *dir2_s != '\0'; dir2_s++) -+ if (ISSLASH (*dir2_s)) -+ break; -+ /* Skip one component in FILENAME, at P. */ -+ const char *filename_s; -+ for (filename_s = filename; *filename_s != '\0'; filename_s++) -+ if (ISSLASH (*filename_s)) -+ break; -+ /* Did the components match? */ -+ if (!(filename_s - filename == dir2_s - dir2 -+ && memcmp (filename, dir2, dir2_s - dir2) == 0)) -+ break; -+ dir2 = dir2_s; -+ filename = filename_s; -+ n--; -+ } -+ -+ if (n == 0 && *filename == '\0') -+ return xstrdup ("."); -+ -+ char *result = (char *) xmalloc (3 * n + strlen (filename) + 1); -+ { -+ char *q = result; -+ for (; n > 0; n--) -+ { -+ q[0] = '.'; q[1] = '.'; q[2] = '/'; q += 3; -+ } -+ strcpy (q, filename); -+ } -+ return result; -+} -+ -+/* Accumulating mtimes. */ -+struct accumulator -+{ -+ bool has_some_mtimes; -+ struct timespec max_of_mtimes; -+}; -+ -+static void -+accumulate (struct accumulator *accu, struct timespec mtime) -+{ -+ if (accu->has_some_mtimes) -+ { -+ /* Compute the maximum of accu->max_of_mtimes and mtime. */ -+ if (accu->max_of_mtimes.tv_sec < mtime.tv_sec -+ || (accu->max_of_mtimes.tv_sec == mtime.tv_sec -+ && accu->max_of_mtimes.tv_nsec < mtime.tv_nsec)) -+ accu->max_of_mtimes = mtime; -+ } -+ else -+ { -+ accu->max_of_mtimes = mtime; -+ accu->has_some_mtimes = true; -+ } -+} -+ -+int -+max_vc_mtime (struct timespec *max_of_mtimes, -+ size_t nfiles, const char * const *filenames) -+{ -+ if (nfiles == 0) -+ /* Invalid argument. */ -+ abort (); -+ -+ struct accumulator accu = { false }; -+ -+ /* Determine which of the specified files are under version control, -+ and which are duplicates. (The case of duplicates is rare, but it needs -+ special attention, because 'git ls-files' eliminates duplicates.) -+ vc_controlled[n] = 1 means that filenames[n] is under version control. -+ vc_controlled[n] = 0 means that filenames[n] is not under version control. -+ vc_controlled[n] = -1 means that filenames[n] is a duplicate. */ -+ signed char *vc_controlled = XNMALLOC (nfiles, signed char); -+ for (size_t n = 0; n < nfiles; n++) -+ vc_controlled[n] = 0; -+ -+ if (is_git_present ()) -+ { -+ /* Since 'git ls-files' produces an error when at least one of the files -+ is outside the git checkout that contains tha current directory, we -+ need to filter out such files. This is most easily done by converting -+ each file name to a canonical file name first and then comparing with -+ the directory name of said git checkout. */ -+ char *git_checkout = abs_git_checkout (); -+ if (git_checkout != NULL) -+ { -+ char *currdir = xgetcwd (); -+ /* git_checkout is expected to be an ancestor directory of the -+ current directory. */ -+ long ancestor = ancestor_level (git_checkout, currdir); -+ if (ancestor >= 0) -+ { -+ char **canonical_filenames = XNMALLOC (nfiles, char *); -+ for (size_t n = 0; n < nfiles; n++) -+ { -+ char *canonical = canonicalize_file_name (filenames[n]); -+ if (canonical == NULL) -+ { -+ if (errno == ENOMEM) -+ xalloc_die (); -+ /* The file filenames[n] does not exist. */ -+ for (size_t k = n; k > 0; ) -+ free (canonical_filenames[--k]); -+ free (canonical_filenames); -+ free (currdir); -+ free (git_checkout); -+ free (vc_controlled); -+ return -1; -+ } -+ canonical_filenames[n] = canonical; -+ } -+ -+ /* Test which of these absolute file names are outside of the -+ git_checkout. */ -+ char *git_checkout_slash = -+ (strcmp (git_checkout, "/") == 0 -+ ? xstrdup (git_checkout) -+ : xasprintf ("%s/", git_checkout)); -+ -+ char **checkout_relative_filenames = XNMALLOC (nfiles, char *); -+ char **currdir_relative_filenames = XNMALLOC (nfiles, char *); -+ for (size_t n = 0; n < nfiles; n++) -+ { -+ if (str_startswith (canonical_filenames[n], git_checkout_slash)) -+ { -+ vc_controlled[n] = 1; -+ checkout_relative_filenames[n] = -+ relativize (canonical_filenames[n], -+ 0, git_checkout, git_checkout); -+ currdir_relative_filenames[n] = -+ relativize (canonical_filenames[n], -+ ancestor, git_checkout, currdir); -+ } -+ else -+ { -+ vc_controlled[n] = 0; -+ checkout_relative_filenames[n] = NULL; -+ currdir_relative_filenames[n] = NULL; -+ } -+ } -+ -+ /* Room for passing arguments to git commands. */ -+ const char **argv = XNMALLOC (6 + nfiles + 1, const char *); -+ -+ { -+ /* Put the relative file names into a hash table. This is needed -+ because 'git ls-files' returns the files in a different order -+ than the one we provide in the command. */ -+ gl_map_t relative_filenames_ht = -+ gl_map_create_empty (GL_HASH_MAP, -+ hashkey_string_equals, hashkey_string_hash, -+ NULL, NULL); -+ for (size_t n = 0; n < nfiles; n++) -+ if (currdir_relative_filenames[n] != NULL) -+ { -+ if (gl_map_get (relative_filenames_ht, currdir_relative_filenames[n]) != NULL) -+ { -+ /* It's already in the table. */ -+ vc_controlled[n] = -1; -+ } -+ else -+ gl_map_put (relative_filenames_ht, currdir_relative_filenames[n], &vc_controlled[n]); -+ } -+ -+ /* Run "git ls-files -c -o -t -z FILE1..." for as many files as -+ possible, and inspect the output. */ -+ size_t n0 = 0; -+ do -+ { -+ size_t i = 0; -+ argv[i++] = "git"; -+ argv[i++] = "ls-files"; -+ argv[i++] = "-c"; -+ argv[i++] = "-o"; -+ argv[i++] = "-t"; -+ argv[i++] = "-z"; -+ size_t i0 = i; -+ -+ size_t n = n0; -+ size_t cmd_len = 25; -+ for (; n < nfiles; n++) -+ { -+ if (vc_controlled[n] == 1) -+ { -+ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN -+ && i > i0) -+ break; -+ argv[i++] = currdir_relative_filenames[n]; -+ cmd_len += 1 + strlen (currdir_relative_filenames[n]); -+ } -+ n++; -+ } -+ if (i > i0) -+ { -+ pid_t child; -+ int fd[1]; -+ -+ argv[i] = NULL; -+ child = create_pipe_in ("git", "git", argv, NULL, NULL, -+ DEV_NULL, true, true, false, fd); -+ if (child == -1) -+ break; -+ -+ /* Read the subprocess output. It is expected to be of the form -+ T1 NUL -+ T2 NUL -+ ... -+ where the relative filenames correspond to the given file -+ names (because we have already relativized them). */ -+ FILE *fp = fdopen (fd[0], "r"); -+ if (fp == NULL) -+ error (EXIT_FAILURE, errno, _("fdopen() failed")); -+ -+ char *fn = NULL; -+ size_t fn_size = 0; -+ for (;;) -+ { -+ int status = fgetc (fp); -+ if (status == EOF) -+ break; -+ /* status is a status tag, as documented in -+ "man git-ls-files". */ -+ -+ int space = fgetc (fp); -+ if (space != ' ') -+ { -+ fprintf (stderr, "vc-mtime: git ls-files output not as expected\n"); -+ break; -+ } -+ -+ if (getdelim (&fn, &fn_size, '\0', fp) == -1) -+ { -+ if (errno == ENOMEM) -+ xalloc_die (); -+ fprintf (stderr, "vc-mtime: failed to read git ls-files output\n"); -+ break; -+ } -+ signed char *vc_controlled_p = -+ (signed char *) gl_map_get (relative_filenames_ht, fn); -+ if (vc_controlled_p == NULL) -+ fprintf (stderr, "vc-mtime: git ls-files returned an unexpected file name: %s\n", fn); -+ else -+ *vc_controlled_p = (status == 'H' ? 1 : 0); -+ } -+ -+ free (fn); -+ fclose (fp); -+ -+ /* Remove zombie process from process list, and retrieve exit status. */ -+ int exitstatus = -+ wait_subprocess (child, "git", false, true, true, false, NULL); -+ if (exitstatus != 0) -+ fprintf (stderr, "vc-mtime: git ls-files failed with exit code %d\n", exitstatus); -+ } -+ n0 = n; -+ } -+ while (n0 < nfiles); -+ -+ gl_map_free (relative_filenames_ht); -+ } -+ -+ { -+ /* Put the relative file names into a hash table. This is needed -+ because 'git diff' returns the files in a different order -+ than the one we provide in the command. */ -+ gl_map_t relative_filenames_ht = -+ gl_map_create_empty (GL_HASH_MAP, -+ hashkey_string_equals, hashkey_string_hash, -+ NULL, NULL); -+ for (size_t n = 0; n < nfiles; n++) -+ if (vc_controlled[n] == 1) -+ { -+ /* No need to test for duplicates here. We have already set -+ vc_controlled[n] to -1 for duplicates, above. */ -+ gl_map_put (relative_filenames_ht, checkout_relative_filenames[n], &vc_controlled[n]); -+ } -+ -+ /* Run "git diff --name-only --no-relative -z HEAD -- FILE1..." for -+ as many files as possible, and inspect the output. */ -+ size_t n0 = 0; -+ do -+ { -+ size_t i = 0; -+ argv[i++] = "git"; -+ argv[i++] = "diff"; -+ argv[i++] = "--name-only"; -+ argv[i++] = "--no-relative"; -+ argv[i++] = "-z"; -+ argv[i++] = "HEAD"; -+ argv[i++] = "--"; -+ size_t i0 = i; -+ -+ size_t n = n0; -+ size_t cmd_len = 46; -+ for (; n < nfiles; n++) -+ { -+ if (vc_controlled[n] == 1) -+ { -+ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN -+ && i > i0) -+ break; -+ argv[i++] = currdir_relative_filenames[n]; -+ cmd_len += 1 + strlen (currdir_relative_filenames[n]); -+ } -+ n++; -+ } -+ if (i > i0) -+ { -+ pid_t child; -+ int fd[1]; -+ -+ argv[i] = NULL; -+ child = create_pipe_in ("git", "git", argv, NULL, NULL, -+ DEV_NULL, true, true, false, fd); -+ if (child == -1) -+ break; -+ -+ /* Read the subprocess output. It is expected to be of the form -+ NUL -+ NUL -+ ... -+ where the relative filenames are relative to the git -+ checkout dir, not to currdir! */ -+ FILE *fp = fdopen (fd[0], "r"); -+ if (fp == NULL) -+ error (EXIT_FAILURE, errno, _("fdopen() failed")); -+ -+ char *fn = NULL; -+ size_t fn_size = 0; -+ for (;;) -+ { -+ /* Test for EOF. */ -+ int c = fgetc (fp); -+ if (c == EOF) -+ break; -+ ungetc (c, fp); -+ -+ if (getdelim (&fn, &fn_size, '\0', fp) == -1) -+ { -+ if (errno == ENOMEM) -+ xalloc_die (); -+ fprintf (stderr, "vc-mtime: failed to read git diff output\n"); -+ break; -+ } -+ signed char *vc_controlled_p = -+ (signed char *) gl_map_get (relative_filenames_ht, fn); -+ if (vc_controlled_p == NULL) -+ fprintf (stderr, "vc-mtime: git diff returned an unexpected file name: %s\n", fn); -+ else -+ /* filenames[n] is under version control but is modified. -+ Treat it like a file not under version control. */ -+ *vc_controlled_p = 0; -+ } -+ -+ free (fn); -+ fclose (fp); -+ -+ /* Remove zombie process from process list, and retrieve exit status. */ -+ int exitstatus = -+ wait_subprocess (child, "git", false, true, true, false, NULL); -+ if (exitstatus != 0) -+ fprintf (stderr, "vc-mtime: git diff failed with exit code %d\n", exitstatus); -+ } -+ n0 = n; -+ } -+ while (n0 < nfiles); -+ -+ gl_map_free (relative_filenames_ht); -+ } -+ -+ { -+ /* Run "git log -1 --format=%ct -- FILE1...". It prints the -+ time of last modification (the 'CommitDate', not the -+ 'AuthorDate' which merely represents the time at which the -+ author locally committed the first version of the change), -+ as the number of seconds since the Epoch. The '--' option -+ is for the case that the specified file was removed. */ -+ size_t n0 = 0; -+ do -+ { -+ size_t i = 0; -+ argv[i++] = "git"; -+ argv[i++] = "log"; -+ argv[i++] = "-1"; -+ argv[i++] = "--format=%ct"; -+ argv[i++] = "--"; -+ size_t i0 = i; -+ -+ size_t n = n0; -+ size_t cmd_len = 27; -+ for (; n < nfiles; n++) -+ { -+ if (vc_controlled[n] == 1) -+ { -+ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN -+ && i > i0) -+ break; -+ argv[i++] = currdir_relative_filenames[n]; -+ cmd_len += 1 + strlen (currdir_relative_filenames[n]); -+ } -+ n++; -+ } -+ if (i > i0) -+ { -+ pid_t child; -+ int fd[1]; -+ -+ argv[i] = NULL; -+ child = create_pipe_in ("git", "git", argv, NULL, NULL, -+ DEV_NULL, true, true, false, fd); -+ if (child == -1) -+ break; -+ -+ /* Read the subprocess output. It is expected to be a -+ single line, containing a positive integer. */ -+ FILE *fp = fdopen (fd[0], "r"); -+ if (fp == NULL) -+ error (EXIT_FAILURE, errno, _("fdopen() failed")); -+ -+ char *line = NULL; -+ size_t linesize = 0; -+ size_t linelen = getline (&line, &linesize, fp); -+ if (linelen == (size_t)(-1)) -+ { -+ if (errno == ENOMEM) -+ xalloc_die (); -+ fprintf (stderr, "vc-mtime: failed to read git log output\n"); -+ git_log_fail1: -+ free (line); -+ fclose (fp); -+ wait_subprocess (child, "git", true, false, true, false, NULL); -+ git_log_fail2: -+ free (argv); -+ for (size_t k = nfiles; k > 0; ) -+ free (currdir_relative_filenames[--k]); -+ free (currdir_relative_filenames); -+ for (size_t k = nfiles; k > 0; ) -+ free (checkout_relative_filenames[--k]); -+ free (checkout_relative_filenames); -+ free (git_checkout_slash); -+ for (size_t k = nfiles; k > 0; ) -+ free (canonical_filenames[--k]); -+ free (canonical_filenames); -+ free (currdir); -+ free (git_checkout); -+ free (vc_controlled); -+ return -1; -+ } -+ if (linelen > 0 && line[linelen - 1] == '\n') -+ line[linelen - 1] = '\0'; -+ -+ char *endptr; -+ unsigned long git_log_time; -+ if (!(xstrtoul (line, &endptr, 10, &git_log_time, NULL) == LONGINT_OK -+ && endptr == line + strlen (line))) -+ { -+ fprintf (stderr, "vc-mtime: git log output not as expected\n"); -+ goto git_log_fail1; -+ } -+ -+ struct timespec mtime; -+ mtime.tv_sec = git_log_time; -+ mtime.tv_nsec = 0; -+ accumulate (&accu, mtime); -+ -+ free (line); -+ fclose (fp); -+ -+ /* Remove zombie process from process list, and retrieve exit status. */ -+ int exitstatus = -+ wait_subprocess (child, "git", false, true, true, false, NULL); -+ if (exitstatus != 0) -+ { -+ fprintf (stderr, "vc-mtime: git log failed with exit code %d\n", exitstatus); -+ goto git_log_fail2; -+ } -+ } -+ n0 = n; -+ } -+ while (n0 < nfiles); -+ } -+ -+ free (argv); -+ for (size_t k = nfiles; k > 0; ) -+ free (currdir_relative_filenames[--k]); -+ free (currdir_relative_filenames); -+ for (size_t k = nfiles; k > 0; ) -+ free (checkout_relative_filenames[--k]); -+ free (checkout_relative_filenames); -+ free (git_checkout_slash); -+ for (size_t k = nfiles; k > 0; ) -+ free (canonical_filenames[--k]); -+ free (canonical_filenames); -+ } -+ free (currdir); -+ } -+ free (git_checkout); -+ } -+ -+ /* For the files that are not under version control, or that are modified -+ compared to HEAD, use the file's time stamp. */ -+ for (size_t n = 0; n < nfiles; n++) -+ if (vc_controlled[n] == 0) -+ { -+ struct stat statbuf; -+ if (stat (filenames[n], &statbuf) < 0) -+ { -+ free (vc_controlled); -+ return -1; -+ } -+ -+ struct timespec mtime = get_stat_mtime (&statbuf); -+ accumulate (&accu, mtime); -+ } -+ -+ free (vc_controlled); -+ -+ /* Since nfiles > 0, we must have accumulated at least one mtime. */ -+ if (!accu.has_some_mtimes) -+ abort (); -+ *max_of_mtimes = accu.max_of_mtimes; -+ return 0; -+} -+ -+/* ========================================================================== */ -+ -+#ifdef TEST -+ -+#include -+#include -+#include -+ -+/* Some unit tests for internal functions. */ -+ -+static void -+test_ancestor_level (void) -+{ -+ assert (ancestor_level ("/home/user/projects/gnulib", "/home/user/projects/gnulib") == 0); -+ assert (ancestor_level ("/", "/") == 0); -+ -+ assert (ancestor_level ("/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto") == 2); -+ assert (ancestor_level ("/", "/home/user") == 2); -+ -+ assert (ancestor_level ("/home/user/.local", "/home/user/projects/gnulib") == -1); -+ assert (ancestor_level ("/.local", "/home/user") == -1); -+ assert (ancestor_level ("/.local", "/") == -1); -+} -+ -+static void -+test_relativize (void) -+{ -+ assert (strcmp (relativize ("/home/user/projects/gnulib", -+ 0, "/home/user/projects/gnulib", "/home/user/projects/gnulib"), -+ ".") == 0); -+ assert (strcmp (relativize ("/home/user/projects/gnulib/NEWS", -+ 0, "/home/user/projects/gnulib", "/home/user/projects/gnulib"), -+ "NEWS") == 0); -+ assert (strcmp (relativize ("/home/user/projects/gnulib/doc/Makefile", -+ 0, "/home/user/projects/gnulib", "/home/user/projects/gnulib"), -+ "doc/Makefile") == 0); -+ -+ assert (strcmp (relativize ("/", -+ 0, "/", "/"), -+ ".") == 0); -+ assert (strcmp (relativize ("/swapfile", -+ 0, "/", "/"), -+ "swapfile") == 0); -+ assert (strcmp (relativize ("/etc/passwd", -+ 0, "/", "/"), -+ "etc/passwd") == 0); -+ -+ assert (strcmp (relativize ("/home/user/projects/gnulib", -+ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"), -+ "../../") == 0); -+ assert (strcmp (relativize ("/home/user/projects/gnulib/lib", -+ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"), -+ "../") == 0); -+ assert (strcmp (relativize ("/home/user/projects/gnulib/lib/crypto", -+ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"), -+ ".") == 0); -+ assert (strcmp (relativize ("/home/user/projects/gnulib/lib/malloc", -+ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"), -+ "../malloc") == 0); -+ assert (strcmp (relativize ("/home/user/projects/gnulib/lib/cr", -+ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"), -+ "../cr") == 0); -+ assert (strcmp (relativize ("/home/user/projects/gnulib/lib/cryptography", -+ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"), -+ "../cryptography") == 0); -+ assert (strcmp (relativize ("/home/user/projects/gnulib/doc", -+ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"), -+ "../../doc") == 0); -+ assert (strcmp (relativize ("/home/user/projects/gnulib/doc/Makefile", -+ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"), -+ "../../doc/Makefile") == 0); -+ -+ assert (strcmp (relativize ("/", -+ 2, "/", "/home/user"), -+ "../../") == 0); -+ assert (strcmp (relativize ("/home", -+ 2, "/", "/home/user"), -+ "../") == 0); -+ assert (strcmp (relativize ("/home/user", -+ 2, "/", "/home/user"), -+ ".") == 0); -+ assert (strcmp (relativize ("/home/root", -+ 2, "/", "/home/user"), -+ "../root") == 0); -+ assert (strcmp (relativize ("/home/us", -+ 2, "/", "/home/user"), -+ "../us") == 0); -+ assert (strcmp (relativize ("/home/users", -+ 2, "/", "/home/user"), -+ "../users") == 0); -+ assert (strcmp (relativize ("/etc", -+ 2, "/", "/home/user"), -+ "../../etc") == 0); -+ assert (strcmp (relativize ("/etc/passwd", -+ 2, "/", "/home/user"), -+ "../../etc/passwd") == 0); -+} -+ -+/* Usage: ./a.out FILE[...] -+ */ -+int -+main (int argc, char *argv[]) -+{ -+ test_ancestor_level (); -+ test_relativize (); -+ -+ if (argc == 1) -+ { -+ fprintf (stderr, "Usage: ./a.out FILE[...]\n"); -+ return 1; -+ } -+ struct timespec mtime; -+ int ret = max_vc_mtime (&mtime, argc - 1, (const char **) argv + 1); -+ if (ret == 0) -+ { -+ time_t t = mtime.tv_sec; -+ struct tm *gmt = gmtime (&t); -+ printf ("mtime = %04d-%02d-%02d %02d:%02d:%02d UTC\n", -+ gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday, -+ gmt->tm_hour, gmt->tm_min, gmt->tm_sec); -+ return 0; -+ } -+ else -+ { -+ printf ("failed\n"); -+ return 1; -+ } -+} -+ -+/* -+ * Local Variables: -+ * compile-command: "gcc -ggdb -DTEST -Wall -I. -I.. vc-mtime.c libgnu.a" -+ * End: -+ */ -+ -+#endif ---- a/lib/vc-mtime.h -+++ b/lib/vc-mtime.h -@@ -90,6 +90,13 @@ extern "C" { - Upon failure, it returns -1. */ - extern int vc_mtime (struct timespec *mtime, const char *filename); - -+/* Determines the maximum of the version-controlled modification times of -+ FILENAMES[0..NFILES-1], and returns 0. -+ Upon failure, it returns -1. -+ NFILES must be > 0. */ -+extern int max_vc_mtime (struct timespec *max_of_mtimes, -+ size_t nfiles, const char * const *filenames); -+ - #ifdef __cplusplus - } - #endif ---- a/modules/vc-mtime -+++ b/modules/vc-mtime -@@ -16,6 +16,17 @@ error - getline - xstrtol - stat-time -+filename -+xalloc -+xgetcwd -+canonicalize-lgpl -+xvasprintf -+str_startswith -+map -+xmap -+hash-map -+hashkey-string -+getdelim - gettext-h - gnulib-i18n - diff --git a/tools/gnulib/patches/798-vc-mtime-add-api.patch b/tools/gnulib/patches/798-vc-mtime-add-api.patch deleted file mode 100644 index 2cf7edab4ee..00000000000 --- a/tools/gnulib/patches/798-vc-mtime-add-api.patch +++ /dev/null @@ -1,91 +0,0 @@ -From f4c40c2d6aabef8e587176bbf5226c8bc6649574 Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Fri, 2 May 2025 02:43:23 +0200 -Subject: [PATCH] vc-mtime: Add API for more efficient use of git, part 2. - -* lib/vc-mtime.c (max_vc_mtime): Don't skip the odd-numbered arguments. ---- - ChangeLog | 5 +++++ - lib/vc-mtime.c | 57 +++++++++++++++++++++----------------------------- - 2 files changed, 29 insertions(+), 33 deletions(-) - ---- a/lib/vc-mtime.c -+++ b/lib/vc-mtime.c -@@ -558,17 +558,14 @@ max_vc_mtime (struct timespec *max_of_mt - size_t n = n0; - size_t cmd_len = 25; - for (; n < nfiles; n++) -- { -- if (vc_controlled[n] == 1) -- { -- if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN -- && i > i0) -- break; -- argv[i++] = currdir_relative_filenames[n]; -- cmd_len += 1 + strlen (currdir_relative_filenames[n]); -- } -- n++; -- } -+ if (vc_controlled[n] == 1) -+ { -+ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN -+ && i > i0) -+ break; -+ argv[i++] = currdir_relative_filenames[n]; -+ cmd_len += 1 + strlen (currdir_relative_filenames[n]); -+ } - if (i > i0) - { - pid_t child; -@@ -672,17 +669,14 @@ max_vc_mtime (struct timespec *max_of_mt - size_t n = n0; - size_t cmd_len = 46; - for (; n < nfiles; n++) -- { -- if (vc_controlled[n] == 1) -- { -- if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN -- && i > i0) -- break; -- argv[i++] = currdir_relative_filenames[n]; -- cmd_len += 1 + strlen (currdir_relative_filenames[n]); -- } -- n++; -- } -+ if (vc_controlled[n] == 1) -+ { -+ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN -+ && i > i0) -+ break; -+ argv[i++] = currdir_relative_filenames[n]; -+ cmd_len += 1 + strlen (currdir_relative_filenames[n]); -+ } - if (i > i0) - { - pid_t child; -@@ -768,17 +762,14 @@ max_vc_mtime (struct timespec *max_of_mt - size_t n = n0; - size_t cmd_len = 27; - for (; n < nfiles; n++) -- { -- if (vc_controlled[n] == 1) -- { -- if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN -- && i > i0) -- break; -- argv[i++] = currdir_relative_filenames[n]; -- cmd_len += 1 + strlen (currdir_relative_filenames[n]); -- } -- n++; -- } -+ if (vc_controlled[n] == 1) -+ { -+ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN -+ && i > i0) -+ break; -+ argv[i++] = currdir_relative_filenames[n]; -+ cmd_len += 1 + strlen (currdir_relative_filenames[n]); -+ } - if (i > i0) - { - pid_t child; diff --git a/tools/gnulib/patches/799-vc-mtime-old-git.patch b/tools/gnulib/patches/799-vc-mtime-old-git.patch deleted file mode 100644 index 4c2082504b5..00000000000 --- a/tools/gnulib/patches/799-vc-mtime-old-git.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 47548a77525a0f4489c9c420ccc2159079365da8 Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Fri, 2 May 2025 12:09:40 +0200 -Subject: [PATCH] vc-mtime: Make it work with git versions < 2.28. - -* lib/vc-mtime.c (git_version): New variable. -(is_git_present): Read the output of "git --version", and set -git_version. -(max_vc_mtime): Don't pass option --no-relative if the git version -is < 2.28. ---- - ChangeLog | 9 ++++++ - lib/vc-mtime.c | 82 +++++++++++++++++++++++++++++++++++++++++++++----- - 2 files changed, 83 insertions(+), 8 deletions(-) - ---- a/lib/vc-mtime.c -+++ b/lib/vc-mtime.c -@@ -53,7 +53,9 @@ - - /* ========================================================================== */ - --/* Determines whether git is present. */ -+static const char *git_version; -+ -+/* Determines whether git is present, and sets git_version if so. */ - static bool - is_git_present (void) - { -@@ -63,17 +65,67 @@ is_git_present (void) - if (!git_tested) - { - /* Test for presence of git: -- "git --version >/dev/null 2>/dev/null" */ -+ "git --version 2>/dev/null" */ - const char *argv[3]; -- int exitstatus; -+ pid_t child; -+ int fd[1]; - - argv[0] = "git"; - argv[1] = "--version"; - argv[2] = NULL; -- exitstatus = execute ("git", "git", argv, NULL, NULL, -- false, false, true, true, -- true, false, NULL); -- git_present = (exitstatus == 0); -+ child = create_pipe_in ("git", "git", argv, NULL, NULL, -+ DEV_NULL, true, true, false, fd); -+ if (child == -1) -+ git_present = false; -+ else -+ { -+ /* Retrieve its result. */ -+ FILE *fp = fdopen (fd[0], "r"); -+ if (fp == NULL) -+ error (EXIT_FAILURE, errno, _("fdopen() failed")); -+ -+ char *line = NULL; -+ size_t linesize = 0; -+ size_t linelen = getline (&line, &linesize, fp); -+ if (linelen == (size_t)(-1)) -+ { -+ fclose (fp); -+ wait_subprocess (child, "git", true, true, true, false, NULL); -+ git_present = false; -+ } -+ else -+ { -+ if (linelen > 0 && line[linelen - 1] == '\n') -+ line[linelen - 1] = '\0'; -+ -+ /* Read until EOF (otherwise the child process may get a SIGPIPE -+ signal). */ -+ while (getc (fp) != EOF) -+ ; -+ -+ fclose (fp); -+ -+ /* Remove zombie process from process list, and retrieve exit -+ status. */ -+ int exitstatus = -+ wait_subprocess (child, "git", true, true, true, false, NULL); -+ if (exitstatus != 0) -+ { -+ free (line); -+ git_present = false; -+ } -+ else -+ { -+ /* The version starts at the first digit in the line. */ -+ const char *p = line; -+ for (; *p != '0'; p++) -+ if (*p >= '0' && *p <= '9') -+ break; -+ git_version = p; -+ git_present = true; -+ } -+ } -+ } - git_tested = true; - } - -@@ -660,7 +712,21 @@ max_vc_mtime (struct timespec *max_of_mt - argv[i++] = "git"; - argv[i++] = "diff"; - argv[i++] = "--name-only"; -- argv[i++] = "--no-relative"; -+ /* With git versions >= 2.28, we pass option --no-relative, -+ in order to neutralize any possible customization of the -+ "diff.relative" property. With git versions < 2.28, this -+ is not needed, and the option --no-relative does not -+ exist. */ -+ if (!(git_version[0] <= '1' -+ || (git_version[0] == '2' && git_version[1] == '.' -+ && ((git_version[2] >= '0' && git_version[2] <= '9' -+ && !(git_version[3] >= '0' && git_version[3] <= '9')) -+ || (((git_version[2] == '1' -+ && git_version[3] >= '0' && git_version[3] <= '9') -+ || (git_version[2] == '2' -+ && git_version[3] >= '0' && git_version[3] <= '7')) -+ && !(git_version[4] >= '0' && git_version[4] <= '9')))))) -+ argv[i++] = "--no-relative"; - argv[i++] = "-z"; - argv[i++] = "HEAD"; - argv[i++] = "--"; diff --git a/tools/gnulib/patches/900-str_startswith-module.patch b/tools/gnulib/patches/900-str_startswith-module.patch deleted file mode 100644 index c9af62710a5..00000000000 --- a/tools/gnulib/patches/900-str_startswith-module.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 24010120fab36721caaf92be076655571e44da07 Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Fri, 3 Jan 2025 09:26:14 +0100 -Subject: [PATCH] str_startswith: New module. - -* lib/string.in.h (str_startswith): New declaration. -* lib/str_startswith.c: New file. -* m4/string_h.m4 (gl_STRING_H_REQUIRE_DEFAULTS): Initialize -GNULIB_STR_STARTSWITH. -* modules/string-h (Makefile.am): Substitute GNULIB_STR_STARTSWITH. -* modules/str_startswith: New file. ---- - ChangeLog | 10 ++++++++++ - lib/str_startswith.c | 29 +++++++++++++++++++++++++++++ - lib/string.in.h | 8 ++++++++ - m4/string_h.m4 | 3 ++- - modules/str_startswith | 23 +++++++++++++++++++++++ - modules/string-h | 1 + - 6 files changed, 73 insertions(+), 1 deletion(-) - create mode 100644 lib/str_startswith.c - create mode 100644 modules/str_startswith - ---- /dev/null -+++ b/lib/str_startswith.c -@@ -0,0 +1,29 @@ -+/* str_startswith function. -+ Copyright (C) 2025 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 Bruno Haible , 2025. */ -+ -+#include "config.h" -+ -+/* Specification. */ -+#include -+ -+ -+int -+str_startswith (const char *string, const char *prefix) -+{ -+ return strncmp (string, prefix, strlen (prefix)) == 0; -+} ---- a/lib/string.in.h -+++ b/lib/string.in.h -@@ -1079,6 +1079,14 @@ _GL_WARN_ON_USE (strtok_r, "strtok_r is - /* The following functions are not specified by POSIX. They are gnulib - extensions. */ - -+#if @GNULIB_STR_STARTSWITH@ -+/* Returns true if STRING starts with PREFIX. -+ Returns false otherwise. */ -+_GL_EXTERN_C int str_startswith (const char *string, const char *prefix) -+ _GL_ATTRIBUTE_PURE -+ _GL_ARG_NONNULL ((1, 2)); -+#endif -+ - #if @GNULIB_MBSLEN@ - /* Return the number of multibyte characters in the character string STRING. - This considers multibyte characters, unlike strlen, which counts bytes. */ ---- a/m4/string_h.m4 -+++ b/m4/string_h.m4 -@@ -70,6 +70,7 @@ AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS], - gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSTR]) - gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCASESTR]) - gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOK_R]) -+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_STARTSWITH]) - gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSLEN]) - gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNLEN]) - gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCHR]) ---- /dev/null -+++ b/modules/str_startswith -@@ -0,0 +1,23 @@ -+Description: -+str_startswith() function: test whether a string starts with a given prefix. -+ -+Files: -+lib/str_startswith.c -+ -+Depends-on: -+string-h -+ -+configure.ac: -+gl_STRING_MODULE_INDICATOR([str_startswith]) -+ -+Makefile.am: -+lib_SOURCES += str_startswith.c -+ -+Include: -+ -+ -+License: -+LGPLv2+ -+ -+Maintainer: -+all ---- a/modules/string-h -+++ b/modules/string-h -@@ -69,6 +69,7 @@ string.h: string.in.h $(top_builddir)/co - -e 's/@''GNULIB_STRSTR''@/$(GNULIB_STRSTR)/g' \ - -e 's/@''GNULIB_STRCASESTR''@/$(GNULIB_STRCASESTR)/g' \ - -e 's/@''GNULIB_STRTOK_R''@/$(GNULIB_STRTOK_R)/g' \ -+ -e 's/@''GNULIB_STR_STARTSWITH''@/$(GNULIB_STR_STARTSWITH)/g' \ - -e 's/@''GNULIB_STRERROR''@/$(GNULIB_STRERROR)/g' \ - -e 's/@''GNULIB_STRERROR_R''@/$(GNULIB_STRERROR_R)/g' \ - -e 's/@''GNULIB_STRERRORNAME_NP''@/$(GNULIB_STRERRORNAME_NP)/g' \ diff --git a/tools/gnulib/patches/901-str_endswith-module.patch b/tools/gnulib/patches/901-str_endswith-module.patch deleted file mode 100644 index 00db5cdce00..00000000000 --- a/tools/gnulib/patches/901-str_endswith-module.patch +++ /dev/null @@ -1,119 +0,0 @@ -From d89ac9373d9748f7601babf52c9129fcbcf0c907 Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Fri, 3 Jan 2025 09:54:14 +0100 -Subject: [PATCH] str_endswith: New module. - -* lib/string.in.h (str_endswith): New declaration. -* lib/str_endswith.c: New file. -* m4/string_h.m4 (gl_STRING_H_REQUIRE_DEFAULTS): Initialize -GNULIB_STR_ENDSWITH. -* modules/string-h (Makefile.am): Substitute GNULIB_STR_ENDSWITH. -* modules/str_endswith: New file. ---- - ChangeLog | 10 ++++++++++ - lib/str_endswith.c | 31 +++++++++++++++++++++++++++++++ - lib/string.in.h | 8 ++++++++ - m4/string_h.m4 | 3 ++- - modules/str_endswith | 23 +++++++++++++++++++++++ - modules/string-h | 1 + - 6 files changed, 75 insertions(+), 1 deletion(-) - create mode 100644 lib/str_endswith.c - create mode 100644 modules/str_endswith - ---- /dev/null -+++ b/lib/str_endswith.c -@@ -0,0 +1,31 @@ -+/* str_endswith function. -+ Copyright (C) 2025 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 Bruno Haible , 2025. */ -+ -+#include "config.h" -+ -+/* Specification. */ -+#include -+ -+ -+int -+str_endswith (const char *string, const char *suffix) -+{ -+ size_t len = strlen (string); -+ size_t n = strlen (suffix); -+ return len >= n && strcmp (string + len - n, suffix) == 0; -+} ---- a/lib/string.in.h -+++ b/lib/string.in.h -@@ -1087,6 +1087,14 @@ _GL_EXTERN_C int str_startswith (const c - _GL_ARG_NONNULL ((1, 2)); - #endif - -+#if @GNULIB_STR_ENDSWITH@ -+/* Returns true if STRING ends with SUFFIX. -+ Returns false otherwise. */ -+_GL_EXTERN_C int str_endswith (const char *string, const char *prefix) -+ _GL_ATTRIBUTE_PURE -+ _GL_ARG_NONNULL ((1, 2)); -+#endif -+ - #if @GNULIB_MBSLEN@ - /* Return the number of multibyte characters in the character string STRING. - This considers multibyte characters, unlike strlen, which counts bytes. */ ---- a/m4/string_h.m4 -+++ b/m4/string_h.m4 -@@ -71,6 +71,7 @@ AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS], - gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCASESTR]) - gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOK_R]) - gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_STARTSWITH]) -+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_ENDSWITH]) - gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSLEN]) - gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNLEN]) - gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCHR]) ---- /dev/null -+++ b/modules/str_endswith -@@ -0,0 +1,23 @@ -+Description: -+str_endswith() function: test whether a string ends with a given suffix. -+ -+Files: -+lib/str_endswith.c -+ -+Depends-on: -+string-h -+ -+configure.ac: -+gl_STRING_MODULE_INDICATOR([str_endswith]) -+ -+Makefile.am: -+lib_SOURCES += str_endswith.c -+ -+Include: -+ -+ -+License: -+LGPLv2+ -+ -+Maintainer: -+all ---- a/modules/string-h -+++ b/modules/string-h -@@ -69,6 +69,7 @@ string.h: string.in.h $(top_builddir)/co - -e 's/@''GNULIB_STRSTR''@/$(GNULIB_STRSTR)/g' \ - -e 's/@''GNULIB_STRCASESTR''@/$(GNULIB_STRCASESTR)/g' \ - -e 's/@''GNULIB_STRTOK_R''@/$(GNULIB_STRTOK_R)/g' \ -+ -e 's/@''GNULIB_STR_ENDSWITH''@/$(GNULIB_STR_ENDSWITH)/g' \ - -e 's/@''GNULIB_STR_STARTSWITH''@/$(GNULIB_STR_STARTSWITH)/g' \ - -e 's/@''GNULIB_STRERROR''@/$(GNULIB_STRERROR)/g' \ - -e 's/@''GNULIB_STRERROR_R''@/$(GNULIB_STRERROR_R)/g' \