From: Paul Eggert Date: Tue, 7 Jul 2020 17:39:10 +0000 (-0700) Subject: maint: use Gnulib libgmp module X-Git-Tag: v9.0~222 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=13046444888a7e96f48d28fdd5a6ffe03d4ab036;p=thirdparty%2Fcoreutils.git maint: use Gnulib libgmp module This lets use assume multiple-precision arithmetic on all platforms, simplifying the code. * bootstrap.conf (gnulib_modules): Add libgmp. * configure.ac: Don’t call cu_GMP, as this is now done by Gnulib. * m4/gmp.m4: Remove. * src/expr.c, src/factor.c: Use gmp.h unconditionally. * src/factor.c: Use the simpler ‘#ifndef mpz_inits’ to determine whether there is an mpz_inits macro. --- diff --git a/bootstrap.conf b/bootstrap.conf index 2506f0db47..b5b6dc2403 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -144,6 +144,7 @@ gnulib_modules=" lchown ldtoastr lib-ignore + libgmp linebuffer link link-follow diff --git a/configure.ac b/configure.ac index c2ad08c393..0afbff6271 100644 --- a/configure.ac +++ b/configure.ac @@ -474,8 +474,6 @@ AC_CHECK_DECLS([strsignal, sys_siglist, _sys_siglist, __sys_siglist], , , [AC_INCLUDES_DEFAULT #include ]) -cu_GMP - # Build df only if there's a point to it. if test $gl_cv_list_mounted_fs = yes && test $gl_cv_fs_space = yes; then gl_ADD_PROG([optional_bin_progs], [df]) diff --git a/m4/gmp.m4 b/m4/gmp.m4 deleted file mode 100644 index 20ae9b4c83..0000000000 --- a/m4/gmp.m4 +++ /dev/null @@ -1,48 +0,0 @@ -# Tests for GNU GMP (or any compatible replacement). - -dnl Copyright (C) 2008-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. - -dnl Written by James Youngman. - -dnl Check for libgmp. We avoid use of AC_CHECK_LIBS because we don't want to -dnl add this to $LIBS for all targets. -AC_DEFUN([cu_GMP], -[ - LIB_GMP= - AC_SUBST([LIB_GMP]) - - AC_ARG_WITH([gmp], - AS_HELP_STRING([--without-gmp], - [do not use the GNU MP library for arbitrary precision - calculation (default: use it if available)]), - [cu_use_gmp=$withval], - [cu_use_gmp=auto]) - - if test $cu_use_gmp != no; then - dnl It was noticed on one MacOS X 10.5.8 system at least - dnl that the libs were available but the header wasn't - HAVE_GMP=0 - AC_CHECK_HEADERS_ONCE([gmp.h]) - if test $ac_cv_header_gmp_h = yes; then - cu_saved_libs=$LIBS - AC_SEARCH_LIBS([__gmpz_init], [gmp], - [test "$ac_cv_search___gmpz_init" = "none required" || - LIB_GMP=$ac_cv_search___gmpz_init - AC_DEFINE([HAVE_GMP], [1], - [Define if you have GNU libgmp (or replacement)]) - HAVE_GMP=1 - # This only available in GMP >= 5 - AC_CHECK_DECLS([mpz_inits], [], [], [[#include ]]) - ]) - LIBS=$cu_saved_libs - fi - if test $HAVE_GMP != 1; then - AC_MSG_WARN([libgmp development library was not found or not usable.]) - AC_MSG_WARN([AC_PACKAGE_NAME will be built without GMP support.]) - fi - fi -]) diff --git a/src/expr.c b/src/expr.c index e134872232..48d0890f83 100644 --- a/src/expr.c +++ b/src/expr.c @@ -33,6 +33,7 @@ #include #include "system.h" +#include #include #include "die.h" #include "error.h" @@ -45,105 +46,6 @@ int, the widest unsigned type that GMP supports. */ verify (SIZE_MAX <= ULONG_MAX); -#ifndef HAVE_GMP -# define HAVE_GMP 0 -#endif - -#if HAVE_GMP -# include -#else -static void integer_overflow (char) ATTRIBUTE_NORETURN; -/* Approximate gmp.h well enough for expr.c's purposes. */ -typedef intmax_t mpz_t[1]; -static void mpz_clear (mpz_t z) { (void) z; } -static void mpz_init_set_ui (mpz_t z, unsigned long int i) { z[0] = i; } -static int -mpz_init_set_str (mpz_t z, char *s, int base) -{ - return xstrtoimax (s, NULL, base, z, "") == LONGINT_OK ? 0 : -1; -} -static void -mpz_add (mpz_t r, mpz_t a0, mpz_t b0) -{ - intmax_t a = a0[0]; - intmax_t b = b0[0]; - intmax_t val = a + b; - if ((val < a) != (b < 0)) - integer_overflow ('+'); - r[0] = val; -} -static void -mpz_sub (mpz_t r, mpz_t a0, mpz_t b0) -{ - intmax_t a = a0[0]; - intmax_t b = b0[0]; - intmax_t val = a - b; - if ((a < val) != (b < 0)) - integer_overflow ('-'); - r[0] = val; -} -static void -mpz_mul (mpz_t r, mpz_t a0, mpz_t b0) -{ - intmax_t a = a0[0]; - intmax_t b = b0[0]; - intmax_t val = a * b; - if (! (a == 0 || b == 0 - || ((val < 0) == ((a < 0) ^ (b < 0)) && val / a == b))) - integer_overflow ('*'); - r[0] = val; -} -static void -mpz_tdiv_q (mpz_t r, mpz_t a0, mpz_t b0) -{ - intmax_t a = a0[0]; - intmax_t b = b0[0]; - - /* Some x86-style hosts raise an exception for INT_MIN / -1. */ - if (a < - INTMAX_MAX && b == -1) - integer_overflow ('/'); - r[0] = a / b; -} -static void -mpz_tdiv_r (mpz_t r, mpz_t a0, mpz_t b0) -{ - intmax_t a = a0[0]; - intmax_t b = b0[0]; - - /* Some x86-style hosts raise an exception for INT_MIN % -1. */ - r[0] = a < - INTMAX_MAX && b == -1 ? 0 : a % b; -} -static char * _GL_ATTRIBUTE_MALLOC -mpz_get_str (char const *str, int base, mpz_t z) -{ - (void) str; (void) base; - char buf[INT_BUFSIZE_BOUND (intmax_t)]; - return xstrdup (imaxtostr (z[0], buf)); -} -static int -mpz_sgn (mpz_t z) -{ - return z[0] < 0 ? -1 : 0 < z[0]; -} -static int -mpz_fits_ulong_p (mpz_t z) -{ - return 0 <= z[0] && z[0] <= ULONG_MAX; -} -static unsigned long int -mpz_get_ui (mpz_t z) -{ - return z[0]; -} -static int -mpz_out_str (FILE *stream, int base, mpz_t z) -{ - (void) base; - char buf[INT_BUFSIZE_BOUND (intmax_t)]; - return fputs (imaxtostr (z[0], buf), stream) != EOF; -} -#endif - /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "expr" @@ -414,15 +316,6 @@ or 0, 2 if EXPRESSION is syntactically invalid, and 3 if an error occurred.\n\ } -#if ! HAVE_GMP -/* Report an integer overflow for operation OP and exit. */ -static void -integer_overflow (char op) -{ - die (EXPR_FAILURE, ERANGE, "%c", op); -} -#endif - int main (int argc, char **argv) { @@ -603,7 +496,7 @@ toarith (VALUE *v) if (! looks_like_integer (s)) return false; - if (mpz_init_set_str (v->u.i, s, 10) != 0 && !HAVE_GMP) + if (mpz_init_set_str (v->u.i, s, 10) != 0) die (EXPR_FAILURE, ERANGE, "%s", (s)); free (s); v->type = integer; diff --git a/src/factor.c b/src/factor.c index 3eb1986a6d..dd87e6309d 100644 --- a/src/factor.c +++ b/src/factor.c @@ -35,12 +35,6 @@ The factoring code for two words will fall into the code for one word when progress allows that. - Using GMP is optional. Define HAVE_GMP to make this code include GMP - factoring code. The GMP factoring code is based on GMP's demos/factorize.c - (last synced 2012-09-07). The GMP-based factoring code will stay in GMP - factoring code even if numbers get small enough for using the two-word - code. - Algorithm: (1) Perform trial division using a small primes table, but without hardware @@ -104,13 +98,7 @@ #include #include #include -#if HAVE_GMP -# include -# if !HAVE_DECL_MPZ_INITS -# include -# endif -#endif - +#include #include #include "system.h" @@ -246,14 +234,12 @@ struct factors unsigned char nfactors; }; -#if HAVE_GMP struct mp_factors { mpz_t *p; unsigned long int *e; unsigned long int nfactors; }; -#endif static void factor (uintmax_t, uintmax_t, struct factors *); @@ -570,12 +556,12 @@ factor_insert_large (struct factors *factors, factor_insert (factors, p0); } -#if HAVE_GMP +#ifndef mpz_inits -# if !HAVE_DECL_MPZ_INITS +# include -# define mpz_inits(...) mpz_va_init (mpz_init, __VA_ARGS__) -# define mpz_clears(...) mpz_va_init (mpz_clear, __VA_ARGS__) +# define mpz_inits(...) mpz_va_init (mpz_init, __VA_ARGS__) +# define mpz_clears(...) mpz_va_init (mpz_clear, __VA_ARGS__) static void mpz_va_init (void (*mpz_single_init)(mpz_t), ...) @@ -590,7 +576,7 @@ mpz_va_init (void (*mpz_single_init)(mpz_t), ...) va_end (ap); } -# endif +#endif static void mp_factor (mpz_t, struct mp_factors *); @@ -660,7 +646,6 @@ mp_factor_insert_ui (struct mp_factors *factors, unsigned long int prime) mp_factor_insert (factors, pz); mpz_clear (pz); } -#endif /* HAVE_GMP */ /* Number of bits in an uintmax_t. */ @@ -835,7 +820,6 @@ factor_using_division (uintmax_t *t1p, uintmax_t t1, uintmax_t t0, return t0; } -#if HAVE_GMP static void mp_factor_using_division (mpz_t t, struct mp_factors *factors) { @@ -872,7 +856,6 @@ mp_factor_using_division (mpz_t t, struct mp_factors *factors) mpz_clear (q); } -#endif /* Entry i contains (2i+1)^(-1) mod 2^8. */ static const unsigned char binvert_table[128] = @@ -1171,7 +1154,6 @@ millerrabin2 (const uintmax_t *np, uintmax_t ni, const uintmax_t *bp, return false; } -#if HAVE_GMP static bool mp_millerrabin (mpz_srcptr n, mpz_srcptr nm1, mpz_ptr x, mpz_ptr y, mpz_srcptr q, unsigned long int k) @@ -1191,7 +1173,6 @@ mp_millerrabin (mpz_srcptr n, mpz_srcptr nm1, mpz_ptr x, mpz_ptr y, } return false; } -#endif /* Lucas' prime test. The number of iterations vary greatly, up to a few dozen have been observed. The average seem to be about 2. */ @@ -1377,7 +1358,6 @@ prime2_p (uintmax_t n1, uintmax_t n0) abort (); } -#if HAVE_GMP static bool mp_prime_p (mpz_t n) { @@ -1460,7 +1440,6 @@ mp_prime_p (mpz_t n) return is_prime; } -#endif static void factor_using_pollard_rho (uintmax_t n, unsigned long int a, @@ -1669,7 +1648,6 @@ factor_using_pollard_rho2 (uintmax_t n1, uintmax_t n0, unsigned long int a, } } -#if HAVE_GMP static void mp_factor_using_pollard_rho (mpz_t n, unsigned long int a, struct mp_factors *factors) @@ -1761,7 +1739,6 @@ mp_factor_using_pollard_rho (mpz_t n, unsigned long int a, mpz_clears (P, t2, t, z, x, y, NULL); } -#endif #if USE_SQUFOF /* FIXME: Maybe better to use an iteration converging to 1/sqrt(n)? If @@ -2251,7 +2228,6 @@ factor (uintmax_t t1, uintmax_t t0, struct factors *factors) } } -#if HAVE_GMP /* Use Pollard-rho to compute the prime factors of arbitrary-precision T, and put the results in FACTORS. */ static void @@ -2273,7 +2249,6 @@ mp_factor (mpz_t t, struct mp_factors *factors) } } } -#endif static strtol_error strto2uintmax (uintmax_t *hip, uintmax_t *lop, const char *s) @@ -2526,7 +2501,6 @@ print_factors (const char *input) return false; } -#if HAVE_GMP devmsg ("[using arbitrary-precision arithmetic] "); mpz_t t; struct mp_factors factors; @@ -2545,10 +2519,6 @@ print_factors (const char *input) putchar ('\n'); fflush (stdout); return true; -#else - error (0, 0, _("%s is too large"), quote (input)); - return false; -#endif } void