aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rwxr-xr-xadmin/merge-gnulib2
-rw-r--r--configure.ac33
-rw-r--r--lib/gnulib.mk.in29
-rw-r--r--lib/mini-gmp-gnulib.c37
-rw-r--r--lib/mini-gmp.c (renamed from src/mini-gmp.c)144
-rw-r--r--lib/mini-gmp.h (renamed from src/mini-gmp.h)10
-rw-r--r--m4/gnulib-comp.m49
-rw-r--r--m4/libgmp.m444
-rw-r--r--src/Makefile.in5
-rw-r--r--src/bignum.h7
-rw-r--r--src/mini-gmp-emacs.c32
-rw-r--r--test/Makefile.in7
-rw-r--r--test/data/emacs-module/mod-test.c5
14 files changed, 233 insertions, 132 deletions
diff --git a/.gitignore b/.gitignore
index d4be6bb23eb..890e63a4318 100644
--- a/.gitignore
+++ b/.gitignore
@@ -60,6 +60,7 @@ lib/execinfo.h
60lib/fcntl.h 60lib/fcntl.h
61lib/getopt.h 61lib/getopt.h
62lib/getopt-cdefs.h 62lib/getopt-cdefs.h
63lib/gmp.h
63lib/ieee754.h 64lib/ieee754.h
64lib/inttypes.h 65lib/inttypes.h
65lib/libgnu.a 66lib/libgnu.a
diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index 5a78b052b24..3f32536a629 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -36,7 +36,7 @@ GNULIB_MODULES='
36 fchmodat fcntl fcntl-h fdopendir 36 fchmodat fcntl fcntl-h fdopendir
37 filemode filename filevercmp flexmember fpieee fstatat fsusage fsync futimens 37 filemode filename filevercmp flexmember fpieee fstatat fsusage fsync futimens
38 getloadavg getopt-gnu getrandom gettime gettimeofday gitlog-to-changelog 38 getloadavg getopt-gnu getrandom gettime gettimeofday gitlog-to-changelog
39 ieee754-h ignore-value intprops largefile lstat 39 ieee754-h ignore-value intprops largefile libgmp lstat
40 manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime nstrftime 40 manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime nstrftime
41 pathmax pipe2 pselect pthread_sigmask 41 pathmax pipe2 pselect pthread_sigmask
42 qcopy-acl readlink readlinkat regex 42 qcopy-acl readlink readlinkat regex
diff --git a/configure.ac b/configure.ac
index 9fe1a0d32c1..148c50e0b39 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4507,32 +4507,6 @@ AC_SUBST(KRB5LIB)
4507AC_SUBST(DESLIB) 4507AC_SUBST(DESLIB)
4508AC_SUBST(KRB4LIB) 4508AC_SUBST(KRB4LIB)
4509 4509
4510AC_ARG_WITH([libgmp],
4511 [AS_HELP_STRING([--without-libgmp],
4512 [don't use the GNU Multiple Precision (GMP) library;
4513 this is the default on systems lacking libgmp.])])
4514GMP_LIB=
4515GMP_OBJ=mini-gmp-emacs.o
4516HAVE_GMP=no
4517case $with_libgmp in
4518 no) ;;
4519 yes) HAVE_GMP=yes GMP_LIB=-lgmp;;
4520 *) AC_CHECK_HEADERS([gmp.h],
4521 [OLIBS=$LIBS
4522 AC_SEARCH_LIBS([__gmpz_roinit_n], [gmp])
4523 LIBS=$OLIBS
4524 case $ac_cv_search___gmpz_roinit_n in
4525 'none needed') HAVE_GMP=yes;;
4526 -*) HAVE_GMP=yes GMP_LIB=$ac_cv_search___gmpz_roinit_n;;
4527 esac]);;
4528esac
4529if test "$HAVE_GMP" = yes; then
4530 GMP_OBJ=
4531 AC_DEFINE([HAVE_GMP], 1, [Define to 1 if you have recent-enough GMP.])
4532fi
4533AC_SUBST([GMP_LIB])
4534AC_SUBST([GMP_OBJ])
4535
4536AC_CHECK_HEADERS(valgrind/valgrind.h) 4510AC_CHECK_HEADERS(valgrind/valgrind.h)
4537 4511
4538AC_CHECK_MEMBERS([struct unipair.unicode], [], [], [[#include <linux/kd.h>]]) 4512AC_CHECK_MEMBERS([struct unipair.unicode], [], [], [[#include <linux/kd.h>]])
@@ -5700,6 +5674,11 @@ done
5700AC_DEFINE_UNQUOTED(EMACS_CONFIG_FEATURES, "${emacs_config_features}", 5674AC_DEFINE_UNQUOTED(EMACS_CONFIG_FEATURES, "${emacs_config_features}",
5701 [Summary of some of the main features enabled by configure.]) 5675 [Summary of some of the main features enabled by configure.])
5702 5676
5677if test -z "$GMP_H"; then
5678 HAVE_GMP=yes
5679else
5680 HAVE_GMP=no
5681fi
5703AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D} 5682AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D}
5704 Does Emacs use -lXpm? ${HAVE_XPM} 5683 Does Emacs use -lXpm? ${HAVE_XPM}
5705 Does Emacs use -ljpeg? ${HAVE_JPEG} 5684 Does Emacs use -ljpeg? ${HAVE_JPEG}
@@ -5728,7 +5707,7 @@ AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D
5728 Does Emacs use -lxft? ${HAVE_XFT} 5707 Does Emacs use -lxft? ${HAVE_XFT}
5729 Does Emacs use -lsystemd? ${HAVE_LIBSYSTEMD} 5708 Does Emacs use -lsystemd? ${HAVE_LIBSYSTEMD}
5730 Does Emacs use -ljansson? ${HAVE_JSON} 5709 Does Emacs use -ljansson? ${HAVE_JSON}
5731 Does Emacs use -lgmp? ${HAVE_GMP} 5710 Does Emacs use the GMP library? ${HAVE_GMP}
5732 Does Emacs directly use zlib? ${HAVE_ZLIB} 5711 Does Emacs directly use zlib? ${HAVE_ZLIB}
5733 Does Emacs have dynamic modules support? ${HAVE_MODULES} 5712 Does Emacs have dynamic modules support? ${HAVE_MODULES}
5734 Does Emacs use toolkit scroll bars? ${USE_TOOLKIT_SCROLL_BARS} 5713 Does Emacs use toolkit scroll bars? ${USE_TOOLKIT_SCROLL_BARS}
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index c249d626728..68cae8faf74 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -117,6 +117,7 @@
117# ignore-value \ 117# ignore-value \
118# intprops \ 118# intprops \
119# largefile \ 119# largefile \
120# libgmp \
120# lstat \ 121# lstat \
121# manywarnings \ 122# manywarnings \
122# memmem-simple \ 123# memmem-simple \
@@ -245,14 +246,14 @@ GL_GENERATE_ALLOCA_H = @GL_GENERATE_ALLOCA_H@
245GL_GENERATE_BYTESWAP_H = @GL_GENERATE_BYTESWAP_H@ 246GL_GENERATE_BYTESWAP_H = @GL_GENERATE_BYTESWAP_H@
246GL_GENERATE_ERRNO_H = @GL_GENERATE_ERRNO_H@ 247GL_GENERATE_ERRNO_H = @GL_GENERATE_ERRNO_H@
247GL_GENERATE_EXECINFO_H = @GL_GENERATE_EXECINFO_H@ 248GL_GENERATE_EXECINFO_H = @GL_GENERATE_EXECINFO_H@
249GL_GENERATE_GMP_H = @GL_GENERATE_GMP_H@
248GL_GENERATE_IEEE754_H = @GL_GENERATE_IEEE754_H@ 250GL_GENERATE_IEEE754_H = @GL_GENERATE_IEEE754_H@
249GL_GENERATE_LIMITS_H = @GL_GENERATE_LIMITS_H@ 251GL_GENERATE_LIMITS_H = @GL_GENERATE_LIMITS_H@
250GL_GENERATE_STDALIGN_H = @GL_GENERATE_STDALIGN_H@ 252GL_GENERATE_STDALIGN_H = @GL_GENERATE_STDALIGN_H@
251GL_GENERATE_STDDEF_H = @GL_GENERATE_STDDEF_H@ 253GL_GENERATE_STDDEF_H = @GL_GENERATE_STDDEF_H@
252GL_GENERATE_STDINT_H = @GL_GENERATE_STDINT_H@ 254GL_GENERATE_STDINT_H = @GL_GENERATE_STDINT_H@
253GMALLOC_OBJ = @GMALLOC_OBJ@ 255GMALLOC_OBJ = @GMALLOC_OBJ@
254GMP_LIB = @GMP_LIB@ 256GMP_H = @GMP_H@
255GMP_OBJ = @GMP_OBJ@
256GNULIB_ACCESS = @GNULIB_ACCESS@ 257GNULIB_ACCESS = @GNULIB_ACCESS@
257GNULIB_ALPHASORT = @GNULIB_ALPHASORT@ 258GNULIB_ALPHASORT = @GNULIB_ALPHASORT@
258GNULIB_ATOLL = @GNULIB_ATOLL@ 259GNULIB_ATOLL = @GNULIB_ATOLL@
@@ -760,6 +761,7 @@ LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@
760LIB_EACCESS = @LIB_EACCESS@ 761LIB_EACCESS = @LIB_EACCESS@
761LIB_EXECINFO = @LIB_EXECINFO@ 762LIB_EXECINFO = @LIB_EXECINFO@
762LIB_GETRANDOM = @LIB_GETRANDOM@ 763LIB_GETRANDOM = @LIB_GETRANDOM@
764LIB_GMP = @LIB_GMP@
763LIB_MATH = @LIB_MATH@ 765LIB_MATH = @LIB_MATH@
764LIB_PTHREAD = @LIB_PTHREAD@ 766LIB_PTHREAD = @LIB_PTHREAD@
765LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@ 767LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@
@@ -2014,6 +2016,29 @@ EXTRA_DIST += cdefs.h libc-config.h
2014endif 2016endif
2015## end gnulib module libc-config 2017## end gnulib module libc-config
2016 2018
2019## begin gnulib module libgmp
2020ifeq (,$(OMIT_GNULIB_MODULE_libgmp))
2021
2022BUILT_SOURCES += $(GMP_H)
2023
2024# Build gmp.h as a wrapper for mini-gmp.h when using mini-gmp.
2025ifneq (,$(GL_GENERATE_GMP_H))
2026gmp.h: $(top_builddir)/config.status
2027 echo '#include "mini-gmp.h"' >$@-t
2028 mv $@-t $@
2029else
2030gmp.h: $(top_builddir)/config.status
2031 rm -f $@
2032endif
2033MOSTLYCLEANFILES += gmp.h gmp.h-t
2034
2035EXTRA_DIST += mini-gmp-gnulib.c mini-gmp.c mini-gmp.h
2036
2037EXTRA_libgnu_a_SOURCES += mini-gmp-gnulib.c mini-gmp.c
2038
2039endif
2040## end gnulib module libgmp
2041
2017## begin gnulib module limits-h 2042## begin gnulib module limits-h
2018ifeq (,$(OMIT_GNULIB_MODULE_limits-h)) 2043ifeq (,$(OMIT_GNULIB_MODULE_limits-h))
2019 2044
diff --git a/lib/mini-gmp-gnulib.c b/lib/mini-gmp-gnulib.c
new file mode 100644
index 00000000000..5019be5d52a
--- /dev/null
+++ b/lib/mini-gmp-gnulib.c
@@ -0,0 +1,37 @@
1/* Tailor mini-gmp.c for Gnulib-using applications.
2
3 Copyright 2018-2020 Free Software Foundation, Inc.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17
18#include <config.h>
19
20#include <stddef.h>
21#include <stdio.h>
22
23#include "mini-gmp.h"
24
25/* Pacify GCC -Wsuggest-attribute=const, malloc, pure. */
26#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
27# pragma GCC diagnostic ignored "-Wsuggest-attribute=const"
28# pragma GCC diagnostic ignored "-Wsuggest-attribute=malloc"
29# pragma GCC diagnostic ignored "-Wsuggest-attribute=pure"
30#endif
31
32/* Pacify GCC -Wunused-variable for variables used only in 'assert' calls. */
33#if defined NDEBUG && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
34# pragma GCC diagnostic ignored "-Wunused-variable"
35#endif
36
37#include "mini-gmp.c"
diff --git a/src/mini-gmp.c b/lib/mini-gmp.c
index 2e789a2dfcc..2e0301b0081 100644
--- a/src/mini-gmp.c
+++ b/lib/mini-gmp.c
@@ -2,21 +2,21 @@
2 2
3 Contributed to the GNU project by Niels Möller 3 Contributed to the GNU project by Niels Möller
4 4
5Copyright 1991-1997, 1999-2019 Free Software Foundation, Inc. 5Copyright 1991-1997, 1999-2020 Free Software Foundation, Inc.
6 6
7This file is part of the GNU MP Library. 7This file is part of the GNU MP Library.
8 8
9The GNU MP Library is free software; you can redistribute it and/or modify 9The GNU MP Library is free software; you can redistribute it and/or modify
10it under the terms of either: 10it under the terms of either:
11 11
12 * the GNU Lesser General Public License as published by the Free 12 * the GNU General Public License as published by the Free
13 Software Foundation; either version 3 of the License, or (at your 13 Software Foundation; either version 3 of the License, or (at your
14 option) any later version. 14 option) any later version.
15 15
16or 16or
17 17
18 * the GNU General Public License as published by the Free Software 18 * the GNU General Public License as published by the Free Software
19 Foundation; either version 2 of the License, or (at your option) any 19 Foundation; either version 3 of the License, or (at your option) any
20 later version. 20 later version.
21 21
22or both in parallel, as here. 22or both in parallel, as here.
@@ -27,7 +27,7 @@ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27for more details. 27for more details.
28 28
29You should have received copies of the GNU General Public License and the 29You should have received copies of the GNU General Public License and the
30GNU Lesser General Public License along with the GNU MP Library. If not, 30GNU General Public License along with the GNU MP Library. If not,
31see https://www.gnu.org/licenses/. */ 31see https://www.gnu.org/licenses/. */
32 32
33/* NOTE: All functions in this file which are not declared in 33/* NOTE: All functions in this file which are not declared in
@@ -351,20 +351,27 @@ mp_set_memory_functions (void *(*alloc_func) (size_t),
351 gmp_free_func = free_func; 351 gmp_free_func = free_func;
352} 352}
353 353
354#define gmp_xalloc(size) ((*gmp_allocate_func)((size))) 354#define gmp_alloc(size) ((*gmp_allocate_func)((size)))
355#define gmp_free(p) ((*gmp_free_func) ((p), 0)) 355#define gmp_free(p, size) ((*gmp_free_func) ((p), (size)))
356#define gmp_realloc(ptr, old_size, size) ((*gmp_reallocate_func)(ptr, old_size, size))
356 357
357static mp_ptr 358static mp_ptr
358gmp_xalloc_limbs (mp_size_t size) 359gmp_alloc_limbs (mp_size_t size)
359{ 360{
360 return (mp_ptr) gmp_xalloc (size * sizeof (mp_limb_t)); 361 return (mp_ptr) gmp_alloc (size * sizeof (mp_limb_t));
361} 362}
362 363
363static mp_ptr 364static mp_ptr
364gmp_xrealloc_limbs (mp_ptr old, mp_size_t size) 365gmp_realloc_limbs (mp_ptr old, mp_size_t old_size, mp_size_t size)
365{ 366{
366 assert (size > 0); 367 assert (size > 0);
367 return (mp_ptr) (*gmp_reallocate_func) (old, 0, size * sizeof (mp_limb_t)); 368 return (mp_ptr) gmp_realloc (old, old_size * sizeof (mp_limb_t), size * sizeof (mp_limb_t));
369}
370
371static void
372gmp_free_limbs (mp_ptr old, mp_size_t size)
373{
374 gmp_free (old, size * sizeof (mp_limb_t));
368} 375}
369 376
370 377
@@ -956,11 +963,17 @@ mpn_div_qr_1_preinv (mp_ptr qp, mp_srcptr np, mp_size_t nn,
956 mp_limb_t d, di; 963 mp_limb_t d, di;
957 mp_limb_t r; 964 mp_limb_t r;
958 mp_ptr tp = NULL; 965 mp_ptr tp = NULL;
966 mp_size_t tn = 0;
959 967
960 if (inv->shift > 0) 968 if (inv->shift > 0)
961 { 969 {
962 /* Shift, reusing qp area if possible. In-place shift if qp == np. */ 970 /* Shift, reusing qp area if possible. In-place shift if qp == np. */
963 tp = qp ? qp : gmp_xalloc_limbs (nn); 971 tp = qp;
972 if (!tp)
973 {
974 tn = nn;
975 tp = gmp_alloc_limbs (tn);
976 }
964 r = mpn_lshift (tp, np, nn, inv->shift); 977 r = mpn_lshift (tp, np, nn, inv->shift);
965 np = tp; 978 np = tp;
966 } 979 }
@@ -977,8 +990,8 @@ mpn_div_qr_1_preinv (mp_ptr qp, mp_srcptr np, mp_size_t nn,
977 if (qp) 990 if (qp)
978 qp[nn] = q; 991 qp[nn] = q;
979 } 992 }
980 if ((inv->shift > 0) && (tp != qp)) 993 if (tn)
981 gmp_free (tp); 994 gmp_free_limbs (tp, tn);
982 995
983 return r >> inv->shift; 996 return r >> inv->shift;
984} 997}
@@ -1136,13 +1149,13 @@ mpn_div_qr (mp_ptr qp, mp_ptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn)
1136 mpn_div_qr_invert (&inv, dp, dn); 1149 mpn_div_qr_invert (&inv, dp, dn);
1137 if (dn > 2 && inv.shift > 0) 1150 if (dn > 2 && inv.shift > 0)
1138 { 1151 {
1139 tp = gmp_xalloc_limbs (dn); 1152 tp = gmp_alloc_limbs (dn);
1140 gmp_assert_nocarry (mpn_lshift (tp, dp, dn, inv.shift)); 1153 gmp_assert_nocarry (mpn_lshift (tp, dp, dn, inv.shift));
1141 dp = tp; 1154 dp = tp;
1142 } 1155 }
1143 mpn_div_qr_preinv (qp, np, nn, dp, dn, &inv); 1156 mpn_div_qr_preinv (qp, np, nn, dp, dn, &inv);
1144 if (tp) 1157 if (tp)
1145 gmp_free (tp); 1158 gmp_free_limbs (tp, dn);
1146} 1159}
1147 1160
1148 1161
@@ -1428,14 +1441,14 @@ mpz_init2 (mpz_t r, mp_bitcnt_t bits)
1428 1441
1429 r->_mp_alloc = rn; 1442 r->_mp_alloc = rn;
1430 r->_mp_size = 0; 1443 r->_mp_size = 0;
1431 r->_mp_d = gmp_xalloc_limbs (rn); 1444 r->_mp_d = gmp_alloc_limbs (rn);
1432} 1445}
1433 1446
1434void 1447void
1435mpz_clear (mpz_t r) 1448mpz_clear (mpz_t r)
1436{ 1449{
1437 if (r->_mp_alloc) 1450 if (r->_mp_alloc)
1438 gmp_free (r->_mp_d); 1451 gmp_free_limbs (r->_mp_d, r->_mp_alloc);
1439} 1452}
1440 1453
1441static mp_ptr 1454static mp_ptr
@@ -1444,9 +1457,9 @@ mpz_realloc (mpz_t r, mp_size_t size)
1444 size = GMP_MAX (size, 1); 1457 size = GMP_MAX (size, 1);
1445 1458
1446 if (r->_mp_alloc) 1459 if (r->_mp_alloc)
1447 r->_mp_d = gmp_xrealloc_limbs (r->_mp_d, size); 1460 r->_mp_d = gmp_realloc_limbs (r->_mp_d, r->_mp_alloc, size);
1448 else 1461 else
1449 r->_mp_d = gmp_xalloc_limbs (size); 1462 r->_mp_d = gmp_alloc_limbs (size);
1450 r->_mp_alloc = size; 1463 r->_mp_alloc = size;
1451 1464
1452 if (GMP_ABS (r->_mp_size) > size) 1465 if (GMP_ABS (r->_mp_size) > size)
@@ -1541,8 +1554,7 @@ mpz_init_set (mpz_t r, const mpz_t x)
1541int 1554int
1542mpz_fits_slong_p (const mpz_t u) 1555mpz_fits_slong_p (const mpz_t u)
1543{ 1556{
1544 return (LONG_MAX + LONG_MIN == 0 || mpz_cmp_ui (u, LONG_MAX) <= 0) && 1557 return mpz_cmp_si (u, LONG_MAX) <= 0 && mpz_cmp_si (u, LONG_MIN) >= 0;
1545 mpz_cmpabs_ui (u, GMP_NEG_CAST (unsigned long int, LONG_MIN)) <= 0;
1546} 1558}
1547 1559
1548static int 1560static int
@@ -1565,6 +1577,30 @@ mpz_fits_ulong_p (const mpz_t u)
1565 return us >= 0 && mpn_absfits_ulong_p (u->_mp_d, us); 1577 return us >= 0 && mpn_absfits_ulong_p (u->_mp_d, us);
1566} 1578}
1567 1579
1580int
1581mpz_fits_sint_p (const mpz_t u)
1582{
1583 return mpz_cmp_si (u, INT_MAX) <= 0 && mpz_cmp_si (u, INT_MIN) >= 0;
1584}
1585
1586int
1587mpz_fits_uint_p (const mpz_t u)
1588{
1589 return u->_mp_size >= 0 && mpz_cmpabs_ui (u, UINT_MAX) <= 0;
1590}
1591
1592int
1593mpz_fits_sshort_p (const mpz_t u)
1594{
1595 return mpz_cmp_si (u, SHRT_MAX) <= 0 && mpz_cmp_si (u, SHRT_MIN) >= 0;
1596}
1597
1598int
1599mpz_fits_ushort_p (const mpz_t u)
1600{
1601 return u->_mp_size >= 0 && mpz_cmpabs_ui (u, USHRT_MAX) <= 0;
1602}
1603
1568long int 1604long int
1569mpz_get_si (const mpz_t u) 1605mpz_get_si (const mpz_t u)
1570{ 1606{
@@ -3073,7 +3109,7 @@ mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const mpz_t m)
3073 one, using a *normalized* m. */ 3109 one, using a *normalized* m. */
3074 minv.shift = 0; 3110 minv.shift = 0;
3075 3111
3076 tp = gmp_xalloc_limbs (mn); 3112 tp = gmp_alloc_limbs (mn);
3077 gmp_assert_nocarry (mpn_lshift (tp, mp, mn, shift)); 3113 gmp_assert_nocarry (mpn_lshift (tp, mp, mn, shift));
3078 mp = tp; 3114 mp = tp;
3079 } 3115 }
@@ -3139,7 +3175,7 @@ mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const mpz_t m)
3139 tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn); 3175 tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn);
3140 } 3176 }
3141 if (tp) 3177 if (tp)
3142 gmp_free (tp); 3178 gmp_free_limbs (tp, mn);
3143 3179
3144 mpz_swap (r, tr); 3180 mpz_swap (r, tr);
3145 mpz_clear (tr); 3181 mpz_clear (tr);
@@ -3350,13 +3386,15 @@ gmp_jacobi_coprime (mp_limb_t a, mp_limb_t b)
3350 gmp_ctz(c, a); 3386 gmp_ctz(c, a);
3351 a >>= 1; 3387 a >>= 1;
3352 3388
3353 do 3389 for (;;)
3354 { 3390 {
3355 a >>= c; 3391 a >>= c;
3356 /* (2/b) = -1 if b = 3 or 5 mod 8 */ 3392 /* (2/b) = -1 if b = 3 or 5 mod 8 */
3357 bit ^= c & (b ^ (b >> 1)); 3393 bit ^= c & (b ^ (b >> 1));
3358 if (a < b) 3394 if (a < b)
3359 { 3395 {
3396 if (a == 0)
3397 return bit & 1 ? -1 : 1;
3360 bit ^= a & b; 3398 bit ^= a & b;
3361 a = b - a; 3399 a = b - a;
3362 b -= a; 3400 b -= a;
@@ -3370,9 +3408,6 @@ gmp_jacobi_coprime (mp_limb_t a, mp_limb_t b)
3370 gmp_ctz(c, a); 3408 gmp_ctz(c, a);
3371 ++c; 3409 ++c;
3372 } 3410 }
3373 while (b > 0);
3374
3375 return bit & 1 ? -1 : 1;
3376} 3411}
3377 3412
3378static void 3413static void
@@ -4144,7 +4179,7 @@ mpz_scan0 (const mpz_t u, mp_bitcnt_t starting_bit)
4144size_t 4179size_t
4145mpz_sizeinbase (const mpz_t u, int base) 4180mpz_sizeinbase (const mpz_t u, int base)
4146{ 4181{
4147 mp_size_t un; 4182 mp_size_t un, tn;
4148 mp_srcptr up; 4183 mp_srcptr up;
4149 mp_ptr tp; 4184 mp_ptr tp;
4150 mp_bitcnt_t bits; 4185 mp_bitcnt_t bits;
@@ -4177,20 +4212,21 @@ mpz_sizeinbase (const mpz_t u, int base)
4177 10. */ 4212 10. */
4178 } 4213 }
4179 4214
4180 tp = gmp_xalloc_limbs (un); 4215 tp = gmp_alloc_limbs (un);
4181 mpn_copyi (tp, up, un); 4216 mpn_copyi (tp, up, un);
4182 mpn_div_qr_1_invert (&bi, base); 4217 mpn_div_qr_1_invert (&bi, base);
4183 4218
4219 tn = un;
4184 ndigits = 0; 4220 ndigits = 0;
4185 do 4221 do
4186 { 4222 {
4187 ndigits++; 4223 ndigits++;
4188 mpn_div_qr_1_preinv (tp, tp, un, &bi); 4224 mpn_div_qr_1_preinv (tp, tp, tn, &bi);
4189 un -= (tp[un-1] == 0); 4225 tn -= (tp[tn-1] == 0);
4190 } 4226 }
4191 while (un > 0); 4227 while (tn > 0);
4192 4228
4193 gmp_free (tp); 4229 gmp_free_limbs (tp, un);
4194 return ndigits; 4230 return ndigits;
4195} 4231}
4196 4232
@@ -4200,7 +4236,7 @@ mpz_get_str (char *sp, int base, const mpz_t u)
4200 unsigned bits; 4236 unsigned bits;
4201 const char *digits; 4237 const char *digits;
4202 mp_size_t un; 4238 mp_size_t un;
4203 size_t i, sn; 4239 size_t i, sn, osn;
4204 4240
4205 digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 4241 digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
4206 if (base > 1) 4242 if (base > 1)
@@ -4221,15 +4257,19 @@ mpz_get_str (char *sp, int base, const mpz_t u)
4221 4257
4222 sn = 1 + mpz_sizeinbase (u, base); 4258 sn = 1 + mpz_sizeinbase (u, base);
4223 if (!sp) 4259 if (!sp)
4224 sp = (char *) gmp_xalloc (1 + sn); 4260 {
4225 4261 osn = 1 + sn;
4262 sp = (char *) gmp_alloc (osn);
4263 }
4264 else
4265 osn = 0;
4226 un = GMP_ABS (u->_mp_size); 4266 un = GMP_ABS (u->_mp_size);
4227 4267
4228 if (un == 0) 4268 if (un == 0)
4229 { 4269 {
4230 sp[0] = '0'; 4270 sp[0] = '0';
4231 sp[1] = '\0'; 4271 sn = 1;
4232 return sp; 4272 goto ret;
4233 } 4273 }
4234 4274
4235 i = 0; 4275 i = 0;
@@ -4248,17 +4288,20 @@ mpz_get_str (char *sp, int base, const mpz_t u)
4248 mp_ptr tp; 4288 mp_ptr tp;
4249 4289
4250 mpn_get_base_info (&info, base); 4290 mpn_get_base_info (&info, base);
4251 tp = gmp_xalloc_limbs (un); 4291 tp = gmp_alloc_limbs (un);
4252 mpn_copyi (tp, u->_mp_d, un); 4292 mpn_copyi (tp, u->_mp_d, un);
4253 4293
4254 sn = i + mpn_get_str_other ((unsigned char *) sp + i, base, &info, tp, un); 4294 sn = i + mpn_get_str_other ((unsigned char *) sp + i, base, &info, tp, un);
4255 gmp_free (tp); 4295 gmp_free_limbs (tp, un);
4256 } 4296 }
4257 4297
4258 for (; i < sn; i++) 4298 for (; i < sn; i++)
4259 sp[i] = digits[(unsigned char) sp[i]]; 4299 sp[i] = digits[(unsigned char) sp[i]];
4260 4300
4301ret:
4261 sp[sn] = '\0'; 4302 sp[sn] = '\0';
4303 if (osn && osn != sn + 1)
4304 sp = gmp_realloc(sp, osn, sn + 1);
4262 return sp; 4305 return sp;
4263} 4306}
4264 4307
@@ -4268,7 +4311,7 @@ mpz_set_str (mpz_t r, const char *sp, int base)
4268 unsigned bits, value_of_a; 4311 unsigned bits, value_of_a;
4269 mp_size_t rn, alloc; 4312 mp_size_t rn, alloc;
4270 mp_ptr rp; 4313 mp_ptr rp;
4271 size_t dn; 4314 size_t dn, sn;
4272 int sign; 4315 int sign;
4273 unsigned char *dp; 4316 unsigned char *dp;
4274 4317
@@ -4306,7 +4349,8 @@ mpz_set_str (mpz_t r, const char *sp, int base)
4306 r->_mp_size = 0; 4349 r->_mp_size = 0;
4307 return -1; 4350 return -1;
4308 } 4351 }
4309 dp = (unsigned char *) gmp_xalloc (strlen (sp)); 4352 sn = strlen(sp);
4353 dp = (unsigned char *) gmp_alloc (sn);
4310 4354
4311 value_of_a = (base > 36) ? 36 : 10; 4355 value_of_a = (base > 36) ? 36 : 10;
4312 for (dn = 0; *sp; sp++) 4356 for (dn = 0; *sp; sp++)
@@ -4326,7 +4370,7 @@ mpz_set_str (mpz_t r, const char *sp, int base)
4326 4370
4327 if (digit >= (unsigned) base) 4371 if (digit >= (unsigned) base)
4328 { 4372 {
4329 gmp_free (dp); 4373 gmp_free (dp, sn);
4330 r->_mp_size = 0; 4374 r->_mp_size = 0;
4331 return -1; 4375 return -1;
4332 } 4376 }
@@ -4336,7 +4380,7 @@ mpz_set_str (mpz_t r, const char *sp, int base)
4336 4380
4337 if (!dn) 4381 if (!dn)
4338 { 4382 {
4339 gmp_free (dp); 4383 gmp_free (dp, sn);
4340 r->_mp_size = 0; 4384 r->_mp_size = 0;
4341 return -1; 4385 return -1;
4342 } 4386 }
@@ -4360,7 +4404,7 @@ mpz_set_str (mpz_t r, const char *sp, int base)
4360 rn -= rp[rn-1] == 0; 4404 rn -= rp[rn-1] == 0;
4361 } 4405 }
4362 assert (rn <= alloc); 4406 assert (rn <= alloc);
4363 gmp_free (dp); 4407 gmp_free (dp, sn);
4364 4408
4365 r->_mp_size = sign ? - rn : rn; 4409 r->_mp_size = sign ? - rn : rn;
4366 4410
@@ -4378,13 +4422,13 @@ size_t
4378mpz_out_str (FILE *stream, int base, const mpz_t x) 4422mpz_out_str (FILE *stream, int base, const mpz_t x)
4379{ 4423{
4380 char *str; 4424 char *str;
4381 size_t len; 4425 size_t len, n;
4382 4426
4383 str = mpz_get_str (NULL, base, x); 4427 str = mpz_get_str (NULL, base, x);
4384 len = strlen (str); 4428 len = strlen (str);
4385 len = fwrite (str, 1, len, stream); 4429 n = fwrite (str, 1, len, stream);
4386 gmp_free (str); 4430 gmp_free (str, len + 1);
4387 return len; 4431 return n;
4388} 4432}
4389 4433
4390 4434
@@ -4512,7 +4556,7 @@ mpz_export (void *r, size_t *countp, int order, size_t size, int endian,
4512 count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size; 4556 count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size;
4513 4557
4514 if (!r) 4558 if (!r)
4515 r = gmp_xalloc (count * size); 4559 r = gmp_alloc (count * size);
4516 4560
4517 if (endian == 0) 4561 if (endian == 0)
4518 endian = gmp_detect_endian (); 4562 endian = gmp_detect_endian ();
diff --git a/src/mini-gmp.h b/lib/mini-gmp.h
index 7cce3f7a328..c00568c2568 100644
--- a/src/mini-gmp.h
+++ b/lib/mini-gmp.h
@@ -7,14 +7,14 @@ This file is part of the GNU MP Library.
7The GNU MP Library is free software; you can redistribute it and/or modify 7The GNU MP Library is free software; you can redistribute it and/or modify
8it under the terms of either: 8it under the terms of either:
9 9
10 * the GNU Lesser General Public License as published by the Free 10 * the GNU General Public License as published by the Free
11 Software Foundation; either version 3 of the License, or (at your 11 Software Foundation; either version 3 of the License, or (at your
12 option) any later version. 12 option) any later version.
13 13
14or 14or
15 15
16 * the GNU General Public License as published by the Free Software 16 * the GNU General Public License as published by the Free Software
17 Foundation; either version 2 of the License, or (at your option) any 17 Foundation; either version 3 of the License, or (at your option) any
18 later version. 18 later version.
19 19
20or both in parallel, as here. 20or both in parallel, as here.
@@ -25,7 +25,7 @@ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25for more details. 25for more details.
26 26
27You should have received copies of the GNU General Public License and the 27You should have received copies of the GNU General Public License and the
28GNU Lesser General Public License along with the GNU MP Library. If not, 28GNU General Public License along with the GNU MP Library. If not,
29see https://www.gnu.org/licenses/. */ 29see https://www.gnu.org/licenses/. */
30 30
31/* About mini-gmp: This is a minimal implementation of a subset of the 31/* 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);
244 244
245int mpz_fits_slong_p (const mpz_t); 245int mpz_fits_slong_p (const mpz_t);
246int mpz_fits_ulong_p (const mpz_t); 246int mpz_fits_ulong_p (const mpz_t);
247int mpz_fits_sint_p (const mpz_t);
248int mpz_fits_uint_p (const mpz_t);
249int mpz_fits_sshort_p (const mpz_t);
250int mpz_fits_ushort_p (const mpz_t);
247long int mpz_get_si (const mpz_t); 251long int mpz_get_si (const mpz_t);
248unsigned long int mpz_get_ui (const mpz_t); 252unsigned long int mpz_get_ui (const mpz_t);
249double mpz_get_d (const mpz_t); 253double mpz_get_d (const mpz_t);
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 3a0fae11c44..f577a6fa741 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -118,6 +118,7 @@ AC_DEFUN([gl_EARLY],
118 AC_REQUIRE([AC_SYS_LARGEFILE]) 118 AC_REQUIRE([AC_SYS_LARGEFILE])
119 # Code from module lchmod: 119 # Code from module lchmod:
120 # Code from module libc-config: 120 # Code from module libc-config:
121 # Code from module libgmp:
121 # Code from module limits-h: 122 # Code from module limits-h:
122 # Code from module localtime-buffer: 123 # Code from module localtime-buffer:
123 # Code from module lstat: 124 # Code from module lstat:
@@ -345,6 +346,10 @@ AC_DEFUN([gl_INIT],
345 gl_INTTYPES_INCOMPLETE 346 gl_INTTYPES_INCOMPLETE
346 AC_REQUIRE([gl_LARGEFILE]) 347 AC_REQUIRE([gl_LARGEFILE])
347 gl___INLINE 348 gl___INLINE
349 gl_LIBGMP
350 if test -n "$GMP_H"; then
351 AC_LIBOBJ([mini-gmp-gnulib])
352 fi
348 gl_LIMITS_H 353 gl_LIMITS_H
349 gl_FUNC_LSTAT 354 gl_FUNC_LSTAT
350 if test $REPLACE_LSTAT = 1; then 355 if test $REPLACE_LSTAT = 1; then
@@ -1035,6 +1040,9 @@ AC_DEFUN([gl_FILE_LIST], [
1035 lib/memmem.c 1040 lib/memmem.c
1036 lib/mempcpy.c 1041 lib/mempcpy.c
1037 lib/memrchr.c 1042 lib/memrchr.c
1043 lib/mini-gmp-gnulib.c
1044 lib/mini-gmp.c
1045 lib/mini-gmp.h
1038 lib/minmax.h 1046 lib/minmax.h
1039 lib/mkostemp.c 1047 lib/mkostemp.c
1040 lib/mktime-internal.h 1048 lib/mktime-internal.h
@@ -1166,6 +1174,7 @@ AC_DEFUN([gl_FILE_LIST], [
1166 m4/inttypes.m4 1174 m4/inttypes.m4
1167 m4/largefile.m4 1175 m4/largefile.m4
1168 m4/lchmod.m4 1176 m4/lchmod.m4
1177 m4/libgmp.m4
1169 m4/limits-h.m4 1178 m4/limits-h.m4
1170 m4/localtime-buffer.m4 1179 m4/localtime-buffer.m4
1171 m4/lstat.m4 1180 m4/lstat.m4
diff --git a/m4/libgmp.m4 b/m4/libgmp.m4
new file mode 100644
index 00000000000..b569bb73462
--- /dev/null
+++ b/m4/libgmp.m4
@@ -0,0 +1,44 @@
1# Configure the GMP library or a replacement.
2
3dnl Copyright 2020 Free Software Foundation, Inc.
4dnl This file is free software; the Free Software Foundation
5dnl gives unlimited permission to copy and/or distribute it,
6dnl with or without modifications, as long as this notice is preserved.
7
8AC_DEFUN([gl_LIBGMP],
9[
10 AC_ARG_WITH([libgmp],
11 [AS_HELP_STRING([--without-libgmp],
12 [do not use the GNU Multiple Precision (GMP) library;
13 this is the default on systems lacking libgmp.])])
14
15 AC_CHECK_HEADERS_ONCE([gmp.h])
16 GMP_H=gmp.h
17 LIB_GMP=
18
19 case $with_libgmp in
20 no) ;;
21 yes) GMP_H= LIB_GMP=-lgmp;;
22 *) if test "$ac_cv_header_gmp_h" = yes; then
23 gl_saved_LIBS=$LIBS
24 AC_SEARCH_LIBS([__gmpz_roinit_n], [gmp])
25 LIBS=$gl_saved_LIBS
26 case $ac_cv_search___gmpz_roinit_n in
27 'none needed')
28 GMP_H=;;
29 -*)
30 GMP_H= LIB_GMP=$ac_cv_search___gmpz_roinit_n;;
31 esac
32 fi;;
33 esac
34
35 if test -z "$GMP_H"; then
36 AC_DEFINE([HAVE_GMP], 1,
37 [Define to 1 if you have the GMP library instead of just the
38 mini-gmp replacement.])
39 fi
40
41 AC_SUBST([LIB_GMP])
42 AC_SUBST([GMP_H])
43 AM_CONDITIONAL([GL_GENERATE_GMP_H], [test -n "$GMP_H"])
44])
diff --git a/src/Makefile.in b/src/Makefile.in
index 552dd2e50ae..72d69fb7a3e 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -323,8 +323,7 @@ INTERVALS_H = dispextern.h intervals.h composite.h
323 323
324GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ 324GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
325 325
326GMP_LIB = @GMP_LIB@ 326LIB_GMP = @LIB_GMP@
327GMP_OBJ = @GMP_OBJ@
328 327
329RUN_TEMACS = ./temacs 328RUN_TEMACS = ./temacs
330 329
@@ -531,7 +530,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
531 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ 530 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
532 $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \ 531 $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \
533 $(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \ 532 $(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \
534 $(JSON_LIBS) $(GMP_LIB) 533 $(JSON_LIBS) $(LIB_GMP)
535 534
536## FORCE it so that admin/unidata can decide whether this file is 535## FORCE it so that admin/unidata can decide whether this file is
537## up-to-date. Although since charprop depends on bootstrap-emacs, 536## up-to-date. Although since charprop depends on bootstrap-emacs,
diff --git a/src/bignum.h b/src/bignum.h
index 4a906c3c0eb..251a19e338a 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/>. */
22#ifndef BIGNUM_H 22#ifndef BIGNUM_H
23#define BIGNUM_H 23#define BIGNUM_H
24 24
25#ifdef HAVE_GMP 25#include <gmp.h>
26# include <gmp.h>
27#else
28# include "mini-gmp.h"
29#endif
30
31#include "lisp.h" 26#include "lisp.h"
32 27
33/* Number of data bits in a limb. */ 28/* 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 b8399b075e0..00000000000
--- a/src/mini-gmp-emacs.c
+++ /dev/null
@@ -1,32 +0,0 @@
1/* Tailor mini-gmp.c for GNU Emacs
2
3Copyright 2018-2020 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or (at
10your option) any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
19
20#include <config.h>
21
22#include <stddef.h>
23
24/* Pacify GCC -Wsuggest-attribute=malloc. */
25static void *gmp_default_alloc (size_t) ATTRIBUTE_MALLOC;
26
27/* Pacify GCC -Wunused-variable for variables used only in 'assert' calls. */
28#if defined NDEBUG && GNUC_PREREQ (4, 6, 0)
29# pragma GCC diagnostic ignored "-Wunused-variable"
30#endif
31
32#include "mini-gmp.c"
diff --git a/test/Makefile.in b/test/Makefile.in
index f03c194a7cb..10e3d9617d3 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -255,8 +255,8 @@ else
255FPIC_CFLAGS = -fPIC 255FPIC_CFLAGS = -fPIC
256endif 256endif
257 257
258GMP_LIB = @GMP_LIB@ 258GMP_H = @GMP_H@
259GMP_OBJ = $(if @GMP_OBJ@, ../src/@GMP_OBJ@) 259LIB_GMP = @LIB_GMP@
260 260
261# Note: emacs-module.h is generated from emacs-module.h.in, hence we 261# Note: emacs-module.h is generated from emacs-module.h.in, hence we
262# look in ../src, not $(srcdir)/../src. 262# look in ../src, not $(srcdir)/../src.
@@ -273,7 +273,8 @@ src/emacs-module-tests.log src/emacs-module-tests.elc: $(test_module)
273$(test_module): $(test_module:${SO}=.c) ../src/emacs-module.h 273$(test_module): $(test_module:${SO}=.c) ../src/emacs-module.h
274 $(AM_V_at)${MKDIR_P} $(dir $@) 274 $(AM_V_at)${MKDIR_P} $(dir $@)
275 $(AM_V_CCLD)$(CC) -shared $(CPPFLAGS) $(MODULE_CFLAGS) $(LDFLAGS) \ 275 $(AM_V_CCLD)$(CC) -shared $(CPPFLAGS) $(MODULE_CFLAGS) $(LDFLAGS) \
276 -o $@ $< $(GMP_LIB) $(GMP_OBJ:.o=.c) \ 276 -o $@ $< $(LIB_GMP) \
277 $(and $(GMP_H),$(srcdir)/../lib/mini-gmp-gnulib.c) \
277 $(srcdir)/../lib/timespec.c $(srcdir)/../lib/gettime.c 278 $(srcdir)/../lib/timespec.c $(srcdir)/../lib/gettime.c
278endif 279endif
279 280
diff --git a/test/data/emacs-module/mod-test.c b/test/data/emacs-module/mod-test.c
index 5e3112f4471..1e64bcd65f1 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 *);
43# include <unistd.h> 43# include <unistd.h>
44#endif 44#endif
45 45
46#ifdef HAVE_GMP
47#include <gmp.h> 46#include <gmp.h>
48#else
49#include "mini-gmp.h"
50#endif
51
52#include <emacs-module.h> 47#include <emacs-module.h>
53 48
54#include "timespec.h" 49#include "timespec.h"