(root)/
mpfr-4.2.1/
tests/
tversion.c
       1  /* Test file for mpfr_version.
       2  
       3  Copyright 2004-2023 Free Software Foundation, Inc.
       4  Contributed by the AriC and Caramba projects, INRIA.
       5  
       6  This file is part of the GNU MPFR Library.
       7  
       8  The GNU MPFR Library is free software; you can redistribute it and/or modify
       9  it under the terms of the GNU Lesser General Public License as published by
      10  the Free Software Foundation; either version 3 of the License, or (at your
      11  option) any later version.
      12  
      13  The GNU MPFR Library is distributed in the hope that it will be useful, but
      14  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      15  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
      16  License for more details.
      17  
      18  You should have received a copy of the GNU Lesser General Public License
      19  along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
      20  https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
      21  51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
      22  
      23  #include <errno.h>
      24  
      25  #define MPFR_NEED_INTMAX_H
      26  #include "mpfr-test.h"
      27  
      28  /* Warning about the usage of printf/puts below:
      29   *
      30   *   - If a macro expansion is used, it must not appear in the first
      31   *     argument of printf (format string), as we do not know whether
      32   *     the expanded string contains a '%' character.
      33   *
      34   *   - If a #if preprocessor directive is used in an argument, parentheses
      35   *     must be put around the function name, in case this function is also
      36   *     implemented as a macro (#if does not work in macro arguments).
      37   */
      38  
      39  int
      40  main (void)
      41  {
      42    mpfr_exp_t e;
      43    int err = 0;
      44  
      45    /* Test the GMP and MPFR versions. */
      46    if (test_version ())
      47      exit (1);
      48  
      49    tests_start_mpfr ();
      50  
      51    errno = 0;
      52  
      53    /*********************** MPFR version and patches ************************/
      54  
      55    /* The printf failure test was added because of an output issue under Wine,
      56     * eventually not related to this output; this test is kept just in case...
      57     * Details:
      58     *   https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=914822
      59     *   https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=914949
      60     */
      61    if (printf ("[tversion] MPFR %s\n", MPFR_VERSION_STRING) < 0)
      62      {
      63        perror ("tversion (first printf)");
      64        err = 1;
      65      }
      66  
      67    if (strcmp (mpfr_get_patches (), "") != 0)
      68      printf ("[tversion] MPFR patches: %s\n", mpfr_get_patches ());
      69  
      70    /************************* Compiler information **************************/
      71  
      72    /* TODO: We may want to output info for non-GNUC-compat compilers too. See:
      73     * https://sourceforge.net/p/predef/wiki/Compilers/
      74     * https://web.archive.org/web/20191011050717/http://nadeausoftware.com/articles/2012/10/c_c_tip_how_detect_compiler_name_and_version_using_compiler_predefined_macros
      75     *
      76     * For ICC, do not check the __ICC macro as it is obsolete and not always
      77     * defined (in particular, on MS Windows).
      78     */
      79  #define COMP "[tversion] Compiler: "
      80  #ifdef __INTEL_COMPILER
      81  # ifdef __VERSION__
      82  #  define ICCV " [" __VERSION__ "]"
      83  # else
      84  #  define ICCV ""
      85  # endif
      86    printf (COMP "ICC %d.%d.%d" ICCV "\n", __INTEL_COMPILER / 100,
      87            __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE);
      88  #elif defined(__TINYC__)
      89    /* The format of __TINYC__ is not described, but libtcc.c defines it with
      90     *   sprintf(buffer, "%d", a*10000 + b*100 + c);
      91     *   tcc_define_symbol(s, "__TINYC__", buffer);
      92     */
      93    printf (COMP "TCC %d.%d.%d\n", (int) (__TINYC__ / 10000),
      94            (int) ((__TINYC__ / 100) % 100), (int) (__TINYC__ % 100));
      95  #elif (defined(__GNUC__) || defined(__clang__)) && defined(__VERSION__)
      96  # ifdef __clang__
      97  #  define COMP2 COMP
      98  # else
      99  #  define COMP2 COMP "GCC "
     100  # endif
     101    printf (COMP2 "%s\n", __VERSION__);
     102  #endif
     103  
     104    /************** More information about the C implementation **************/
     105  
     106    /* The following macros are currently used by src/mpfr-cvers.h and/or
     107       src/mpfr-impl.h; they may have an influcence on how MPFR is compiled. */
     108  
     109  #if defined(__STDC__) || defined(__STDC_VERSION__)
     110    (puts) ("[tversion] C standard: __STDC__ = "
     111  #if defined(__STDC__)
     112            MAKE_STR(__STDC__)
     113  #else
     114            "undef"
     115  #endif
     116            ", __STDC_VERSION__ = "
     117  #if defined(__STDC_VERSION__)
     118            MAKE_STR(__STDC_VERSION__)
     119  #else
     120            "undef"
     121  #endif
     122            );
     123  #endif
     124  
     125  #if defined(__GNUC__)
     126    (puts) ("[tversion] __GNUC__ = " MAKE_STR(__GNUC__) ", __GNUC_MINOR__ = "
     127  #if defined(__GNUC_MINOR__)
     128            MAKE_STR(__GNUC_MINOR__)
     129  #else
     130            "undef"
     131  #endif
     132  #if defined(__STRICT_ANSI__)
     133            ", __STRICT_ANSI__"
     134  #endif
     135            );
     136  #endif
     137  
     138  #if defined(__ICC) || defined(__INTEL_COMPILER)
     139    (puts) ("[tversion] Intel compiler: __ICC = "
     140  #if defined(__ICC)
     141            MAKE_STR(__ICC)
     142  #else
     143            "undef"
     144  #endif
     145            ", __INTEL_COMPILER = "
     146  #if defined(__INTEL_COMPILER)
     147            MAKE_STR(__INTEL_COMPILER)
     148  #else
     149            "undef"
     150  #endif
     151            );
     152  #endif
     153  
     154  #if defined(_WIN32) || defined(_MSC_VER)
     155    (puts) ("[tversion] MS Windows: _WIN32 = "
     156  #if defined(_WIN32)
     157            MAKE_STR(_WIN32)
     158  #else
     159            "undef"
     160  #endif
     161            ", _MSC_VER = "
     162  #if defined(_MSC_VER)
     163            MAKE_STR(_MSC_VER)
     164  #else
     165            "undef"
     166  #endif
     167            );
     168  #endif
     169  
     170    /* With MinGW64, both __MINGW32__ and __MINGW64__ seem to be defined,
     171       but test both, just in case this will change in the future. Tested
     172       with "x86_64-w64-mingw32-gcc -dM -E -xc /dev/null" under Debian. */
     173  #if defined(__MINGW32__) || defined(__MINGW64__)
     174    (puts) ("[tversion] MinGW"
     175  #if defined(__MINGW64__)
     176            "64"
     177  #else
     178            "32"
     179  #endif
     180            ": __USE_MINGW_ANSI_STDIO = "
     181  #if defined(__USE_MINGW_ANSI_STDIO)
     182            MAKE_STR(__USE_MINGW_ANSI_STDIO)
     183  #else
     184            "undef"
     185  #endif
     186            );
     187  #endif
     188  
     189  #if defined(__GLIBC__)
     190    (puts) ("[tversion] __GLIBC__ = " MAKE_STR(__GLIBC__) ", __GLIBC_MINOR__ = "
     191  #if defined(__GLIBC_MINOR__)
     192            MAKE_STR(__GLIBC_MINOR__)
     193  #else
     194            "undef"
     195  #endif
     196            );
     197  #endif
     198  
     199    /******************* GMP version and build information *******************/
     200  
     201  #ifdef __MPIR_VERSION
     202    printf ("[tversion] MPIR: header %d.%d.%d, library %s\n",
     203            __MPIR_VERSION, __MPIR_VERSION_MINOR, __MPIR_VERSION_PATCHLEVEL,
     204            mpir_version);
     205  #else
     206  #ifdef MPFR_USE_MINI_GMP
     207    printf ("[tversion] mini-gmp\n");
     208  #else
     209    printf ("[tversion] GMP: header %d.%d.%d, library %s\n",
     210            __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL,
     211            gmp_version);
     212  #endif
     213  #endif
     214  
     215  #ifdef __GMP_CC
     216    printf ("[tversion] __GMP_CC = \"%s\"\n", __GMP_CC);
     217  #endif
     218  #ifdef __GMP_CFLAGS
     219    printf ("[tversion] __GMP_CFLAGS = \"%s\"\n", __GMP_CFLAGS);
     220  #endif
     221  
     222    /* The following output is also useful under Unix, where one should get:
     223       WinDLL: __GMP_LIBGMP_DLL = 0, MPFR_WIN_THREAD_SAFE_DLL = undef
     224       If this is not the case, something is probably broken. We cannot test
     225       automatically as some MS Windows implementations may declare some Unix
     226       (POSIX) compatibility; for instance, Cygwin32 defines __unix__ (but
     227       Cygwin64 does not, probably because providing both MS Windows API and
     228       POSIX API is not possible with a 64-bit ABI, since MS Windows is LLP64
     229       and Unix is LP64).
     230       MPFR_WIN_THREAD_SAFE_DLL is directly set up from __GMP_LIBGMP_DLL;
     231       that is why it is output here. */
     232    (puts) ("[tversion] WinDLL: __GMP_LIBGMP_DLL = "
     233  #if defined(__GMP_LIBGMP_DLL)
     234            MAKE_STR(__GMP_LIBGMP_DLL)
     235  #else
     236            "undef"
     237  #endif
     238            ", MPFR_WIN_THREAD_SAFE_DLL = "
     239  #if defined(MPFR_WIN_THREAD_SAFE_DLL)
     240            MAKE_STR(MPFR_WIN_THREAD_SAFE_DLL)
     241  #else
     242            "undef"
     243  #endif
     244            );
     245  
     246    /********************* MPFR configuration parameters *********************/
     247  
     248    /* The following code outputs configuration parameters, either set up
     249       by the user or determined automatically (default values). */
     250  
     251    if (
     252  #ifdef MPFR_USE_THREAD_SAFE
     253        !
     254  #endif
     255        mpfr_buildopt_tls_p ())
     256      {
     257        printf ("ERROR! mpfr_buildopt_tls_p() and macros"
     258                " do not match!\n");
     259        err = 1;
     260      }
     261  
     262    if (
     263  #ifdef MPFR_WANT_FLOAT128
     264        !
     265  #endif
     266        mpfr_buildopt_float128_p ())
     267      {
     268        printf ("ERROR! mpfr_buildopt_float128_p() and macros"
     269                " do not match!\n");
     270        err = 1;
     271      }
     272  
     273    if (
     274  #ifdef MPFR_WANT_DECIMAL_FLOATS
     275        !
     276  #endif
     277        mpfr_buildopt_decimal_p ())
     278      {
     279        printf ("ERROR! mpfr_buildopt_decimal_p() and macros"
     280                " do not match!\n");
     281        err = 1;
     282      }
     283  
     284    if (
     285  #if defined(MPFR_HAVE_GMP_IMPL) || defined(WANT_GMP_INTERNALS)
     286        !
     287  #endif
     288        mpfr_buildopt_gmpinternals_p ())
     289      {
     290        printf ("ERROR! mpfr_buildopt_gmpinternals_p() and macros"
     291                " do not match!\n");
     292        err = 1;
     293      }
     294  
     295  #if defined(MPFR_HAVE_GMP_IMPL)
     296    (puts) ("[tversion] MPFR built with the GMP build (--with-gmp-build)");
     297  #else
     298    (printf) ("[tversion] MPFR_ALLOCA_MAX = %ld\n", (long) MPFR_ALLOCA_MAX);
     299  #endif
     300  
     301    if (
     302  #ifdef MPFR_WANT_SHARED_CACHE
     303        !
     304  #endif
     305        mpfr_buildopt_sharedcache_p ())
     306      {
     307        printf ("ERROR! mpfr_buildopt_sharedcache_p() and macros"
     308                " do not match!\n");
     309        err = 1;
     310      }
     311  
     312    (printf) ("[tversion] TLS = %s, float128 = %s, decimal = %s,"
     313              " GMP internals = %s\n",
     314              mpfr_buildopt_tls_p () ? "yes" : "no",
     315              mpfr_buildopt_float128_p () ? "yes" : "no",
     316              mpfr_buildopt_decimal_p () ? "yes"
     317  #if defined(DECIMAL_BID_FORMAT)
     318              " (BID)"
     319  #elif defined(DECIMAL_DPD_FORMAT)
     320              " (DPD)"
     321  #endif
     322              : "no",
     323              mpfr_buildopt_gmpinternals_p () ? "yes" : "no");
     324  
     325  #ifdef MPFR_THREAD_LOCK_METHOD
     326  # define LOCK_METHOD " (lock method: " MPFR_THREAD_LOCK_METHOD ")"
     327  #else
     328  # define LOCK_METHOD ""
     329  #endif
     330  
     331    (printf) ("[tversion] Shared cache = %s\n",
     332              mpfr_buildopt_sharedcache_p () ? "yes" LOCK_METHOD : "no");
     333  
     334    (puts) ("[tversion] intmax_t = "
     335  #if defined(_MPFR_H_HAVE_INTMAX_T)
     336            "yes"
     337  #else
     338            "no"
     339  #endif
     340            ", printf = "
     341  #if defined(HAVE_STDARG) && !defined(MPFR_USE_MINI_GMP)
     342            "yes"
     343  #else
     344            "no"
     345  #endif
     346            ", IEEE floats = "
     347  #if _MPFR_IEEE_FLOATS
     348            "yes"
     349  #else
     350            "no"
     351  #endif
     352            );
     353  
     354    (puts) ("[tversion] gmp_printf: hhd = "
     355  #if defined(NPRINTF_HH)
     356            "no"
     357  #else
     358            "yes"
     359  #endif
     360            ", lld = "
     361  #if defined(NPRINTF_LL)
     362            "no"
     363  #else
     364            "yes"
     365  #endif
     366            ", jd = "
     367  #if defined(NPRINTF_J)
     368            "no"
     369  #else
     370            "yes"
     371  #endif
     372            ", td = "
     373  #if defined(NPRINTF_T)
     374            "no"
     375  #elif defined(PRINTF_T)
     376            "yes"
     377  #else
     378            "?"
     379  #endif
     380            ", Ld = "
     381  #if defined(NPRINTF_L)
     382            "no"
     383  #elif defined(PRINTF_L)
     384            "yes"
     385  #else
     386            "?"
     387  #endif
     388            );
     389  
     390    if (strcmp (mpfr_buildopt_tune_case (), MPFR_TUNE_CASE) != 0)
     391      {
     392        printf ("ERROR! mpfr_buildopt_tune_case() and MPFR_TUNE_CASE"
     393                " do not match!\n  %s\n  %s\n",
     394                mpfr_buildopt_tune_case (), MPFR_TUNE_CASE);
     395        err = 1;
     396      }
     397    else
     398      printf ("[tversion] MPFR tuning parameters from %s\n", MPFR_TUNE_CASE);
     399  
     400    /**************************** ABI information ****************************/
     401  
     402    (printf) ("[tversion] sizeof(long) = %ld, sizeof(mpfr_intmax_t) = %ld"
     403  #if defined(_MPFR_H_HAVE_INTMAX_T)
     404              ", sizeof(intmax_t) = %ld"
     405  #endif
     406              "\n", (long) sizeof(long), (long) sizeof(mpfr_intmax_t)
     407  #if defined(_MPFR_H_HAVE_INTMAX_T)
     408              , (long) sizeof(intmax_t)
     409  #endif
     410              );
     411  
     412    if (mp_bits_per_limb != GMP_NUMB_BITS)
     413      {
     414        printf ("ERROR! mp_bits_per_limb != GMP_NUMB_BITS (%ld vs %ld)\n",
     415                (long) mp_bits_per_limb, (long) GMP_NUMB_BITS);
     416        err = 1;
     417      }
     418  
     419    printf ("[tversion] GMP_NUMB_BITS = %ld, sizeof(mp_limb_t) = %ld\n",
     420            (long) GMP_NUMB_BITS, (long) sizeof(mp_limb_t));
     421  
     422    /* Concerning the MPFR_LONG_WITHIN_LIMB and MPFR_INTMAX_WITHIN_LIMB macros,
     423       if defined, code may be optimized to take these properties into account.
     424       If not defined, MPFR should select portable code. So one should ideally
     425       get either "y/y" or "n/n"; "n/y" is allowed, but "y/n" is forbidden.
     426       Note: MPFR_LONG_WITHIN_LIMB should be defined by the configure script,
     427       but may also be defined by the src/mpfr-impl.h header file. */
     428  #define WITHIN_LIMB(T)                         \
     429    (MPFR_LIMB_MAX >= (T) -1 ?                   \
     430     ((WM) ? "y/y" : "n/y") :                    \
     431     ((WM) ? (err = 1, "y/n (WRONG!)") : "n/n"))
     432  
     433    (printf) ("[tversion] Within limb: long = %s"
     434  #if defined(_MPFR_H_HAVE_INTMAX_T)
     435              ", intmax_t = %s"
     436  #endif
     437              "\n"
     438  #undef WM
     439  #if defined(MPFR_LONG_WITHIN_LIMB)
     440  # define WM 1
     441  #else
     442  # define WM 0
     443  #endif
     444              , WITHIN_LIMB (unsigned long)
     445  #if defined(_MPFR_H_HAVE_INTMAX_T)
     446  #undef WM
     447  #if defined(MPFR_INTMAX_WITHIN_LIMB)
     448  # define WM 1
     449  #else
     450  # define WM 0
     451  #endif
     452              , WITHIN_LIMB (uintmax_t)
     453  #endif
     454              );
     455  
     456    printf ("[tversion] _MPFR_PREC_FORMAT = %ld, sizeof(mpfr_prec_t) = %ld\n",
     457            (long) _MPFR_PREC_FORMAT, (long) sizeof(mpfr_prec_t));
     458  
     459    printf ("[tversion] _MPFR_EXP_FORMAT = %ld, sizeof(mpfr_exp_t) = %ld\n",
     460            (long) _MPFR_EXP_FORMAT, (long) sizeof(mpfr_exp_t));
     461  
     462    printf ("[tversion] sizeof(mpfr_t) = %ld, sizeof(mpfr_ptr) = %ld\n",
     463            (long) sizeof(mpfr_t), (long) sizeof(mpfr_ptr));
     464  
     465  #define RANGE " range: [%" MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d]\n"
     466  
     467    printf ("[tversion] Precision" RANGE,
     468            (mpfr_eexp_t) MPFR_PREC_MIN, (mpfr_eexp_t) MPFR_PREC_MAX);
     469  
     470    e = mpfr_get_emin_min ();
     471    if (e != MPFR_EMIN_MIN)
     472      {
     473        printf ("ERROR! mpfr_get_emin_min != MPFR_EMIN_MIN (%"
     474                MPFR_EXP_FSPEC "d vs %" MPFR_EXP_FSPEC "d)\n",
     475                (mpfr_eexp_t) e, (mpfr_eexp_t) MPFR_EMIN_MIN);
     476        err = 1;
     477      }
     478  
     479    e = mpfr_get_emax_max ();
     480    if (e != MPFR_EMAX_MAX)
     481      {
     482        printf ("ERROR! mpfr_get_emax_max != MPFR_EMAX_MAX (%"
     483                MPFR_EXP_FSPEC "d vs %" MPFR_EXP_FSPEC "d)\n",
     484                (mpfr_eexp_t) e, (mpfr_eexp_t) MPFR_EMAX_MAX);
     485        err = 1;
     486      }
     487  
     488    printf ("[tversion] Max exponent" RANGE,
     489            (mpfr_eexp_t) MPFR_EMIN_MIN, (mpfr_eexp_t) MPFR_EMAX_MAX);
     490  
     491    (puts) ("[tversion] Generic ABI code: "
     492  #if defined(MPFR_GENERIC_ABI)
     493            "yes"
     494  #else
     495            "no"
     496  #endif
     497            );
     498  
     499    (puts) ("[tversion] Enable formally proven code: "
     500  #if defined(MPFR_WANT_PROVEN_CODE)
     501            "yes"
     502  #else
     503            "no"
     504  #endif
     505            );
     506  
     507    /************************* Run-time information **************************/
     508  
     509    if (locale != NULL)
     510      printf ("[tversion] Locale: %s\n", locale);
     511    /* The memory limit should not be changed for "make check".
     512       The warning below signals a possible user mistake.
     513       Do not use "%zu" because it is not available in C90;
     514       the type mpfr_ueexp_t should be sufficiently large. */
     515    if (tests_memory_limit != DEFAULT_MEMORY_LIMIT)
     516      printf ("[tversion] Warning! Memory limit changed to %" MPFR_EXP_FSPEC
     517              "u\n", (mpfr_ueexp_t) tests_memory_limit);
     518  
     519    /*************************************************************************/
     520  
     521    if (errno != 0)
     522      {
     523        perror ("tversion");
     524        err = 1;
     525      }
     526  
     527    tests_end_mpfr ();
     528  
     529    return err;
     530  }