emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master c8b6006 3/4: Use Gnulib libgmp module


From: Paul Eggert
Subject: master c8b6006 3/4: Use Gnulib libgmp module
Date: Thu, 9 Jul 2020 19:38:53 -0400 (EDT)

branch: master
commit c8b6006d82196f9063581e988ea12d6c99c95536
Author: Paul Eggert <eggert@cs.ucla.edu>
Commit: Paul Eggert <eggert@cs.ucla.edu>

    Use Gnulib libgmp module
    
    Instead of doing GMP by hand, use the Gnulib libgmp module.
    * .gitignore: Add lib/gmp.h.
    * admin/merge-gnulib (GNULIB_MODULES): Add libgmp.
    * configure.ac (GMP_LIB, GMP_OBJ): Remove.  Gnulib uses the name
    LIB_GMP, so all uses changed.  All uses of GMP_OBJ removed.
    (HAVE_GMP): Set this from Gnulib’s variables.
    * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
    * lib/mini-gmp-gnulib.c, lib/mini-gmp.c, lib/mini-gmp.h, m4/libgmp.m4:
    New files, copied from Gnulib.
    * src/bignum.h, test/data/emacs-module/mod-test.c:
    Include gmp.h unconditionally.
    * src/mini-gmp-emacs.c, src/mini-gmp.c, src/mini-gmp.h:
    Remove.  This moves these files from src to lib, and
    updates them to the current GMP version.
    * test/Makefile.in (GMP_H): New macro.
    ($(test_module)): Use it to decide whether to compile
    mini-gmp-gnulib.c too.
---
 .gitignore                        |   1 +
 admin/merge-gnulib                |   2 +-
 configure.ac                      |  33 ++-------
 lib/gnulib.mk.in                  |  29 +++++++-
 lib/mini-gmp-gnulib.c             |  37 ++++++++++
 {src => lib}/mini-gmp.c           | 144 +++++++++++++++++++++++++-------------
 {src => lib}/mini-gmp.h           |  10 ++-
 m4/gnulib-comp.m4                 |   9 +++
 m4/libgmp.m4                      |  44 ++++++++++++
 src/Makefile.in                   |   5 +-
 src/bignum.h                      |   7 +-
 src/mini-gmp-emacs.c              |  32 ---------
 test/Makefile.in                  |   7 +-
 test/data/emacs-module/mod-test.c |   5 --
 14 files changed, 233 insertions(+), 132 deletions(-)

diff --git a/.gitignore b/.gitignore
index d4be6bb..890e63a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -60,6 +60,7 @@ lib/execinfo.h
 lib/fcntl.h
 lib/getopt.h
 lib/getopt-cdefs.h
+lib/gmp.h
 lib/ieee754.h
 lib/inttypes.h
 lib/libgnu.a
diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index 5a78b05..3f32536 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -36,7 +36,7 @@ GNULIB_MODULES='
   fchmodat fcntl fcntl-h fdopendir
   filemode filename filevercmp flexmember fpieee fstatat fsusage fsync futimens
   getloadavg getopt-gnu getrandom gettime gettimeofday gitlog-to-changelog
-  ieee754-h ignore-value intprops largefile lstat
+  ieee754-h ignore-value intprops largefile libgmp lstat
   manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime nstrftime
   pathmax pipe2 pselect pthread_sigmask
   qcopy-acl readlink readlinkat regex
diff --git a/configure.ac b/configure.ac
index 9fe1a0d..148c50e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4507,32 +4507,6 @@ AC_SUBST(KRB5LIB)
 AC_SUBST(DESLIB)
 AC_SUBST(KRB4LIB)
 
