Please find attached patches that allow building GNU Global v6.6.14 on
Fedora GNU/Linux v42 and v43. The first three are straight forward:
1. When looking for Universal Ctags, use option `--extras'. The code
does this, but configure was using `--extra'.
2. When looking for libsqlite3, add /usr/lib64 to the search path.
3. Address a GNU C v15 compilation error: assignment from incompatible
pointer type 'int (*)(void)'. The fix is to conditionally add
prototypes to dberr masks.
Many modern systems come with Gnulib. So either GNU Global could link
against the system Gnulib, or, alternatively, the Gnulib `bootstrap'
script could be added to the GNU Global distribution. Gnulib bootstrap
downloads Gnulib modules as needed. See:
https://cgit.git.savannah.gnu.org/cgit/gnulib.git/tree/top/bootstrap
One complication is that the function hash_string is no longer
included in Gnulib.
4. So the final patch is an attempt to address these issues in
minimalist (lazy) way: If the system provides regcomp and
getopt_long, then the system-provided functions are used by
default. To override this, use the configure option
`--with-included-regex'. An updated version of the hash_string
function by Bruno Haible is added directly to libutil/strhash.c.
The function is described in the article:
https://www.haible.de/bruno/hashfunc.html
A more correct approach might be to leverage Gnulib's bootstrap script
and update strhash.c to use current Gnulib hash functions. If I had
more time, I would have liked to offer an alternative patch for this.
The current Gnulib does have lots of overhead, so maybe the included
patch will be acceptable compromise.
diff --git a/configure.ac b/configure.ac
index ef2c9c6..5a9e415 100644
--- a/configure.ac
+++ b/configure.ac
@@ -343,7 +343,7 @@ AC_ARG_WITH(universal-ctags,
withval=
for d in `echo $PATH | sed -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' -e 's/:/ /g'`
do
- if test -x "$d/ctags" && (sh -c "'$d/ctags' --_xformat='%R %-16N %4n %-16F %C' --extra=+r --fields=+r -x /dev/null") > /dev/null 2>&1; then
+ if test -x "$d/ctags" && (sh -c "'$d/ctags' --_xformat='%R %-16N %4n %-16F %C' --extras=+r --fields=+r -x /dev/null") > /dev/null 2>&1; then
withval="$d/ctags"
break
fi
diff --git a/configure.ac b/configure.ac
index 5a9e415..25e57ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -247,8 +247,10 @@ AC_ARG_WITH(sqlite3,
if ! test -r "$withval/include/sqlite3.h"; then
AC_MSG_ERROR([header $withval/include/sqlite3.h not found.])
fi
- if ! test -r "$withval/lib/libsqlite3.so" && ! test -r "$withval/lib/libsqlite3.dylib"; then
- AC_MSG_ERROR([library $withval/lib/libsqlite3.* not found.])
+ if ! test -r "$withval/lib/libsqlite3.so" \
+ && ! test -r "$withval/lib64/libsqlite3.so" \
+ && ! test -r "$withval/lib/libsqlite3.dylib"; then
+ AC_MSG_ERROR([library $withval/lib*/libsqlite3.* not found.])
fi
AM_CONDITIONAL(USE_SQLITE3_VENDORED, false)
AM_CPPFLAGS="$AM_CPPFLAGS -I$withval/include"
diff --git a/libdb/compat.h b/libdb/compat.h
index 9c52219..f331498 100644
--- a/libdb/compat.h
+++ b/libdb/compat.h
@@ -83,6 +83,14 @@ static int __sigtemp; /**< For the use of sigprocmask */
#endif
#endif
+#ifndef __P
+#ifndef __STDC__
+# define __P(proto) ()
+#else
+# define __P(proto) proto
+#endif /* __STDC__ */
+#endif /* __P */
+
/* Compatibility macros */
/*
* Old definitions were rewritten using 'HAVE_XXX' macros.
diff --git a/libdb/db.c b/libdb/db.c
index d6734a1..d17758f 100644
--- a/libdb/db.c
+++ b/libdb/db.c
@@ -89,10 +89,10 @@ void
__dbpanic(DB *dbp)
{
/* The only thing that can succeed is a close. */
- dbp->del = (int (*)())__dberr;
- dbp->fd = (int (*)())__dberr;
- dbp->get = (int (*)())__dberr;
- dbp->put = (int (*)())__dberr;
- dbp->seq = (int (*)())__dberr;
- dbp->sync = (int (*)())__dberr;
+ dbp->del = (int (*)__P((const struct __db *, const DBT *, u_int)))__dberr;
+ dbp->fd = (int (*)__P((const struct __db *)))__dberr;
+ dbp->get = (int (*)__P((const struct __db *, const DBT *, DBT *, u_int)))__dberr;
+ dbp->put = (int (*)__P((const struct __db *, DBT *, const DBT *, u_int)))__dberr;
+ dbp->seq = (int (*)__P((const struct __db *, DBT *, DBT *, u_int)))__dberr;
+ dbp->sync = (int (*)__P((const struct __db *, u_int)))__dberr;
}
diff --git a/Makefile.am b/Makefile.am
index 44452dc..6bbf764 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -11,7 +11,10 @@
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
ACLOCAL_AMFLAGS = -I m4
-SUBDIRS = libglibc libutil libparser libltdl plugin-factory
+SUBDIRS = libutil libparser libltdl plugin-factory
+if LDADD_GNULIB
+ SUBDIRS += libglibc
+endif
if !USE_DB185_COMPAT
SUBDIRS += libdb
endif
diff --git a/configure.ac b/configure.ac
index 25e57ce..bf9eed1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,6 +25,7 @@ AC_INIT([GNU Global],[6.6.14])
AC_DEFINE(COPYRIGHT_YEAR,["1996-2024"],[Copyright Year])
AC_CONFIG_SRCDIR(global/global.c)
AC_CONFIG_HEADERS([config.h:config-h.in])
+AC_CONFIG_LIBOBJ_DIR([libglibc])
AC_CONFIG_MACRO_DIRS([m4])
AC_PREREQ(2.71)
AM_INIT_AUTOMAKE([1.9.3 gnu subdir-objects])
@@ -220,7 +221,39 @@ AC_ARG_WITH(db185-compat,
],[ with_db185_compat=no ])
AM_CONDITIONAL([USE_DB185_COMPAT], [test "$with_db185_compat" != no])
-LDADD='../libparser/libgloparser.a ../libutil/libgloutil.a '$DBLIBRARY' ../libglibc/libgloglibc.a'
+LDADD='../libparser/libgloparser.a ../libutil/libgloutil.a '$DBLIBRARY
+
+AX_FUNC_GETOPT_LONG
+
+AC_MSG_CHECKING([whether included regex is requested])
+AC_ARG_WITH([included-regex],
+ [AS_HELP_STRING([--with-included-regex],
+ [use included GNU regex library])],
+ [], [with_included_regex=check])
+AC_MSG_RESULT([$with_included_regex])
+if test ! ."$with_included_regex" = .'yes'; then
+ AC_CHECK_FUNCS([regcomp],
+ [with_included_regex=no],
+ [with_included_regex=yes
+ AC_MSG_WARN([System regex not found, falling back to included version])])
+fi
+AM_CONDITIONAL([LIBADD_REGEX],
+ [test ."$with_included_regex" = .'yes' \
+ -o ."$ac_cv_func_getopt_long" != .'yes'])
+AM_COND_IF([LIBADD_REGEX],
+ [LDADD="$LDADD ../libglibc/libgloglibc.a"
+ AC_DEFINE([HAVE_REG_SYNTAX_T], [1],
+ [Define to 1 if regex.h defines `reg_syntax_t'.])],
+ [AC_CHECK_TYPES([reg_syntax_t],
+ [AC_DEFINE([HAVE_REG_SYNTAX_T], [1],
+ [Define to 1 if regex.h defines `reg_syntax_t'.])],[],
+ [[#include <sys/types.h>
+#include <regex.h>]])])
+
+AM_CONDITIONAL([LDADD_GNULIB],
+ [test ."$with_included_regex" = .'yes' \
+ -o ."$ac_cv_func_getopt_long" != .'yes'])
+
dnl
dnl Use sqlite3 API.
dnl
diff --git a/libutil/strhash.c b/libutil/strhash.c
index 393a069..879bae5 100644
--- a/libutil/strhash.c
+++ b/libutil/strhash.c
@@ -20,6 +20,7 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -72,9 +73,27 @@ strhash_close(hash); // free resources.
#define obstack_chunk_alloc check_malloc
#define obstack_chunk_free free
+#define LONGBITS (CHAR_BIT * sizeof(long))
+
+/* Source: https://www.haible.de/bruno/hashfunc.html */
+static unsigned long
+compute_hashval (const void *key, size_t keylen)
+{
+ size_t cnt;
+ unsigned long int hval;
+
+ cnt = 0;
+ hval = keylen;
+ while (cnt < keylen)
+ {
+ hval = (hval << 9) | (hval >> (LONGBITS - 9));
+ hval += (unsigned long int) *(((char *) key) + cnt++);
+ }
+ return hval != 0 ? hval : ~((unsigned long) 0);
+}
/**
- * strhash_open: open string hash table.
+ * strhash_open: open hash table.
*
* @param[in] buckets size of bucket table
* @return sh STRHASH structure
@@ -108,7 +127,8 @@ strhash_open(int buckets)
struct sh_entry *
strhash_assign(STRHASH *sh, const char *name, int force)
{
- struct sh_head *head = &sh->htab[__hash_string(name) % sh->buckets];
+ struct sh_head *head =
+ &sh->htab[compute_hashval(name, strlen(name)) % sh->buckets];
struct sh_entry *entry;
/*