X-Git-Url: http://git.hcoop.net/bpt/guile.git/blobdiff_plain/5995c6d8013789b0d18ea0419e63c8377d01734b..521c542199afa4f199746d5bbffc18a988cb30bc:/test-suite/standalone/test-conversion.c diff --git a/test-suite/standalone/test-conversion.c b/test-suite/standalone/test-conversion.c index b8dfab8ea..700e5b3d4 100644 --- a/test-suite/standalone/test-conversion.c +++ b/test-suite/standalone/test-conversion.c @@ -1,18 +1,19 @@ -/* Copyright (C) 1999,2000,2001,2003,2004, 2006, 2007, 2008 Free Software Foundation, Inc. +/* Copyright (C) 1999,2000,2001,2003,2004, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA */ #if HAVE_CONFIG_H @@ -21,13 +22,15 @@ #include +#include #include -#include #include #ifdef HAVE_INTTYPES_H # include -#elif (!defined PRIiMAX) +#endif + +#ifndef PRIiMAX # if (defined SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG >= 8) # define PRIiMAX "lli" # define PRIuMAX "llu" @@ -48,7 +51,7 @@ test_1 (const char *str, scm_t_intmax min, scm_t_intmax max, fprintf (stderr, "fail: scm_is_signed_integer (%s, " "%" PRIiMAX ", %" PRIiMAX ") == %d\n", str, min, max, result); - exit (1); + exit (EXIT_FAILURE); } } @@ -134,7 +137,7 @@ test_2 (const char *str, scm_t_uintmax min, scm_t_uintmax max, fprintf (stderr, "fail: scm_is_unsigned_integer (%s, " "%" PRIuMAX ", %" PRIuMAX ") == %d\n", str, min, max, result); - exit (1); + exit (EXIT_FAILURE); } } @@ -255,7 +258,7 @@ test_3 (const char *str, scm_t_intmax min, scm_t_intmax max, "fail: scm_to_signed_int (%s, " "%" PRIiMAX ", %" PRIiMAX ") -> out of range\n", str, min, max); - exit (1); + exit (EXIT_FAILURE); } } else if (type_error) @@ -268,7 +271,7 @@ test_3 (const char *str, scm_t_intmax min, scm_t_intmax max, "fail: scm_to_signed_int (%s, " "%" PRIiMAX", %" PRIiMAX ") -> wrong type\n", str, min, max); - exit (1); + exit (EXIT_FAILURE); } } else @@ -282,7 +285,7 @@ test_3 (const char *str, scm_t_intmax min, scm_t_intmax max, "fail: scm_to_signed_int (%s, " "%" PRIiMAX ", %" PRIiMAX ") = %" PRIiMAX "\n", str, min, max, result); - exit (1); + exit (EXIT_FAILURE); } } } @@ -390,7 +393,7 @@ test_4 (const char *str, scm_t_uintmax min, scm_t_uintmax max, "fail: scm_to_unsigned_int (%s, " "%" PRIuMAX ", %" PRIuMAX ") -> out of range\n", str, min, max); - exit (1); + exit (EXIT_FAILURE); } } else if (type_error) @@ -403,7 +406,7 @@ test_4 (const char *str, scm_t_uintmax min, scm_t_uintmax max, "fail: scm_to_unsigned_int (%s, " "%" PRIuMAX ", %" PRIuMAX ") -> wrong type\n", str, min, max); - exit (1); + exit (EXIT_FAILURE); } } else @@ -417,7 +420,7 @@ test_4 (const char *str, scm_t_uintmax min, scm_t_uintmax max, "fail: scm_to_unsigned_int (%s, " "%" PRIuMAX ", %" PRIuMAX ") == %" PRIuMAX "\n", str, min, max, result); - exit (1); + exit (EXIT_FAILURE); } } } @@ -473,7 +476,7 @@ test_5 (scm_t_intmax val, const char *result) { fprintf (stderr, "fail: scm_from_signed_integer (%" PRIiMAX ") == %s\n", val, result); - exit (1); + exit (EXIT_FAILURE); } } @@ -506,7 +509,7 @@ test_6 (scm_t_uintmax val, const char *result) fprintf (stderr, "fail: scm_from_unsigned_integer (%" PRIuMAX ") == %s\n", val, result); - exit (1); + exit (EXIT_FAILURE); } } @@ -534,7 +537,7 @@ test_7s (SCM n, scm_t_intmax c_n, const char *result, const char *func) if (scm_is_false (scm_equal_p (n, r))) { fprintf (stderr, "fail: %s (%" PRIiMAX ") == %s\n", func, c_n, result); - exit (1); + exit (EXIT_FAILURE); } } @@ -548,7 +551,7 @@ test_7u (SCM n, scm_t_uintmax c_n, const char *result, const char *func) if (scm_is_false (scm_equal_p (n, r))) { fprintf (stderr, "fail: %s (%" PRIuMAX ") == %s\n", func, c_n, result); - exit (1); + exit (EXIT_FAILURE); } } @@ -584,7 +587,7 @@ test_8s (const char *str, scm_t_intmax (*func) (SCM), const char *func_name, { fprintf (stderr, "fail: %s (%s) -> out of range\n", func_name, str); - exit (1); + exit (EXIT_FAILURE); } } else if (type_error) @@ -595,7 +598,7 @@ test_8s (const char *str, scm_t_intmax (*func) (SCM), const char *func_name, { fprintf (stderr, "fail: %s (%s) -> wrong type\n", func_name, str); - exit (1); + exit (EXIT_FAILURE); } } else @@ -607,7 +610,7 @@ test_8s (const char *str, scm_t_intmax (*func) (SCM), const char *func_name, { fprintf (stderr, "fail: %s (%s) = %" PRIiMAX "\n", func_name, str, result); - exit (1); + exit (EXIT_FAILURE); } } } @@ -642,7 +645,7 @@ test_8u (const char *str, scm_t_uintmax (*func) (SCM), const char *func_name, { fprintf (stderr, "fail: %s (%s) -> out of range\n", func_name, str); - exit (1); + exit (EXIT_FAILURE); } } else if (type_error) @@ -653,7 +656,7 @@ test_8u (const char *str, scm_t_uintmax (*func) (SCM), const char *func_name, { fprintf (stderr, "fail: %s (%s) -> wrong type\n", func_name, str); - exit (1); + exit (EXIT_FAILURE); } } else @@ -665,7 +668,7 @@ test_8u (const char *str, scm_t_uintmax (*func) (SCM), const char *func_name, { fprintf (stderr, "fail: %s (%s) = %" PRIiMAX "\n", func_name, str, result); - exit (1); + exit (EXIT_FAILURE); } } } @@ -678,32 +681,30 @@ test_8u (const char *str, scm_t_uintmax (*func) (SCM), const char *func_name, #define DEFSTST(f) static scm_t_intmax tst_##f (SCM x) { return f(x); } #define DEFUTST(f) static scm_t_uintmax tst_##f (SCM x) { return f(x); } -DEFSTST (scm_to_schar); -DEFUTST (scm_to_uchar); -DEFSTST (scm_to_char); -DEFSTST (scm_to_short); -DEFUTST (scm_to_ushort); -DEFSTST (scm_to_int); -DEFUTST (scm_to_uint); -DEFSTST (scm_to_long); -DEFUTST (scm_to_ulong); +DEFSTST (scm_to_schar) +DEFUTST (scm_to_uchar) +DEFSTST (scm_to_char) +DEFSTST (scm_to_short) +DEFUTST (scm_to_ushort) +DEFSTST (scm_to_int) +DEFUTST (scm_to_uint) +DEFSTST (scm_to_long) +DEFUTST (scm_to_ulong) #if SCM_SIZEOF_LONG_LONG != 0 -DEFSTST (scm_to_long_long); -DEFUTST (scm_to_ulong_long); -#endif -DEFSTST (scm_to_ssize_t); -DEFUTST (scm_to_size_t); - -DEFSTST (scm_to_int8); -DEFUTST (scm_to_uint8); -DEFSTST (scm_to_int16); -DEFUTST (scm_to_uint16); -DEFSTST (scm_to_int32); -DEFUTST (scm_to_uint32); -#ifdef SCM_HAVE_T_INT64 -DEFSTST (scm_to_int64); -DEFUTST (scm_to_uint64); +DEFSTST (scm_to_long_long) +DEFUTST (scm_to_ulong_long) #endif +DEFSTST (scm_to_ssize_t) +DEFUTST (scm_to_size_t) + +DEFSTST (scm_to_int8) +DEFUTST (scm_to_uint8) +DEFSTST (scm_to_int16) +DEFUTST (scm_to_uint16) +DEFSTST (scm_to_int32) +DEFUTST (scm_to_uint32) +DEFSTST (scm_to_int64) +DEFUTST (scm_to_uint64) #define TEST_8S(v,f,r,re,te) test_8s (v, tst_##f, #f, r, re, te) #define TEST_8U(v,f,r,re,te) test_8u (v, tst_##f, #f, r, re, te) @@ -743,11 +744,9 @@ test_int_sizes () TEST_7S (scm_from_int32, SCM_T_INT32_MAX+1LL, "-2147483648"); TEST_7U (scm_from_uint32, SCM_T_UINT32_MAX, "4294967295"); -#if SCM_HAVE_T_INT64 TEST_7S (scm_from_int64, SCM_T_INT64_MIN, "-9223372036854775808"); TEST_7S (scm_from_int64, SCM_T_INT64_MAX, "9223372036854775807"); TEST_7U (scm_from_uint64, SCM_T_UINT64_MAX, "18446744073709551615"); -#endif TEST_8S ("91", scm_to_schar, 91, 0, 0); TEST_8U ("91", scm_to_uchar, 91, 0, 0); @@ -792,7 +791,6 @@ test_int_sizes () TEST_8U ("-1", scm_to_uint32, 0, 1, 0); TEST_8U ("#f", scm_to_uint32, 0, 0, 1); -#if SCM_HAVE_T_INT64 TEST_8S ("-9223372036854775808", scm_to_int64, SCM_T_INT64_MIN, 0, 0); TEST_8S ("9223372036854775807", scm_to_int64, SCM_T_INT64_MAX, 0, 0); TEST_8S ("9223372036854775808", scm_to_int64, 0, 1, 0); @@ -801,7 +799,6 @@ test_int_sizes () TEST_8U ("18446744073709551616", scm_to_uint64, 0, 1, 0); TEST_8U ("-1", scm_to_uint64, 0, 1, 0); TEST_8U ("#f", scm_to_uint64, 0, 0, 1); -#endif } @@ -812,19 +809,64 @@ test_9 (double val, const char *result) if (scm_is_false (scm_eqv_p (res, scm_from_double (val)))) { fprintf (stderr, "fail: scm_from_double (%g) == %s\n", val, result); - exit (1); + exit (EXIT_FAILURE); } } +/* The `infinity' and `not-a-number' values. */ +static double guile_Inf, guile_NaN; + +/* Initialize GUILE_INF and GUILE_NAN. Taken from `guile_ieee_init ()' in + `libguile/numbers.c'. */ +static void +ieee_init (void) +{ +#ifdef INFINITY + /* C99 INFINITY, when available. + FIXME: The standard allows for INFINITY to be something that overflows + at compile time. We ought to have a configure test to check for that + before trying to use it. (But in practice we believe this is not a + problem on any system guile is likely to target.) */ + guile_Inf = INFINITY; +#elif defined HAVE_DINFINITY + /* OSF */ + extern unsigned int DINFINITY[2]; + guile_Inf = (*((double *) (DINFINITY))); +#else + double tmp = 1e+10; + guile_Inf = tmp; + for (;;) + { + guile_Inf *= 1e+10; + if (guile_Inf == tmp) + break; + tmp = guile_Inf; + } +#endif + +#ifdef NAN + /* C99 NAN, when available */ + guile_NaN = NAN; +#elif defined HAVE_DQNAN + { + /* OSF */ + extern unsigned int DQNAN[2]; + guile_NaN = (*((double *)(DQNAN))); + } +#else + guile_NaN = guile_Inf / guile_Inf; +#endif +} + static void test_from_double () { test_9 (12, "12.0"); test_9 (0.25, "0.25"); test_9 (0.1, "0.1"); - test_9 (1.0/0.0, "+inf.0"); - test_9 (-1.0/0.0, "-inf.0"); - test_9 (0.0/0.0, "+nan.0"); + test_9 (guile_Inf, "+inf.0"); + test_9 (-guile_Inf, "-inf.0"); + test_9 (guile_NaN, "+nan.0"); } typedef struct { @@ -854,7 +896,7 @@ test_10 (const char *val, double result, int type_error) { fprintf (stderr, "fail: scm_double (%s) -> wrong type\n", val); - exit (1); + exit (EXIT_FAILURE); } } else @@ -866,7 +908,7 @@ test_10 (const char *val, double result, int type_error) { fprintf (stderr, "fail: scm_to_double (%s) = %g\n", val, result); - exit (1); + exit (EXIT_FAILURE); } } } @@ -878,8 +920,8 @@ test_to_double () test_10 ("12", 12.0, 0); test_10 ("0.25", 0.25, 0); test_10 ("1/4", 0.25, 0); - test_10 ("+inf.0", 1.0/0.0, 0); - test_10 ("-inf.0", -1.0/0.0, 0); + test_10 ("+inf.0", guile_Inf, 0); + test_10 ("-inf.0",-guile_Inf, 0); test_10 ("+1i", 0.0, 1); } @@ -911,7 +953,7 @@ test_11 (const char *str, const char *result, int misc_error, int type_error) { fprintf (stderr, "fail: scm_to_locale_string (%s) -> misc error\n", str); - exit (1); + exit (EXIT_FAILURE); } } else if (type_error) @@ -922,7 +964,7 @@ test_11 (const char *str, const char *result, int misc_error, int type_error) { fprintf (stderr, "fail: scm_to_locale_string (%s) -> wrong type\n", str); - exit (1); + exit (EXIT_FAILURE); } } else @@ -934,7 +976,7 @@ test_11 (const char *str, const char *result, int misc_error, int type_error) { fprintf (stderr, "fail: scm_to_locale_string (%s) = %s\n", str, result); - exit (1); + exit (EXIT_FAILURE); } } @@ -953,7 +995,7 @@ test_locale_strings () if (!scm_is_string (scm_c_eval_string ("\"foo\""))) { fprintf (stderr, "fail: scm_is_string (\"foo\") = true\n"); - exit (1); + exit (EXIT_FAILURE); } str = scm_from_locale_string (lstr); @@ -961,14 +1003,14 @@ test_locale_strings () if (!scm_is_string (str)) { fprintf (stderr, "fail: scm_is_string (str) = true\n"); - exit (1); + exit (EXIT_FAILURE); } lstr2 = scm_to_locale_string (str); if (strcmp (lstr, lstr2)) { fprintf (stderr, "fail: lstr = lstr2\n"); - exit (1); + exit (EXIT_FAILURE); } free (lstr2); @@ -977,17 +1019,17 @@ test_locale_strings () if (len != strlen (lstr)) { fprintf (stderr, "fail: scm_to_locale_stringbuf (...) = strlen(lstr)\n"); - exit (1); + exit (EXIT_FAILURE); } if (buf[15] != 'x') { fprintf (stderr, "fail: scm_to_locale_stringbuf (...) no overrun\n"); - exit (1); + exit (EXIT_FAILURE); } if (strncmp (lstr, buf, 15)) { fprintf (stderr, "fail: scm_to_locale_stringbuf (...) = lstr\n"); - exit (1); + exit (EXIT_FAILURE); } str2 = scm_from_locale_stringn (lstr, 10); @@ -995,14 +1037,14 @@ test_locale_strings () if (!scm_is_string (str2)) { fprintf (stderr, "fail: scm_is_string (str2) = true\n"); - exit (1); + exit (EXIT_FAILURE); } lstr2 = scm_to_locale_string (str2); if (strncmp (lstr, lstr2, 10)) { fprintf (stderr, "fail: lstr = lstr2\n"); - exit (1); + exit (EXIT_FAILURE); } free (lstr2); @@ -1011,24 +1053,24 @@ test_locale_strings () if (len != 10) { fprintf (stderr, "fail: scm_to_locale_stringbuf (...) = 10\n"); - exit (1); + exit (EXIT_FAILURE); } if (buf[10] != 'x') { fprintf (stderr, "fail: scm_to_locale_stringbuf (...) no overrun\n"); - exit (1); + exit (EXIT_FAILURE); } if (strncmp (lstr, buf, 10)) { fprintf (stderr, "fail: scm_to_locale_stringbuf (...) = lstr\n"); - exit (1); + exit (EXIT_FAILURE); } lstr2 = scm_to_locale_stringn (str2, &len); if (len != 10) { fprintf (stderr, "fail: scm_to_locale_stringn, len = 10\n"); - exit (1); + exit (EXIT_FAILURE); } test_11 ("#f", NULL, 0, 1); @@ -1036,6 +1078,105 @@ test_locale_strings () test_11 ("(string #\\f #\\nul)", NULL, 1, 0); } +static void +test_to_utf8_stringn () +{ + scm_t_wchar wstr[] = { 0x20, /* 0x20 */ + 0xDF, /* 0xC3, 0x9F */ + 0x65E5, /* 0xE6, 0x97, 0xA5 */ + 0x1D400 }; /* 0xF0, 0x9D, 0x90, 0x80 */ + + SCM str0 = scm_from_utf32_stringn (wstr, 1); /* ASCII */ + SCM str1 = scm_from_utf32_stringn (wstr, 2); /* Narrow */ + SCM str2 = scm_from_utf32_stringn (wstr, 4); /* Wide */ + + char cstr0[] = { 0x20, 0 }; + char cstr1[] = { 0x20, 0xC3, 0x9F, 0 }; + char cstr2[] = { 0x20, 0xC3, 0x9F, 0xE6, 0x97, 0xA5, + 0xF0, 0x9D, 0x90, 0x80, 0 }; + char *cstr; + size_t len; + + /* Test conversion of ASCII string */ + cstr = scm_to_utf8_stringn (str0, &len); + if (len + 1 != sizeof (cstr0) || memcmp (cstr, cstr0, len)) + { + fprintf (stderr, "fail: scm_to_utf8_stringn (, &len)"); + exit (EXIT_FAILURE); + } + free (cstr); + cstr = scm_to_utf8_stringn (str0, NULL); + if (memcmp (cstr, cstr0, len + 1)) + { + fprintf (stderr, "fail: scm_to_utf8_stringn (, NULL)"); + exit (EXIT_FAILURE); + } + free (cstr); + + /* Test conversion of narrow string */ + cstr = scm_to_utf8_stringn (str1, &len); + if (len + 1 != sizeof (cstr1) || memcmp (cstr, cstr1, len)) + { + fprintf (stderr, "fail: scm_to_utf8_stringn (, &len)"); + exit (EXIT_FAILURE); + } + free (cstr); + cstr = scm_to_utf8_stringn (str1, NULL); + if (memcmp (cstr, cstr1, len + 1)) + { + fprintf (stderr, "fail: scm_to_utf8_stringn (, NULL)"); + exit (EXIT_FAILURE); + } + free (cstr); + + /* Test conversion of wide string */ + cstr = scm_to_utf8_stringn (str2, &len); + if (len + 1 != sizeof (cstr2) || memcmp (cstr, cstr2, len)) + { + fprintf (stderr, "fail: scm_to_utf8_stringn (, &len)"); + exit (EXIT_FAILURE); + } + free (cstr); + cstr = scm_to_utf8_stringn (str2, NULL); + if (memcmp (cstr, cstr2, len + 1)) + { + fprintf (stderr, "fail: scm_to_utf8_stringn (, NULL)"); + exit (EXIT_FAILURE); + } + free (cstr); +} + +static void +test_is_exact () +{ + if (1 != scm_is_exact (scm_c_eval_string ("3"))) + { + fprintf (stderr, "fail: scm_is_exact (\"3\") = 1\n"); + exit (EXIT_FAILURE); + } + if (0 != scm_is_exact (scm_c_eval_string ("3.0"))) + { + fprintf (stderr, "fail: scm_is_exact (\"3.0\") = 0\n"); + exit (EXIT_FAILURE); + } +} + +static void +test_is_inexact () +{ + if (1 !=scm_is_inexact (scm_c_eval_string ("3.0"))) + { + fprintf (stderr, "fail: scm_is_inexact (\"3.0\") = 1\n"); + exit (EXIT_FAILURE); + } + if (0 != scm_is_inexact (scm_c_eval_string ("3"))) + { + fprintf (stderr, "fail: scm_is_inexact (\"3\") = 0\n"); + exit (EXIT_FAILURE); + } +} + + static void tests (void *data, int argc, char **argv) { @@ -1049,11 +1190,15 @@ tests (void *data, int argc, char **argv) test_from_double (); test_to_double (); test_locale_strings (); + test_to_utf8_stringn (); + test_is_exact (); + test_is_inexact (); } int main (int argc, char *argv[]) { + ieee_init (); scm_boot_guile (argc, argv, tests, NULL); return 0; }