-AC_ARG_WITH([libgmp],
-  [AS_HELP_STRING([--without-libgmp],
-                 [don't use the GNU Multiple Precision (GMP) library;
-                  this is the default on systems lacking libgmp.])])
-GMP_LIB=
-GMP_OBJ=mini-gmp-emacs.o
-HAVE_GMP=no
-case $with_libgmp in
-  no) ;;
-  yes) HAVE_GMP=yes GMP_LIB=-lgmp;;
-  *) AC_CHECK_HEADERS([gmp.h],
-       [OLIBS=$LIBS
-       AC_SEARCH_LIBS([__gmpz_roinit_n], [gmp])
-       LIBS=$OLIBS
-       case $ac_cv_search___gmpz_roinit_n in
-         'none needed') HAVE_GMP=yes;;
-         -*) HAVE_GMP=yes GMP_LIB=$ac_cv_search___gmpz_roinit_n;;
-       esac]);;
-esac
-if test "$HAVE_GMP" = yes; then
-  GMP_OBJ=
-  AC_DEFINE([HAVE_GMP], 1, [Define to 1 if you have recent-enough GMP.])
-fi
-AC_SUBST([GMP_LIB])
-AC_SUBST([GMP_OBJ])
-
 AC_CHECK_HEADERS(valgrind/valgrind.h)
 
 AC_CHECK_MEMBERS([struct unipair.unicode], [], [], [[#include <linux/kd.h>]])
@@ -5700,6 +5674,11 @@ done
 AC_DEFINE_UNQUOTED(EMACS_CONFIG_FEATURES, "${emacs_config_features}",
   [Summary of some of the main features enabled by configure.])
 
+if test -z "$GMP_H"; then
+  HAVE_GMP=yes
+else
+  HAVE_GMP=no
+fi
 AS_ECHO(["  Does Emacs use -lXaw3d?                                 
${HAVE_XAW3D}
   Does Emacs use -lXpm?                                   ${HAVE_XPM}
   Does Emacs use -ljpeg?                                  ${HAVE_JPEG}
@@ -5728,7 +5707,7 @@ AS_ECHO(["  Does Emacs use -lXaw3d?                       
          ${HAVE_XAW3D
   Does Emacs use -lxft?                                   ${HAVE_XFT}
   Does Emacs use -lsystemd?                               ${HAVE_LIBSYSTEMD}
   Does Emacs use -ljansson?                               ${HAVE_JSON}
-  Does Emacs use -lgmp?                                   ${HAVE_GMP}
+  Does Emacs use the GMP library?                         ${HAVE_GMP}
   Does Emacs directly use zlib?                           ${HAVE_ZLIB}
   Does Emacs have dynamic modules support?                ${HAVE_MODULES}
   Does Emacs use toolkit scroll bars?                     
${USE_TOOLKIT_SCROLL_BARS}
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index c249d62..68cae8f 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -117,6 +117,7 @@
 #  ignore-value \
 #  intprops \
 #  largefile \
+#  libgmp \
 #  lstat \
 #  manywarnings \
 #  memmem-simple \
@@ -245,14 +246,14 @@ GL_GENERATE_ALLOCA_H = @GL_GENERATE_ALLOCA_H@
 GL_GENERATE_BYTESWAP_H = @GL_GENERATE_BYTESWAP_H@
 GL_GENERATE_ERRNO_H = @GL_GENERATE_ERRNO_H@
 GL_GENERATE_EXECINFO_H = @GL_GENERATE_EXECINFO_H@
+GL_GENERATE_GMP_H = @GL_GENERATE_GMP_H@
 GL_GENERATE_IEEE754_H = @GL_GENERATE_IEEE754_H@
 GL_GENERATE_LIMITS_H = @GL_GENERATE_LIMITS_H@
 GL_GENERATE_STDALIGN_H = @GL_GENERATE_STDALIGN_H@
 GL_GENERATE_STDDEF_H = @GL_GENERATE_STDDEF_H@
 GL_GENERATE_STDINT_H = @GL_GENERATE_STDINT_H@
 GMALLOC_OBJ = @GMALLOC_OBJ@
-GMP_LIB = @GMP_LIB@
-GMP_OBJ = @GMP_OBJ@
+GMP_H = @GMP_H@
 GNULIB_ACCESS = @GNULIB_ACCESS@
 GNULIB_ALPHASORT = @GNULIB_ALPHASORT@
 GNULIB_ATOLL = @GNULIB_ATOLL@
@@ -760,6 +761,7 @@ LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@
 LIB_EACCESS = @LIB_EACCESS@
 LIB_EXECINFO = @LIB_EXECINFO@
 LIB_GETRANDOM = @LIB_GETRANDOM@
+LIB_GMP = @LIB_GMP@
 LIB_MATH = @LIB_MATH@
 LIB_PTHREAD = @LIB_PTHREAD@
 LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@
@@ -2014,6 +2016,29 @@ EXTRA_DIST += cdefs.h libc-config.h
 endif
 ## end   gnulib module libc-config
 
+## begin gnulib module libgmp
+ifeq (,$(OMIT_GNULIB_MODULE_libgmp))
+
+BUILT_SOURCES += $(GMP_H)
+
+# Build gmp.h as a wrapper for mini-gmp.h when using mini-gmp.
+ifneq (,$(GL_GENERATE_GMP_H))
+gmp.h: $(top_builddir)/config.status
+       echo '#include "mini-gmp.h"' >$@-t
+       mv $@-t $@
+else
+gmp.h: $(top_builddir)/config.status
+       rm -f $@
+endif
+MOSTLYCLEANFILES += gmp.h gmp.h-t
+
+EXTRA_DIST += mini-gmp-gnulib.c mini-gmp.c mini-gmp.h
+
+EXTRA_libgnu_a_SOURCES += mini-gmp-gnulib.c mini-gmp.c
+
+endif
+## end   gnulib module libgmp
+
 ## begin gnulib module limits-h
 ifeq (,$(OMIT_GNULIB_MODULE_limits-h))
 
diff --git a/lib/mini-gmp-gnulib.c b/lib/mini-gmp-gnulib.c
new file mode 100644
index 0000000..5019be5
--- /dev/null
+++ b/lib/mini-gmp-gnulib.c
@@ -0,0 +1,37 @@
+/* Tailor mini-gmp.c for Gnulib-using applications.
+
+   Copyright 2018-2020 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 <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include "mini-gmp.h"
+
+/* Pacify GCC -Wsuggest-attribute=const, malloc, pure.  */
+#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
+# pragma GCC diagnostic ignored "-Wsuggest-attribute=const"
+# pragma GCC diagnostic ignored "-Wsuggest-attribute=malloc"
+# pragma GCC diagnostic ignored "-Wsuggest-attribute=pure"
+#endif
+
+/* Pacify GCC -Wunused-variable for variables used only in 'assert' calls.  */
+#if defined NDEBUG && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
+# pragma GCC diagnostic ignored "-Wunused-variable"
+#endif
+
+#include "mini-gmp.c"
diff --git a/src/mini-gmp.c b/lib/mini-gmp.c
similarity index 97%
rename from src/mini-gmp.c
rename to lib/mini-gmp.c
index 2e789a2..2e0301b 100644
--- a/src/mini-gmp.c
+++ b/lib/mini-gmp.c
@@ -2,21 +2,21 @@
 
    Contributed to the GNU project by Niels Möller
 
-Copyright 1991-1997, 1999-2019 Free Software Foundation, Inc.
+Copyright 1991-1997, 1999-2020 Free Software Foundation, Inc.
 
 This file is part of the GNU MP Library.
 
 The GNU MP Library is free software; you can redistribute it and/or modify
 it under the terms of either:
 
-  * the GNU Lesser General Public License as published by the Free
+  * 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.
 
 or
 
   * the GNU General Public License as published by the Free Software
-    Foundation; either version 2 of the License, or (at your option) any
+    Foundation; either version 3 of the License, or (at your option) any
     later version.
 
 or both in parallel, as here.
@@ -27,7 +27,7 @@ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General 
Public License
 for more details.
 
 You should have received copies of the GNU General Public License and the
-GNU Lesser General Public License along with the GNU MP Library.  If not,
+GNU General Public License along with the GNU MP Library.  If not,
 see https://www.gnu.org/licenses/.  */
 
 /* NOTE: All functions in this file which are not declared in
@@ -351,20 +351,27 @@ mp_set_memory_functions (void *(*alloc_func) (size_t),
   gmp_free_func = free_func;
 }
 
-#define gmp_xalloc(size) ((*gmp_allocate_func)((size)))
-#define gmp_free(p) ((*gmp_free_func) ((p), 0))
+#define gmp_alloc(size) ((*gmp_allocate_func)((size)))
+#define gmp_free(p, size) ((*gmp_free_func) ((p), (size)))
+#define gmp_realloc(ptr, old_size, size) ((*gmp_reallocate_func)(ptr, 
old_size, size))
 
 static mp_ptr
-gmp_xalloc_limbs (mp_size_t size)
+gmp_alloc_limbs (mp_size_t size)
 {
-  return (mp_ptr) gmp_xalloc (size * sizeof (mp_limb_t));
+  return (mp_ptr) gmp_alloc (size * sizeof (mp_limb_t));
 }
 
 static mp_ptr
-gmp_xrealloc_limbs (mp_ptr old, mp_size_t size)
+gmp_realloc_limbs (mp_ptr old, mp_size_t old_size, mp_size_t size)
 {
   assert (size > 0);
-  return (mp_ptr) (*gmp_reallocate_func) (old, 0, size * sizeof (mp_limb_t));
+  return (mp_ptr) gmp_realloc (old, old_size * sizeof (mp_limb_t), size * 
sizeof (mp_limb_t));
+}
+
+static void
+gmp_free_limbs (mp_ptr old, mp_size_t size)
+{
+  gmp_free (old, size * sizeof (mp_limb_t));
 }
 
 
@@ -956,11 +963,17 @@ mpn_div_qr_1_preinv (mp_ptr qp, mp_srcptr np, mp_size_t 
nn,
   mp_limb_t d, di;
   mp_limb_t r;
   mp_ptr tp = NULL;
+  mp_size_t tn = 0;
 
   if (inv->shift > 0)
     {
       /* Shift, reusing qp area if possible. In-place shift if qp == np. */
-      tp = qp ? qp : gmp_xalloc_limbs (nn);
+      tp = qp;
+      if (!tp)
+        {
+          tn = nn;
+          tp = gmp_alloc_limbs (tn);
+        }
       r = mpn_lshift (tp, np, nn, inv->shift);
       np = tp;
     }
@@ -977,8 +990,8 @@ mpn_div_qr_1_preinv (mp_ptr qp, mp_srcptr np, mp_size_t nn,
       if (qp)
        qp[nn] = q;
     }
-  if ((inv->shift > 0) && (tp != qp))
-    gmp_free (tp);
+  if (tn)
+    gmp_free_limbs (tp, tn);
 
   return r >> inv->shift;
 }
@@ -1136,13 +1149,13 @@ mpn_div_qr (mp_ptr qp, mp_ptr np, mp_size_t nn, 
mp_srcptr dp, mp_size_t dn)
   mpn_div_qr_invert (&inv, dp, dn);
   if (dn > 2 && inv.shift > 0)
     {
-      tp = gmp_xalloc_limbs (dn);
+      tp = gmp_alloc_limbs (dn);
       gmp_assert_nocarry (mpn_lshift (tp, dp, dn, inv.shift));
       dp = tp;
     }
   mpn_div_qr_preinv (qp, np, nn, dp, dn, &inv);
   if (tp)
-    gmp_free (tp);
+    gmp_free_limbs (tp, dn);
 }
 
 
@@ -1428,14 +1441,14 @@ mpz_init2 (mpz_t r, mp_bitcnt_t bits)
 
   r->_mp_alloc = rn;
   r->_mp_size = 0;
-  r->_mp_d = gmp_xalloc_limbs (rn);
+  r->_mp_d = gmp_alloc_limbs (rn);
 }
 
 void
 mpz_clear (mpz_t r)
 {
   if (r->_mp_alloc)
-    gmp_free (r->_mp_d);
+    gmp_free_limbs (r->_mp_d, r->_mp_alloc);
 }
 
 static mp_ptr
@@ -1444,9 +1457,9 @@ mpz_realloc (mpz_t r, mp_size_t size)
   size = GMP_MAX (size, 1);
 
   if (r->_mp_alloc)
-    r->_mp_d = gmp_xrealloc_limbs (r->_mp_d, size);
+    r->_mp_d = gmp_realloc_limbs (r->_mp_d, r->_mp_alloc, size);
   else
-    r->_mp_d = gmp_xalloc_limbs (size);
+    r->_mp_d = gmp_alloc_limbs (size);
   r->_mp_alloc = size;
 
   if (GMP_ABS (r->_mp_size) > size)
@@ -1541,8 +1554,7 @@ mpz_init_set (mpz_t r, const mpz_t x)
 int
 mpz_fits_slong_p (const mpz_t u)
 {
-  return (LONG_MAX + LONG_MIN == 0 || mpz_cmp_ui (u, LONG_MAX) <= 0) &&
-    mpz_cmpabs_ui (u, GMP_NEG_CAST (unsigned long int, LONG_MIN)) <= 0;
+  return mpz_cmp_si (u, LONG_MAX) <= 0 && mpz_cmp_si (u, LONG_MIN) >= 0;
 }
 
 static int
@@ -1565,6 +1577,30 @@ mpz_fits_ulong_p (const mpz_t u)
   return us >= 0 && mpn_absfits_ulong_p (u->_mp_d, us);
 }
 
+int
+mpz_fits_sint_p (const mpz_t u)
+{
+  return mpz_cmp_si (u, INT_MAX) <= 0 && mpz_cmp_si (u, INT_MIN) >= 0;
+}
+
+int
+mpz_fits_uint_p (const mpz_t u)
+{
+  return u->_mp_size >= 0 && mpz_cmpabs_ui (u, UINT_MAX) <= 0;
+}
+
+int
+mpz_fits_sshort_p (const mpz_t u)
+{
+  return mpz_cmp_si (u, SHRT_MAX) <= 0 && mpz_cmp_si (u, SHRT_MIN) >= 0;
+}
+
+int
+mpz_fits_ushort_p (const mpz_t u)
+{
+  return u->_mp_size >= 0 && mpz_cmpabs_ui (u, USHRT_MAX) <= 0;
+}
+
 long int
 mpz_get_si (const mpz_t u)
 {
@@ -3073,7 +3109,7 @@ mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const 
mpz_t m)
         one, using a *normalized* m. */
       minv.shift = 0;
 
-      tp = gmp_xalloc_limbs (mn);
+      tp = gmp_alloc_limbs (mn);
       gmp_assert_nocarry (mpn_lshift (tp, mp, mn, shift));
       mp = tp;
     }
@@ -3139,7 +3175,7 @@ mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const 
mpz_t m)
       tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn);
     }
   if (tp)
