1 /* Test file for mpfr_version. 2 3 Copyright 2004-2020 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 * http://sourceforge.net/p/predef/wiki/Compilers/ 74 * 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(__GNUC__) || defined(__clang__)) && defined(__VERSION__) 89 # ifdef __clang__ 90 # define COMP2 COMP 91 # else 92 # define COMP2 COMP "GCC " 93 # endif 94 printf (COMP2 "%s\n", __VERSION__); 95 #endif 96 97 /************** More information about the C implementation **************/ 98 99 /* The following macros are currently used by src/mpfr-cvers.h and/or 100 src/mpfr-impl.h; they may have an influcence on how MPFR is compiled. */ 101 102 #if defined(__STDC__) || defined(__STDC_VERSION__) 103 (puts) ("[tversion] C standard: __STDC__ = " 104 #if defined(__STDC__) 105 MAKE_STR(__STDC__) 106 #else 107 "undef" 108 #endif 109 ", __STDC_VERSION__ = " 110 #if defined(__STDC_VERSION__) 111 MAKE_STR(__STDC_VERSION__) 112 #else 113 "undef" 114 #endif 115 ); 116 #endif 117 118 #if defined(__GNUC__) 119 (puts) ("[tversion] __GNUC__ = " MAKE_STR(__GNUC__) ", __GNUC_MINOR__ = " 120 #if defined(__GNUC_MINOR__) 121 MAKE_STR(__GNUC_MINOR__) 122 #else 123 "undef" 124 #endif 125 #if defined(__STRICT_ANSI__) 126 ", __STRICT_ANSI__" 127 #endif 128 ); 129 #endif 130 131 #if defined(__ICC) || defined(__INTEL_COMPILER) 132 (puts) ("[tversion] Intel compiler: __ICC = " 133 #if defined(__ICC) 134 MAKE_STR(__ICC) 135 #else 136 "undef" 137 #endif 138 ", __INTEL_COMPILER = " 139 #if defined(__INTEL_COMPILER) 140 MAKE_STR(__INTEL_COMPILER) 141 #else 142 "undef" 143 #endif 144 ); 145 #endif 146 147 #if defined(_WIN32) || defined(_MSC_VER) 148 (puts) ("[tversion] MS Windows: _WIN32 = " 149 #if defined(_WIN32) 150 MAKE_STR(_WIN32) 151 #else 152 "undef" 153 #endif 154 ", _MSC_VER = " 155 #if defined(_MSC_VER) 156 MAKE_STR(_MSC_VER) 157 #else 158 "undef" 159 #endif 160 ); 161 #endif 162 163 /* With MinGW64, both __MINGW32__ and __MINGW64__ seem to be defined, 164 but test both, just in case this will change in the future. Tested 165 with "x86_64-w64-mingw32-gcc -dM -E -xc /dev/null" under Debian. */ 166 #if defined(__MINGW32__) || defined(__MINGW64__) 167 (puts) ("[tversion] MinGW" 168 #if defined(__MINGW64__) 169 "64" 170 #else 171 "32" 172 #endif 173 ": __USE_MINGW_ANSI_STDIO = " 174 #if defined(__USE_MINGW_ANSI_STDIO) 175 MAKE_STR(__USE_MINGW_ANSI_STDIO) 176 #else 177 "undef" 178 #endif 179 ); 180 #endif 181 182 #if defined(__GLIBC__) 183 (puts) ("[tversion] __GLIBC__ = " MAKE_STR(__GLIBC__) ", __GLIBC_MINOR__ = " 184 #if defined(__GLIBC_MINOR__) 185 MAKE_STR(__GLIBC_MINOR__) 186 #else 187 "undef" 188 #endif 189 ); 190 #endif 191 192 /******************* GMP version and build information *******************/ 193 194 #ifdef __MPIR_VERSION 195 printf ("[tversion] MPIR: header %d.%d.%d, library %s\n", 196 __MPIR_VERSION, __MPIR_VERSION_MINOR, __MPIR_VERSION_PATCHLEVEL, 197 mpir_version); 198 #else 199 #ifdef MPFR_USE_MINI_GMP 200 printf ("[tversion] mini-gmp\n"); 201 #else 202 printf ("[tversion] GMP: header %d.%d.%d, library %s\n", 203 __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL, 204 gmp_version); 205 #endif 206 #endif 207 208 #ifdef __GMP_CC 209 printf ("[tversion] __GMP_CC = \"%s\"\n", __GMP_CC); 210 #endif 211 #ifdef __GMP_CFLAGS 212 printf ("[tversion] __GMP_CFLAGS = \"%s\"\n", __GMP_CFLAGS); 213 #endif 214 215 /* The following output is also useful under Unix, where one should get: 216 WinDLL: __GMP_LIBGMP_DLL = 0, MPFR_WIN_THREAD_SAFE_DLL = undef 217 If this is not the case, something is probably broken. We cannot test 218 automatically as some MS Windows implementations may declare some Unix 219 (POSIX) compatibility; for instance, Cygwin32 defines __unix__ (but 220 Cygwin64 does not, probably because providing both MS Windows API and 221 POSIX API is not possible with a 64-bit ABI, since MS Windows is LLP64 222 and Unix is LP64). 223 MPFR_WIN_THREAD_SAFE_DLL is directly set up from __GMP_LIBGMP_DLL; 224 that is why it is output here. */ 225 (puts) ("[tversion] WinDLL: __GMP_LIBGMP_DLL = " 226 #if defined(__GMP_LIBGMP_DLL) 227 MAKE_STR(__GMP_LIBGMP_DLL) 228 #else 229 "undef" 230 #endif 231 ", MPFR_WIN_THREAD_SAFE_DLL = " 232 #if defined(MPFR_WIN_THREAD_SAFE_DLL) 233 MAKE_STR(MPFR_WIN_THREAD_SAFE_DLL) 234 #else 235 "undef" 236 #endif 237 ); 238 239 /********************* MPFR configuration parameters *********************/ 240 241 /* The following code outputs configuration parameters, either set up 242 by the user or determined automatically (default values). */ 243 244 if ( 245 #ifdef MPFR_USE_THREAD_SAFE 246 ! 247 #endif 248 mpfr_buildopt_tls_p ()) 249 { 250 printf ("ERROR! mpfr_buildopt_tls_p() and macros" 251 " do not match!\n"); 252 err = 1; 253 } 254 255 if ( 256 #ifdef MPFR_WANT_FLOAT128 257 ! 258 #endif 259 mpfr_buildopt_float128_p ()) 260 { 261 printf ("ERROR! mpfr_buildopt_float128_p() and macros" 262 " do not match!\n"); 263 err = 1; 264 } 265 266 if ( 267 #ifdef MPFR_WANT_DECIMAL_FLOATS 268 ! 269 #endif 270 mpfr_buildopt_decimal_p ()) 271 { 272 printf ("ERROR! mpfr_buildopt_decimal_p() and macros" 273 " do not match!\n"); 274 err = 1; 275 } 276 277 if ( 278 #if defined(MPFR_HAVE_GMP_IMPL) || defined(WANT_GMP_INTERNALS) 279 ! 280 #endif 281 mpfr_buildopt_gmpinternals_p ()) 282 { 283 printf ("ERROR! mpfr_buildopt_gmpinternals_p() and macros" 284 " do not match!\n"); 285 err = 1; 286 } 287 288 #if defined(MPFR_HAVE_GMP_IMPL) 289 (puts) ("[tversion] MPFR built with the GMP build (--with-gmp-build)"); 290 #else 291 (printf) ("[tversion] MPFR_ALLOCA_MAX = %ld\n", (long) MPFR_ALLOCA_MAX); 292 #endif 293 294 if ( 295 #ifdef MPFR_WANT_SHARED_CACHE 296 ! 297 #endif 298 mpfr_buildopt_sharedcache_p ()) 299 { 300 printf ("ERROR! mpfr_buildopt_sharedcache_p() and macros" 301 " do not match!\n"); 302 err = 1; 303 } 304 305 (printf) ("[tversion] TLS = %s, float128 = %s, decimal = %s," 306 " GMP internals = %s\n", 307 mpfr_buildopt_tls_p () ? "yes" : "no", 308 mpfr_buildopt_float128_p () ? "yes" : "no", 309 mpfr_buildopt_decimal_p () ? "yes" 310 #if defined(DECIMAL_BID_FORMAT) 311 " (BID)" 312 #elif defined(DECIMAL_DPD_FORMAT) 313 " (DPD)" 314 #endif 315 : "no", 316 mpfr_buildopt_gmpinternals_p () ? "yes" : "no"); 317 318 #ifdef MPFR_THREAD_LOCK_METHOD 319 # define LOCK_METHOD " (lock method: " MPFR_THREAD_LOCK_METHOD ")" 320 #else 321 # define LOCK_METHOD "" 322 #endif 323 324 (printf) ("[tversion] Shared cache = %s\n", 325 mpfr_buildopt_sharedcache_p () ? "yes" LOCK_METHOD : "no"); 326 327 (puts) ("[tversion] intmax_t = " 328 #if defined(_MPFR_H_HAVE_INTMAX_T) 329 "yes" 330 #else 331 "no" 332 #endif 333 ", printf = " 334 #if defined(HAVE_STDARG) && !defined(MPFR_USE_MINI_GMP) 335 "yes" 336 #else 337 "no" 338 #endif 339 ", IEEE floats = " 340 #if _MPFR_IEEE_FLOATS 341 "yes" 342 #else 343 "no" 344 #endif 345 ); 346 347 (puts) ("[tversion] gmp_printf: hhd = " 348 #if defined(NPRINTF_HH) 349 "no" 350 #else 351 "yes" 352 #endif 353 ", lld = " 354 #if defined(NPRINTF_LL) 355 "no" 356 #else 357 "yes" 358 #endif 359 ", jd = " 360 #if defined(NPRINTF_J) 361 "no" 362 #else 363 "yes" 364 #endif 365 ", td = " 366 #if defined(NPRINTF_T) 367 "no" 368 #elif defined(PRINTF_T) 369 "yes" 370 #else 371 "?" 372 #endif 373 ", Ld = " 374 #if defined(NPRINTF_L) 375 "no" 376 #elif defined(PRINTF_L) 377 "yes" 378 #else 379 "?" 380 #endif 381 ); 382 383 (puts) ("[tversion] _mulx_u64 = " 384 #if defined(HAVE_MULX_U64) 385 "yes" 386 #else 387 "no" 388 #endif 389 ); 390 391 if (strcmp (mpfr_buildopt_tune_case (), MPFR_TUNE_CASE) != 0) 392 { 393 printf ("ERROR! mpfr_buildopt_tune_case() and MPFR_TUNE_CASE" 394 " do not match!\n %s\n %s\n", 395 mpfr_buildopt_tune_case (), MPFR_TUNE_CASE); 396 err = 1; 397 } 398 else 399 printf ("[tversion] MPFR tuning parameters from %s\n", MPFR_TUNE_CASE); 400 401 /**************************** ABI information ****************************/ 402 403 (printf) ("[tversion] sizeof(long) = %ld, sizeof(mpfr_intmax_t) = %ld" 404 #if defined(_MPFR_H_HAVE_INTMAX_T) 405 ", sizeof(intmax_t) = %ld" 406 #endif 407 "\n", (long) sizeof(long), (long) sizeof(mpfr_intmax_t) 408 #if defined(_MPFR_H_HAVE_INTMAX_T) 409 , (long) sizeof(intmax_t) 410 #endif 411 ); 412 413 if (mp_bits_per_limb != GMP_NUMB_BITS) 414 { 415 printf ("ERROR! mp_bits_per_limb != GMP_NUMB_BITS (%ld vs %ld)\n", 416 (long) mp_bits_per_limb, (long) GMP_NUMB_BITS); 417 err = 1; 418 } 419 420 printf ("[tversion] GMP_NUMB_BITS = %ld, sizeof(mp_limb_t) = %ld\n", 421 (long) GMP_NUMB_BITS, (long) sizeof(mp_limb_t)); 422 423 /* Concerning the MPFR_LONG_WITHIN_LIMB and MPFR_INTMAX_WITHIN_LIMB macros, 424 if defined, code may be optimized to take these properties into account. 425 If not defined, MPFR should select portable code. So one should ideally 426 get either "y/y" or "n/n"; "n/y" is allowed, but "y/n" is forbidden. 427 Note: MPFR_LONG_WITHIN_LIMB should be defined by the configure script, 428 but may also be defined by the src/mpfr-impl.h header file. */ 429 #define WITHIN_LIMB(T) \ 430 (MPFR_LIMB_MAX >= (T) -1 ? \ 431 ((WM) ? "y/y" : "n/y") : \ 432 ((WM) ? (err = 1, "y/n (WRONG!)") : "n/n")) 433 434 (printf) ("[tversion] Within limb: long = %s" 435 #if defined(_MPFR_H_HAVE_INTMAX_T) 436 ", intmax_t = %s" 437 #endif 438 "\n" 439 #undef WM 440 #if defined(MPFR_LONG_WITHIN_LIMB) 441 # define WM 1 442 #else 443 # define WM 0 444 #endif 445 , WITHIN_LIMB (unsigned long) 446 #if defined(_MPFR_H_HAVE_INTMAX_T) 447 #undef WM 448 #if defined(MPFR_INTMAX_WITHIN_LIMB) 449 # define WM 1 450 #else 451 # define WM 0 452 #endif 453 , WITHIN_LIMB (uintmax_t) 454 #endif 455 ); 456 457 printf ("[tversion] _MPFR_PREC_FORMAT = %ld, sizeof(mpfr_prec_t) = %ld\n", 458 (long) _MPFR_PREC_FORMAT, (long) sizeof(mpfr_prec_t)); 459 460 printf ("[tversion] _MPFR_EXP_FORMAT = %ld, sizeof(mpfr_exp_t) = %ld\n", 461 (long) _MPFR_EXP_FORMAT, (long) sizeof(mpfr_exp_t)); 462 463 printf ("[tversion] sizeof(mpfr_t) = %ld, sizeof(mpfr_ptr) = %ld\n", 464 (long) sizeof(mpfr_t), (long) sizeof(mpfr_ptr)); 465 466 #define RANGE " range: [%" MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d]\n" 467 468 printf ("[tversion] Precision" RANGE, 469 (mpfr_eexp_t) MPFR_PREC_MIN, (mpfr_eexp_t) MPFR_PREC_MAX); 470 471 e = mpfr_get_emin_min (); 472 if (e != MPFR_EMIN_MIN) 473 { 474 printf ("ERROR! mpfr_get_emin_min != MPFR_EMIN_MIN (%ld vs %ld)\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 (%ld vs %ld)\n", 483 (mpfr_eexp_t) e, (mpfr_eexp_t) MPFR_EMAX_MAX); 484 err = 1; 485 } 486 487 printf ("[tversion] Max exponent" RANGE, 488 (mpfr_eexp_t) MPFR_EMIN_MIN, (mpfr_eexp_t) MPFR_EMAX_MAX); 489 490 (puts) ("[tversion] Generic ABI code: " 491 #if defined(MPFR_GENERIC_ABI) 492 "yes" 493 #else 494 "no" 495 #endif 496 ); 497 498 (puts) ("[tversion] Enable formally proven code: " 499 #if defined(MPFR_WANT_PROVEN_CODE) 500 "yes" 501 #else 502 "no" 503 #endif 504 ); 505 506 /************************* Run-time information **************************/ 507 508 if (locale != NULL) 509 printf ("[tversion] Locale: %s\n", locale); 510 /* The memory limit should not be changed for "make check". 511 The warning below signals a possible user mistake. 512 Do not use "%zu" because it is not available in C90; 513 the type mpfr_ueexp_t should be sufficiently large. */ 514 if (tests_memory_limit != DEFAULT_MEMORY_LIMIT) 515 printf ("[tversion] Warning! Memory limit changed to %" MPFR_EXP_FSPEC 516 "u\n", (mpfr_ueexp_t) tests_memory_limit); 517 518 /*************************************************************************/ 519 520 if (errno != 0) 521 { 522 perror ("tversion"); 523 err = 1; 524 } 525 526 tests_end_mpfr (); 527 528 return err; 529 } 530