#define _GNU_SOURCE 1 #include #include #include #include #include #include #include #include #include #include #include #include #include #define obstack_chunk_alloc malloc #define obstack_chunk_free free #ifdef __NO_LONG_DOUBLE_MATH /* Provide prototypes ourselves. */ extern long double acoshl (long double); extern long double acosl (long double); extern long double asinhl (long double); extern long double asinl (long double); extern long double atan2l (long double, long double); extern long double atanhl (long double); extern long double atanl (long double); extern long double cbrtl (long double); extern long double ceill (long double); extern long double copysignl (long double, long double); extern long double coshl (long double); extern long double cosl (long double); extern long double dreml (long double, long double); extern long double erfcl (long double); extern long double erfl (long double); extern long double exp10l (long double); extern long double exp2l (long double); extern long double expl (long double); extern long double expm1l (long double); extern long double fabsl (long double); extern long double fdiml (long double, long double); extern long double floorl (long double); extern long double fmal (long double, long double, long double); extern long double fmaxl (long double, long double); extern long double fminl (long double, long double); extern long double fmodl (long double, long double); extern long double gammal (long double); extern long double hypotl (long double, long double); extern int ilogbl (long double); extern long double j0l (long double); extern long double j1l (long double); extern long double jnl (int, long double); extern long double ldexpl (long double, int); #endif long double l1, l2; double d1, d2; int failures; #define CHECK(x) \ do { \ if (!(x)) \ { \ fprintf (stderr, "failure on line %d\n", __LINE__); \ ++failures; \ } \ } while (0) #define CHECK2(x, y) \ do { \ l1 = x; \ /* Avoid using fabsl here, we want to test it too. */ \ CHECK ((l1 > y && (l1 - y) < 0.01L) \ || (l1 <= y && (y - l1) < 0.01L)); \ } while (0) #define CHECK3(fn, x, y) \ CHECK2 (fn##l (x##L), y##L); \ CHECK2 (fn (x), y) #define CHECK4(fn, x, y, z) \ CHECK2 (fn##l (x##L, y##L), z##L); \ CHECK2 (fn (x, y), z) #define CHECK5(fn, x, y, z, w) \ CHECK2 (fn##l (x##L, y##L, z##L), w##L); \ CHECK2 (fn (x, y, z), w) void test (va_list *ap, va_list *pap) { int i; if (freopen ("/proc/self/fd/1", "w", stderr) == NULL) CHECK (0); CHECK (setlocale (LC_ALL, "en_US.ISO-8859-1") != NULL); locale_t loc = newlocale (LC_ALL_MASK, "en_US.ISO-8859-1", NULL); CHECK (loc != NULL); locale_t loc2 = newlocale (LC_ALL_MASK, "cs_CZ.UTF-8", NULL); CHECK (loc2 != NULL); char tmpp2[] = "/tmp/tst-ldbl-dbl-XXXXXX"; int fd = mkstemp (tmpp2); if (fd < 0) CHECK (0); char tmpp[sizeof ("/proc/self/fd/%d") + 3 * sizeof (int)]; snprintf (tmpp, sizeof (tmpp), "/proc/self/fd/%d", fd); unlink (tmpp2); if (freopen (tmpp, "w", stdout) == NULL) CHECK (0); /* asprintf, dprintf, fprintf, fwprintf, obstack_printf, obstack_vprintf, printf, printf_size, snprintf, sprintf, swprintf, vasprintf, vdprintf, vfprintf, vfwprintf, vprintf, vsnprintf, vsprintf, vswprintf, vwprintf, wprintf */ /* _IO_fprintf, _IO_printf, _IO_sprintf, _IO_vfprintf, _IO_vsprintf, __asprintf, __vsnprintf, __fprintf_chk, __fwprintf_chk, __printf_chk, __snprintf_chk, __sprintf_chk, __swprintf_chk, __vfprintf_chk, __vfwprintf_chk, __vprintf_chk, __vsnprintf_chk, __vsprintf_chk, __vswprintf_chk, __vwprintf_chk, __wprintf_chk, __printf_fp */ char *p; p = NULL; asprintf (&p, "%Lg %5.9Lf %g %5.9f\n", 3.25L, 7834.5L, 3.75, 7835.5); CHECK (strcmp (p, "3.25 7834.500000000 3.75 7835.500000000\n") == 0); free (p); p = NULL; vasprintf (&p, "%Lg %5.9Lf %g %5.9f\n", *ap++); CHECK (strcmp (p, "3.25 7834.500000000 3.75 7835.500000000\n") == 0); free (p); fflush (stdout); dprintf (1, "%Lg %5.9Lf %g %5.9f\n", 3.25L, 7834.5L, 3.75, 7835.5); vdprintf (1, "%Lg %5.9Lf %g %5.9f\n", *ap++); fflush (stdout); fprintf (stdout, "%Lg %5.9Lf %g %5.9f\n", 3.25L, 7834.5L, 3.75, 7835.5); vfprintf (stdout, "%Lg %5.9Lf %g %5.9f\n", *ap++); printf ("%Lg %5.9Lf %g %5.9f\n", 3.25L, 7834.5L, 3.75, 7835.5); vprintf ("%Lg %5.9Lf %g %5.9f\n", *ap++); struct obstack o; obstack_init (&o); obstack_printf (&o, "%Lg %5.9Lf %g %5.9f\n", 3.25L, 7834.5L, 3.75, 7835.5); obstack_1grow (&o, 0); p = obstack_finish (&o); CHECK (strcmp (p, "3.25 7834.500000000 3.75 7835.500000000\n") == 0); obstack_1grow (&o, 'z'); obstack_finish (&o); obstack_vprintf (&o, "%Lg %5.9Lf %g %5.9f\n", *ap++); obstack_1grow (&o, 0); p = obstack_finish (&o); CHECK (strcmp (p, "3.25 7834.500000000 3.75 7835.500000000\n") == 0); obstack_free (&o, NULL); char buf[80]; memset (buf, 0, sizeof (buf)); sprintf (buf, "%Lg %5.9Lf %g %5.9f\n", 3.25L, 7834.5L, 3.75, 7835.5); CHECK (strcmp (buf, "3.25 7834.500000000 3.75 7835.500000000\n") == 0); memset (buf, 0, sizeof (buf)); vsprintf (buf, "%Lg %5.9Lf %g %5.9f\n", *ap++); CHECK (strcmp (buf, "3.25 7834.500000000 3.75 7835.500000000\n") == 0); memset (buf, 0, sizeof (buf)); snprintf (buf, 80, "%Lg %5.9Lf %g %5.9f\n", 3.25L, 7834.5L, 3.75, 7835.5); CHECK (strcmp (buf, "3.25 7834.500000000 3.75 7835.500000000\n") == 0); memset (buf, 0, sizeof (buf)); vsnprintf (buf, 80, "%Lg %5.9Lf %g %5.9f\n", *ap++); CHECK (strcmp (buf, "3.25 7834.500000000 3.75 7835.500000000\n") == 0); fflush (stdout); if (freopen (tmpp, "r", stdin) == NULL) CHECK (0); for (i = 0; i < 6; i++) { memset (buf, 0, sizeof (buf)); CHECK (fgets (buf, sizeof (buf), stdin) == buf); CHECK (strcmp (buf, "3.25 7834.500000000 3.75 7835.500000000\n") == 0); } if (freopen (tmpp, "w", stdout) == NULL) CHECK (0); fwprintf (stdout, L"%Lg %5.9Lf %g %5.9f\n", 3.25L, 7834.5L, 3.75, 7835.5); vfwprintf (stdout, L"%Lg %5.9Lf %g %5.9f\n", *ap++); wprintf (L"%Lg %5.9Lf %g %5.9f\n", 3.25L, 7834.5L, 3.75, 7835.5); vwprintf (L"%Lg %5.9Lf %g %5.9f\n", *ap++); fflush (stdout); if (freopen (tmpp, "r", stdin) == NULL) CHECK (0); for (i = 0; i < 4; i++) { memset (buf, 0, sizeof (buf)); CHECK (fgets (buf, sizeof (buf), stdin) == buf); CHECK (strcmp (buf, "3.25 7834.500000000 3.75 7835.500000000\n") == 0); } if (freopen (tmpp, "w", stdout) == NULL) CHECK (0); wchar_t wbuf[80]; memset (wbuf, 0, sizeof (wbuf)); swprintf (wbuf, 80, L"%Lg %5.9Lf %g %5.9f\n", 3.25L, 7834.5L, 3.75, 7835.5); CHECK (wcscmp (wbuf, L"3.25 7834.500000000 3.75 7835.500000000\n") == 0); memset (wbuf, 0, sizeof (wbuf)); vswprintf (wbuf, 80, L"%Lg %5.9Lf %g %5.9f\n", *ap++); CHECK (wcscmp (wbuf, L"3.25 7834.500000000 3.75 7835.500000000\n") == 0); register_printf_function ('B', printf_size, printf_size_info); register_printf_function ('b', printf_size, printf_size_info); memset (buf, 0, sizeof (buf)); sprintf (buf, "%LB %LB %B %B\n", 3.25L, 7834.5L, 3.75, 7835.5); CHECK (strcmp (buf, "3.250 7.835K 3.750 7.835K\n") == 0); memset (buf, 0, sizeof (buf)); vsprintf (buf, "%Lb %Lb %b %b\n", *ap++); CHECK (strcmp (buf, "3.250 7.651k 3.750 7.652k\n") == 0); /* fscanf, fwscanf, scanf, sscanf, swscanf, vfscanf, vfwscanf, vscanf, vsscanf, vswscanf, vwscanf, wscanf */ /* _IO_sscanf, _IO_vfscanf, __vfscanf, __vsscanf */ l1 = 0; l2 = 0; d1 = 0; d2 = 0; CHECK (sscanf ("8.125 16372.625 -9.5 32163.125", "%Lf %Lf %lf %lf\n", &l1, &l2, &d1, &d2) == 4); CHECK (l1 == 8.125L && l2 == 16372.625 && d1 == -9.5 && d2 == 32163.125); l1 = 0; l2 = 0; d1 = 0; d2 = 0; CHECK (vsscanf ("8.125 16372.625 -9.5 32163.125", "%Lf %Lf %lf %lf\n", *pap++) == 4); CHECK (l1 == 8.125L && l2 == 16372.625 && d1 == -9.5 && d2 == 32163.125); for (i = 0; i < 4; i++) puts ("8.125 16372.625 -9.5 32163.125"); fflush (stdout); if (freopen (tmpp, "r", stdin) == NULL) CHECK (0); l1 = 0; l2 = 0; d1 = 0; d2 = 0; CHECK (fscanf (stdin, "%Lf %Lf %lf %lf\n", &l1, &l2, &d1, &d2) == 4); CHECK (l1 == 8.125L && l2 == 16372.625 && d1 == -9.5 && d2 == 32163.125); l1 = 0; l2 = 0; d1 = 0; d2 = 0; CHECK (vfscanf (stdin, "%Lf %Lf %lf %lf\n", *pap++) == 4); CHECK (l1 == 8.125L && l2 == 16372.625 && d1 == -9.5 && d2 == 32163.125); l1 = 0; l2 = 0; d1 = 0; d2 = 0; CHECK (scanf ("%Lf %Lf %lf %lf\n", &l1, &l2, &d1, &d2) == 4); CHECK (l1 == 8.125L && l2 == 16372.625 && d1 == -9.5 && d2 == 32163.125); l1 = 0; l2 = 0; d1 = 0; d2 = 0; CHECK (vscanf ("%Lf %Lf %lf %lf\n", *pap++) == 4); CHECK (l1 == 8.125L && l2 == 16372.625 && d1 == -9.5 && d2 == 32163.125); if (freopen (tmpp, "r", stdin) == NULL) CHECK (0); l1 = 0; l2 = 0; d1 = 0; d2 = 0; CHECK (swscanf (L"8.125 16372.625 -9.5 32163.125", L"%Lf %Lf %lf %lf\n", &l1, &l2, &d1, &d2) == 4); CHECK (l1 == 8.125L && l2 == 16372.625 && d1 == -9.5 && d2 == 32163.125); l1 = 0; l2 = 0; d1 = 0; d2 = 0; CHECK (vswscanf (L"8.125 16372.625 -9.5 32163.125", L"%Lf %Lf %lf %lf\n", *pap++) == 4); CHECK (l1 == 8.125L && l2 == 16372.625 && d1 == -9.5 && d2 == 32163.125); l1 = 0; l2 = 0; d1 = 0; d2 = 0; CHECK (fwscanf (stdin, L"%Lf %Lf %lf %lf\n", &l1, &l2, &d1, &d2) == 4); CHECK (l1 == 8.125L && l2 == 16372.625 && d1 == -9.5 && d2 == 32163.125); l1 = 0; l2 = 0; d1 = 0; d2 = 0; CHECK (vfwscanf (stdin, L"%Lf %Lf %lf %lf\n", *pap++) == 4); CHECK (l1 == 8.125L && l2 == 16372.625 && d1 == -9.5 && d2 == 32163.125); l1 = 0; l2 = 0; d1 = 0; d2 = 0; CHECK (wscanf (L"%Lf %Lf %lf %lf\n", &l1, &l2, &d1, &d2) == 4); CHECK (l1 == 8.125L && l2 == 16372.625 && d1 == -9.5 && d2 == 32163.125); l1 = 0; l2 = 0; d1 = 0; d2 = 0; CHECK (vwscanf (L"%Lf %Lf %lf %lf\n", *pap++) == 4); CHECK (l1 == 8.125L && l2 == 16372.625 && d1 == -9.5 && d2 == 32163.125); /* syslog, vsyslog */ /* __syslog_chk, __vsyslog_chk */ syslog (1, "long double test %Lg %5.9Lf %g %5.9f\n", 3.25L, 7834.5L, 3.75, 7835.5); vsyslog (1, "long double test %Lg %5.9Lf %g %5.9f\n", *ap++); /* qecvt, qecvt_r, qfcvt, qfcvt_r, qgcvt */ int decpt, sign; decpt = -1300; sign = -1300; CHECK (strcmp (qecvt (3.25L, 8, &decpt, &sign), "32500000") == 0); CHECK (decpt == 1 && sign == 0); decpt = -1300; sign = -1300; CHECK (strcmp (qecvt (-7834.5L, 9, &decpt, &sign), "783450000") == 0); CHECK (decpt == 4 && sign == 1); decpt = -1300; sign = -1300; CHECK (strcmp (ecvt (3.75, 8, &decpt, &sign), "37500000") == 0); CHECK (decpt == 1 && sign == 0); decpt = -1300; sign = -1300; CHECK (strcmp (ecvt (-7835.5, 9, &decpt, &sign), "783550000") == 0); CHECK (decpt == 4 && sign == 1); decpt = -1300; sign = -1300; CHECK (strcmp (qfcvt (3.25L, 8, &decpt, &sign), "325000000") == 0); CHECK (decpt == 1 && sign == 0); decpt = -1300; sign = -1300; CHECK (strcmp (qfcvt (-7834.5L, 9, &decpt, &sign), "7834500000000") == 0); CHECK (decpt == 4 && sign == 1); decpt = -1300; sign = -1300; CHECK (strcmp (fcvt (3.75, 8, &decpt, &sign), "375000000") == 0); CHECK (decpt == 1 && sign == 0); decpt = -1300; sign = -1300; CHECK (strcmp (fcvt (-7835.5, 9, &decpt, &sign), "7835500000000") == 0); CHECK (decpt == 4 && sign == 1); decpt = -1300; sign = -1300; memset (buf, 0, sizeof (buf)); CHECK (qecvt_r (3.25L, 8, &decpt, &sign, buf, sizeof (buf)) == 0); CHECK (strcmp (buf, "32500000") == 0); CHECK (decpt == 1 && sign == 0); decpt = -1300; sign = -1300; memset (buf, 0, sizeof (buf)); CHECK (qecvt_r (-7834.5L, 9, &decpt, &sign, buf, sizeof (buf)) == 0); CHECK (strcmp (buf, "783450000") == 0); CHECK (decpt == 4 && sign == 1); decpt = -1300; sign = -1300; memset (buf, 0, sizeof (buf)); CHECK (ecvt_r (3.75, 8, &decpt, &sign, buf, sizeof (buf)) == 0); CHECK (strcmp (buf, "37500000") == 0); CHECK (decpt == 1 && sign == 0); decpt = -1300; sign = -1300; memset (buf, 0, sizeof (buf)); CHECK (ecvt_r (-7835.5, 9, &decpt, &sign, buf, sizeof (buf)) == 0); CHECK (strcmp (buf, "783550000") == 0); CHECK (decpt == 4 && sign == 1); decpt = -1300; sign = -1300; memset (buf, 0, sizeof (buf)); CHECK (qfcvt_r (3.25L, 8, &decpt, &sign, buf, sizeof (buf)) == 0); CHECK (strcmp (buf, "325000000") == 0); CHECK (decpt == 1 && sign == 0); decpt = -1300; sign = -1300; memset (buf, 0, sizeof (buf)); CHECK (qfcvt_r (-7834.5L, 9, &decpt, &sign, buf, sizeof (buf)) == 0); CHECK (strcmp (buf, "7834500000000") == 0); CHECK (decpt == 4 && sign == 1); decpt = -1300; sign = -1300; memset (buf, 0, sizeof (buf)); CHECK (fcvt_r (3.75, 8, &decpt, &sign, buf, sizeof (buf)) == 0); CHECK (strcmp (buf, "375000000") == 0); CHECK (decpt == 1 && sign == 0); decpt = -1300; sign = -1300; memset (buf, 0, sizeof (buf)); CHECK (fcvt_r (-7835.5, 9, &decpt, &sign, buf, sizeof (buf)) == 0); CHECK (strcmp (buf, "7835500000000") == 0); CHECK (decpt == 4 && sign == 1); memset (buf, 0, sizeof (buf)); CHECK (qgcvt (3.251L, 3, buf) == buf); CHECK (strcmp (buf, "3.25") == 0); memset (buf, 0, sizeof (buf)); CHECK (qgcvt (7834.51L, 5, buf) == buf); CHECK (strcmp (buf, "7834.5") == 0); memset (buf, 0, sizeof (buf)); CHECK (gcvt (3.751, 3, buf) == buf); CHECK (strcmp (buf, "3.75") == 0); memset (buf, 0, sizeof (buf)); CHECK (gcvt (7835.51, 5, buf) == buf); CHECK (strcmp (buf, "7835.5") == 0); /* strfmon, strfmon_l */ /* __strfmon_l */ memset (buf, 0, sizeof (buf)); strfmon (buf, sizeof (buf), "%Ln %Ln %n %n", 3.25L, 7834.5L, 3.75, 7835.5); CHECK (strcmp (buf, "$3.25 $7,834.50 $3.75 $7,835.50") == 0); memset (buf, 0, sizeof (buf)); strfmon_l (buf, sizeof (buf), loc, "%Ln %Ln %n %n", 3.25L, 7834.5L, 3.75, 7835.5); CHECK (strcmp (buf, "$3.25 $7,834.50 $3.75 $7,835.50") == 0); /* strtold, strtold_l, wcstold, wcstold_l */ /* __strtold_l, __wcstold_l, __strtold_internal, __wcstold_internal */ char *q = "1324.75"; CHECK (strtold (q, &p) == 1324.75L && p == q + 7); q = "12325,75"; CHECK (strtold_l (q, &p, loc2) == 12325.75L && p == q + 8); wchar_t *r = L"1374.25", *s; CHECK (wcstold (r, &s) == 1374.25L && s == r + 7); r = L"18374,125"; CHECK (wcstold_l (r, &s, loc2) == 18374.125L && s == r + 9); /* acoshl, acosl, asinhl, asinl, atan2l, atanhl, atanl, cabsl, cacoshl, cacosl, cargl, casinhl, casinl, catanhl, catanl, cbrtl, ccoshl, ccosl, ceill, cexpl, cimagl, clog10l, clogl, conjl, copysignl, coshl, cosl, cpowl, cprojl, creall, csinhl, csinl, csqrtl, ctanhl, ctanl, dreml, erfcl, erfl, exp10l, exp2l, expl, expm1l, fabsl, fdiml, finitel, floorl, fmal, fmaxl, fminl, fmodl, frexpl, gammal, hypotl, ilogbl, isinfl, isnanl, j0l, j1l, jnl, ldexpl, lgammal, lgammal_r, llrintl, llroundl, log10l, log1pl, log2l, logbl, logl, lrintl, lroundl, nexttoward, nexttowardf, modfl, nanl, nearbyintl, nextafterl, nexttowardl, pow10l, powl, remainderl, remquol, rintl, roundl, scalbl, scalblnl, scalbnl, significandl, sincosl, sinhl, sinl, sqrtl, tanhl, tanl, tgammal, truncl, y0l, y1l, ynl */ /* __clog10l, __finitel, __isinfl, __isnanl, __signbitl */ CHECK3 (acosh, 7.0, 2.6339); CHECK3 (acos, 0.75, 0.722734); CHECK3 (asinh, 0.75, 0.69314718); CHECK3 (asin, 0.75, 0.848062078); CHECK4 (atan2, 0.75, 1.0, 0.6435011); CHECK3 (atanh, 0.75, 0.97295507); CHECK3 (atan, 0.75, 0.6435011); CHECK3 (cbrt, 0.75, 0.908560296); CHECK3 (ceil, 0.25, 1.0); CHECK4 (copysign, 3.25, -5.125, -3.25); CHECK3 (cosh, 0.75, 1.29468328); CHECK3 (cos, 0.75, 0.731688868); CHECK4 (drem, 6.2, 2.31, -0.73); CHECK3 (erfc, 2.0, 0.00467773498); CHECK3 (erf, 2.0, 0.995322265); CHECK3 (exp10, 0.75, 5.6234132519); #ifndef __NO_LONG_DOUBLE_MATH /* exp2l hasn't been exported from libm before glibc 2.4. */ CHECK3 (exp2, 0.75, 1.68179283); #endif CHECK3 (exp, 0.75, 2.1170000166); CHECK3 (expm1, 0.75, 1.1170000166); CHECK3 (fabs, -17.25, 17.25); CHECK4 (fdim, 7.9, 2.3, 5.6); CHECK (finitel (2.5L) != 0); CHECK (finitel (HUGE_VALL) == 0); CHECK (finitel ((long double) NAN) == 0); CHECK (finite (2.5) != 0); CHECK (finite (HUGE_VAL) == 0); CHECK (finite ((double) NAN) == 0); CHECK3 (floor, 3.25, 3.0); CHECK5 (fma, 2.4, 4.8, 7.1, 18.62); CHECK4 (fmax, 17.8, 19.1, 19.1); CHECK4 (fmin, 17.8, 19.1, 17.8); CHECK4 (fmod, 6.2, 2.31, 1.58); /* frexpl */ CHECK3 (gamma, 3, 0.6931471805599); CHECK4 (hypot, 0.7, -12.4, 12.4197423); CHECK (ilogbl (-2000.0L) == 10); CHECK (ilogb (-2000.0) == 10); CHECK (isinfl (HUGE_VALL) == 1); CHECK (isinfl (-HUGE_VALL) == -1); CHECK (isinfl (3.2L) == 0); CHECK (isinfl ((long double) NAN) == 0); CHECK (isinf (HUGE_VAL) == 1); CHECK (isinf (-HUGE_VAL) == -1); CHECK (isinf (3.2) == 0); CHECK (isinf ((double) NAN) == 0); CHECK (isnanl (HUGE_VALL) == 0); CHECK (isnanl (3.2L) == 0); CHECK (isnanl ((long double) NAN) != 0); CHECK (isnan (HUGE_VAL) == 0); CHECK (isnan (3.2) == 0); CHECK (isnan ((double) NAN) != 0); CHECK3 (j0, 0.75, 0.864242275); CHECK3 (j1, 0.75, 0.349243602); CHECK4 (jn, 3.0, 2.0, 0.12894324947); CHECK4 (ldexp, 0.8, 4, 12.8); } void test2 (va_list *pap, ...) { va_list ap, apl[50]; int i; va_start (ap, pap); for (i = 0; i < 50; i++) va_copy (apl[i], ap); test (apl, pap); for (i = 0; i < 50; i++) va_end (apl[i]); va_end (ap); } void test3 (int dummy, ...) { va_list ap, apl[50]; int i; va_start (ap, dummy); for (i = 0; i < 50; i++) va_copy (apl[i], ap); test2 (apl, 3.25L, 7834.5L, 3.75, 7835.5); for (i = 0; i < 50; i++) va_end (apl[i]); va_end (ap); } int main (void) { test3 (0, &l1, &l2, &d1, &d2); return failures != 0; }