-    gmp_free (tp);
+    gmp_free_limbs (tp, mn);
 
   mpz_swap (r, tr);
   mpz_clear (tr);
@@ -3350,13 +3386,15 @@ gmp_jacobi_coprime (mp_limb_t a, mp_limb_t b)
   gmp_ctz(c, a);
   a >>= 1;
 
-  do
+  for (;;)
     {
       a >>= c;
       /* (2/b) = -1 if b = 3 or 5 mod 8 */
       bit ^= c & (b ^ (b >> 1));
       if (a < b)
        {
+         if (a == 0)
+           return bit & 1 ? -1 : 1;
          bit ^= a & b;
          a = b - a;
          b -= a;
@@ -3370,9 +3408,6 @@ gmp_jacobi_coprime (mp_limb_t a, mp_limb_t b)
       gmp_ctz(c, a);
       ++c;
     }
-  while (b > 0);
-
-  return bit & 1 ? -1 : 1;
 }
 
 static void
@@ -4144,7 +4179,7 @@ mpz_scan0 (const mpz_t u, mp_bitcnt_t starting_bit)
 size_t
 mpz_sizeinbase (const mpz_t u, int base)
 {
-  mp_size_t un;
+  mp_size_t un, tn;
   mp_srcptr up;
   mp_ptr tp;
   mp_bitcnt_t bits;
@@ -4177,20 +4212,21 @@ mpz_sizeinbase (const mpz_t u, int base)
         10. */
     }
 
-  tp = gmp_xalloc_limbs (un);
+  tp = gmp_alloc_limbs (un);
   mpn_copyi (tp, up, un);
   mpn_div_qr_1_invert (&bi, base);
 
+  tn = un;
   ndigits = 0;
   do
     {
       ndigits++;
-      mpn_div_qr_1_preinv (tp, tp, un, &bi);
-      un -= (tp[un-1] == 0);
+      mpn_div_qr_1_preinv (tp, tp, tn, &bi);
+      tn -= (tp[tn-1] == 0);
     }
-  while (un > 0);
+  while (tn > 0);
 
-  gmp_free (tp);
+  gmp_free_limbs (tp, un);
   return ndigits;
 }
 
@@ -4200,7 +4236,7 @@ mpz_get_str (char *sp, int base, const mpz_t u)
   unsigned bits;
   const char *digits;
   mp_size_t un;
-  size_t i, sn;
+  size_t i, sn, osn;
 
   digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
   if (base > 1)
@@ -4221,15 +4257,19 @@ mpz_get_str (char *sp, int base, const mpz_t u)
 
   sn = 1 + mpz_sizeinbase (u, base);
   if (!sp)
-    sp = (char *) gmp_xalloc (1 + sn);
-
+    {
+      osn = 1 + sn;
+      sp = (char *) gmp_alloc (osn);
+    }
+  else
+    osn = 0;
   un = GMP_ABS (u->_mp_size);
 
   if (un == 0)
     {
       sp[0] = '0';
-      sp[1] = '\0';
-      return sp;
+      sn = 1;
+      goto ret;
     }
 
   i = 0;
@@ -4248,17 +4288,20 @@ mpz_get_str (char *sp, int base, const mpz_t u)
       mp_ptr tp;
 
       mpn_get_base_info (&info, base);
-      tp = gmp_xalloc_limbs (un);
+      tp = gmp_alloc_limbs (un);
       mpn_copyi (tp, u->_mp_d, un);
 
       sn = i + mpn_get_str_other ((unsigned char *) sp + i, base, &info, tp, 
un);
-      gmp_free (tp);
+      gmp_free_limbs (tp, un);
     }
 
   for (; i < sn; i++)
     sp[i] = digits[(unsigned char) sp[i]];
 
+ret:
   sp[sn] = '\0';
+  if (osn && osn != sn + 1)
+    sp = gmp_realloc(sp, osn, sn + 1);
   return sp;
 }
 
@@ -4268,7 +4311,7 @@ mpz_set_str (mpz_t r, const char *sp, int base)
   unsigned bits, value_of_a;
   mp_size_t rn, alloc;
   mp_ptr rp;
-  size_t dn;
+  size_t dn, sn;
   int sign;
   unsigned char *dp;
 
@@ -4306,7 +4349,8 @@ mpz_set_str (mpz_t r, const char *sp, int base)
       r->_mp_size = 0;
       return -1;
     }
-  dp = (unsigned char *) gmp_xalloc (strlen (sp));
+  sn = strlen(sp);
+  dp = (unsigned char *) gmp_alloc (sn);
 
   value_of_a = (base > 36) ? 36 : 10;
   for (dn = 0; *sp; sp++)
@@ -4326,7 +4370,7 @@ mpz_set_str (mpz_t r, const char *sp, int base)
 
       if (digit >= (unsigned) base)
        {
-         gmp_free (dp);
+         gmp_free (dp, sn);
          r->_mp_size = 0;
          return -1;
        }
@@ -4336,7 +4380,7 @@ mpz_set_str (mpz_t r, const char *sp, int base)
 
   if (!dn)
     {
-      gmp_free (dp);
+      gmp_free (dp, sn);
       r->_mp_size = 0;
       return -1;
     }
@@ -4360,7 +4404,7 @@ mpz_set_str (mpz_t r, const char *sp, int base)
       rn -= rp[rn-1] == 0;
     }
   assert (rn <= alloc);
-  gmp_free (dp);
+  gmp_free (dp, sn);
 
   r->_mp_size = sign ? - rn : rn;
 
@@ -4378,13 +4422,13 @@ size_t
 mpz_out_str (FILE *stream, int base, const mpz_t x)
 {
   char *str;
-  size_t len;
+  size_t len, n;
 
   str = mpz_get_str (NULL, base, x);
   len = strlen (str);
-  len = fwrite (str, 1, len, stream);
-  gmp_free (str);
-  return len;
+  n = fwrite (str, 1, len, stream);
+  gmp_free (str, len + 1);
+  return n;
 }
 
 
@@ -4512,7 +4556,7 @@ mpz_export (void *r, size_t *countp, int order, size_t 
size, int endian,
       count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size;
 
       if (!r)
-       r = gmp_xalloc (count * size);
+       r = gmp_alloc (count * size);
 
       if (endian == 0)
        endian = gmp_detect_endian ();
diff --git a/src/mini-gmp.h b/lib/mini-gmp.h
similarity index 97%
rename from src/mini-gmp.h
rename to lib/mini-gmp.h
index 7cce3f7..c00568c 100644
--- a/src/mini-gmp.h
+++ b/lib/mini-gmp.h
@@ -7,14 +7,14 @@ This file is part of the GNU MP Library.
 The GNU MP Library is free software; you can redistribute it and/or modify
 it under the terms of either:
 
-  * the GNU Lesser General Public License as published by the Free
+  * 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.
 
 or
 
   * the GNU General Public License as published by the Free Software
-    Foundation; either version 2 of the License, or (at your option) any
+    Foundation; either version 3 of the License, or (at your option) any
     later version.
 
 or both in parallel, as here.
@@ -25,7 +25,7 @@ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General 
Public License
 for more details.
 
 You should have received copies of the GNU General Public License and the
-GNU Lesser General Public License along with the GNU MP Library.  If not,
+GNU General Public License along with the GNU MP Library.  If not,
 see https://www.gnu.org/licenses/.  */
 
 /* About mini-gmp: This is a minimal implementation of a subset of the
@@ -244,6 +244,10 @@ mp_bitcnt_t mpz_scan1 (const mpz_t, mp_bitcnt_t);
 
 int mpz_fits_slong_p (const mpz_t);
 int mpz_fits_ulong_p (const mpz_t);
+int mpz_fits_sint_p (const mpz_t);
+int mpz_fits_uint_p (const mpz_t);
+int mpz_fits_sshort_p (const mpz_t);
+int mpz_fits_ushort_p (const mpz_t);
 long int mpz_get_si (const mpz_t);
 unsigned long int mpz_get_ui (const mpz_t);
 double mpz_get_d (const mpz_t);
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 3a0fae1..f577a6f 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -118,6 +118,7 @@ AC_DEFUN([gl_EARLY],
   AC_REQUIRE([AC_SYS_LARGEFILE])
   # Code from module lchmod:
   # Code from module libc-config:
+  # Code from module libgmp:
   # Code from module limits-h:
   # Code from module localtime-buffer:
   # Code from module lstat:
@@ -345,6 +346,10 @@ AC_DEFUN([gl_INIT],
   gl_INTTYPES_INCOMPLETE
   AC_REQUIRE([gl_LARGEFILE])
   gl___INLINE
+  gl_LIBGMP
+  if test -n "$GMP_H"; then
+    AC_LIBOBJ([mini-gmp-gnulib])
+  fi
   gl_LIMITS_H
   gl_FUNC_LSTAT
   if test $REPLACE_LSTAT = 1; then
@@ -1035,6 +1040,9 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/memmem.c
   lib/mempcpy.c
   lib/memrchr.c
+  lib/mini-gmp-gnulib.c
+  lib/mini-gmp.c
+  lib/mini-gmp.h
   lib/minmax.h
   lib/mkostemp.c
   lib/mktime-internal.h
@@ -1166,6 +1174,7 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/inttypes.m4
   m4/largefile.m4
   m4/lchmod.m4
+  m4/libgmp.m4
   m4/limits-h.m4
   m4/localtime-buffer.m4
   m4/lstat.m4
diff --git a/m4/libgmp.m4 b/m4/libgmp.m4
new file mode 100644
index 0000000..b569bb7
--- /dev/null
+++ b/m4/libgmp.m4
@@ -0,0 +1,44 @@
+# Configure the GMP library or a replacement.
+
+dnl Copyright 2020 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_LIBGMP],
+[
+  AC_ARG_WITH([libgmp],
+    [AS_HELP_STRING([--without-libgmp],
+       [do not use the GNU Multiple Precision (GMP) library;
+        this is the default on systems lacking libgmp.])])
+
+  AC_CHECK_HEADERS_ONCE([gmp.h])
+  GMP_H=gmp.h
+  LIB_GMP=
+
+  case $with_libgmp in
+    no) ;;
+    yes) GMP_H= LIB_GMP=-lgmp;;
+    *) if test "$ac_cv_header_gmp_h" = yes; then
+         gl_saved_LIBS=$LIBS
+         AC_SEARCH_LIBS([__gmpz_roinit_n], [gmp])
+         LIBS=$gl_saved_LIBS
+         case $ac_cv_search___gmpz_roinit_n in
+           'none needed')
+             GMP_H=;;
+           -*)
+             GMP_H= LIB_GMP=$ac_cv_search___gmpz_roinit_n;;
+         esac
+       fi;;
+  esac
+
+  if test -z "$GMP_H"; then
+    AC_DEFINE([HAVE_GMP], 1,
+      [Define to 1 if you have the GMP library instead of just the
+       mini-gmp replacement.])
+  fi
+
+  AC_SUBST([LIB_GMP])
+  AC_SUBST([GMP_H])
+  AM_CONDITIONAL([GL_GENERATE_GMP_H], [test -n "$GMP_H"])
+])
diff --git a/src/Makefile.in b/src/Makefile.in
index 552dd2e..72d69fb 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -323,8 +323,7 @@ INTERVALS_H = dispextern.h intervals.h composite.h
 
 GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
 
-GMP_LIB = @GMP_LIB@
-GMP_OBJ = @GMP_OBJ@
+LIB_GMP = @LIB_GMP@
 
 RUN_TEMACS = ./temacs
 
@@ -531,7 +530,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) 
$(LIBIMAGE) \
    $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) 
$(M17N_FLT_LIBS) \
    $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \
    $(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \
-   $(JSON_LIBS) $(GMP_LIB)
+   $(JSON_LIBS) $(LIB_GMP)
 
 ## FORCE it so that admin/unidata can decide whether this file is
 ## up-to-date.  Although since charprop depends on bootstrap-emacs,
diff --git a/src/bignum.h b/src/bignum.h
index 4a906c3..251a19e 100644
--- a/src/bignum.h
+++ b/src/bignum.h
@@ -22,12 +22,7 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #ifndef BIGNUM_H
 #define BIGNUM_H
 
-#ifdef HAVE_GMP
-# include <gmp.h>
-#else
-# include "mini-gmp.h"
-#endif
-
+#include <gmp.h>
 #include "lisp.h"
 
 /* Number of data bits in a limb.  */
diff --git a/src/mini-gmp-emacs.c b/src/mini-gmp-emacs.c
deleted file mode 100644
index b8399b0..0000000
--- a/src/mini-gmp-emacs.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Tailor mini-gmp.c for GNU Emacs
-
-Copyright 2018-2020 Free Software Foundation, Inc.
-
-This file is part of GNU Emacs.
-
-GNU Emacs 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.
-
-GNU Emacs 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 GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
-
-#include <config.h>
-
-#include <stddef.h>
-
-/* Pacify GCC -Wsuggest-attribute=malloc.  */
-static void *gmp_default_alloc (size_t) ATTRIBUTE_MALLOC;
-
-/* Pacify GCC -Wunused-variable for variables used only in 'assert' calls.  */
-#if defined NDEBUG && GNUC_PREREQ (4, 6, 0)
-# pragma GCC diagnostic ignored "-Wunused-variable"
-#endif
-
-#include "mini-gmp.c"
diff --git a/test/Makefile.in b/test/Makefile.in
index f03c194..10e3d96 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -255,8 +255,8 @@ else
 FPIC_CFLAGS = -fPIC
 endif
 
-GMP_LIB = @GMP_LIB@
-GMP_OBJ = $(if @GMP_OBJ@, ../src/@GMP_OBJ@)
+GMP_H = @GMP_H@
+LIB_GMP = @LIB_GMP@
 
 # Note: emacs-module.h is generated from emacs-module.h.in, hence we
 # look in ../src, not $(srcdir)/../src.
@@ -273,7 +273,8 @@ src/emacs-module-tests.log src/emacs-module-tests.elc: 
$(test_module)
 $(test_module): $(test_module:${SO}=.c) ../src/emacs-module.h
        $(AM_V_at)${MKDIR_P} $(dir $@)
        $(AM_V_CCLD)$(CC) -shared $(CPPFLAGS) $(MODULE_CFLAGS) $(LDFLAGS) \
-         -o $@ $< $(GMP_LIB) $(GMP_OBJ:.o=.c) \
+         -o $@ $< $(LIB_GMP) \
+         $(and $(GMP_H),$(srcdir)/../lib/mini-gmp-gnulib.c) \
          $(srcdir)/../lib/timespec.c $(srcdir)/../lib/gettime.c
 endif
 
diff --git a/test/data/emacs-module/mod-test.c 
b/test/data/emacs-module/mod-test.c
index 5e3112f..1e64bcd 100644
--- a/test/data/emacs-module/mod-test.c
+++ b/test/data/emacs-module/mod-test.c
@@ -43,12 +43,7 @@ uintptr_t _beginthread (void (__cdecl *)(void *), unsigned, 
void *);
 # include <unistd.h>
 #endif
 
-#ifdef HAVE_GMP
 #include <gmp.h>
-#else
-#include "mini-gmp.h"
-#endif
-
 #include <emacs-module.h>
 
 #include "timespec.h"



reply via email to

[Prev in Thread] Current Thread [Next in Thread]