Renamed the "frames" that are related to dynamic-wind to "dynamic
[bpt/guile.git] / test-suite / standalone / test-conversion.c
index 7dc792d..d690264 100644 (file)
  *
  * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libguile.h"
 
 #include <stdio.h>
 #include <assert.h>
+#include <string.h>
 
 static void
 test_1 (const char *str, scm_t_intmax min, scm_t_intmax max,
@@ -187,13 +188,19 @@ typedef struct {
 static SCM
 out_of_range_handler (void *data, SCM key, SCM args)
 {
-  return scm_equal_p (key, scm_str2symbol ("out-of-range"));
+  return scm_equal_p (key, scm_from_locale_symbol ("out-of-range"));
 }
 
 static SCM
 wrong_type_handler (void *data, SCM key, SCM args)
 {
-  return scm_equal_p (key, scm_str2symbol ("wrong-type-arg"));
+  return scm_equal_p (key, scm_from_locale_symbol ("wrong-type-arg"));
+}
+
+static SCM
+misc_error_handler (void *data, SCM key, SCM args)
+{
+  return scm_equal_p (key, scm_from_locale_symbol ("misc-error"));
 }
 
 static SCM
@@ -493,62 +500,516 @@ test_from_unsigned_integer ()
   test_6 (SCM_MOST_POSITIVE_FIXNUM+1, "(+ most-positive-fixnum 1)");
 }
 
+static void
+test_7s (SCM n, scm_t_intmax c_n, const char *result, const char *func)
+{
+  SCM r = scm_c_eval_string (result);
+
+  if (scm_is_false (scm_equal_p (n, r)))
+    {
+      fprintf (stderr, "fail: %s (%Ld) == %s\n", func, c_n, result);
+      exit (1);
+    }
+}
+
+#define TEST_7S(func,arg,res) test_7s (func(arg), arg, res, #func)
+
+static void
+test_7u (SCM n, scm_t_uintmax c_n, const char *result, const char *func)
+{
+  SCM r = scm_c_eval_string (result);
+
+  if (scm_is_false (scm_equal_p (n, r)))
+    {
+      fprintf (stderr, "fail: %s (%Lu) == %s\n", func, c_n, result);
+      exit (1);
+    }
+}
+
+#define TEST_7U(func,arg,res) test_7u (func(arg), arg, res, #func)
+
+typedef struct {
+  SCM val;
+  scm_t_intmax (*func) (SCM);
+  scm_t_intmax result;
+} to_signed_func_data;
+
+static SCM
+to_signed_func_body (void *data)
+{
+  to_signed_func_data *d = (to_signed_func_data *)data;
+  d->result = d->func (d->val);
+  return SCM_BOOL_F;
+}
+
+static void
+test_8s (const char *str, scm_t_intmax (*func) (SCM), const char *func_name,
+        scm_t_intmax result, int range_error, int type_error)
+{
+  to_signed_func_data data;
+  data.val = scm_c_eval_string (str);
+  data.func = func;
+  
+  if (range_error)
+    {
+      if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
+                                           to_signed_func_body, &data,
+                                           out_of_range_handler, NULL)))
+       {
+         fprintf (stderr,
+                  "fail: %s (%s) -> out of range\n", func_name, str);
+         exit (1);
+       }
+    }
+  else if (type_error)
+    {
+      if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
+                                           to_signed_func_body, &data,
+                                           wrong_type_handler, NULL)))
+       {
+         fprintf (stderr,
+                  "fail: %s (%s) -> wrong type\n", func_name, str);
+         exit (1);
+       }
+    }
+  else
+    {
+      if (scm_is_true (scm_internal_catch (SCM_BOOL_T,
+                                          to_signed_func_body, &data,
+                                          any_handler, NULL))
+         || data.result != result)
+       {
+         fprintf (stderr,
+                  "fail: %s (%s) = %Ld\n", func_name, str, result);
+         exit (1);
+       }
+    }
+}
+
+typedef struct {
+  SCM val;
+  scm_t_uintmax (*func) (SCM);
+  scm_t_uintmax result;
+} to_unsigned_func_data;
+
+static SCM
+to_unsigned_func_body (void *data)
+{
+  to_unsigned_func_data *d = (to_unsigned_func_data *)data;
+  d->result = d->func (d->val);
+  return SCM_BOOL_F;
+}
+
+static void
+test_8u (const char *str, scm_t_uintmax (*func) (SCM), const char *func_name,
+        scm_t_uintmax result, int range_error, int type_error)
+{
+  to_unsigned_func_data data;
+  data.val = scm_c_eval_string (str);
+  data.func = func;
+  
+  if (range_error)
+    {
+      if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
+                                           to_unsigned_func_body, &data,
+                                           out_of_range_handler, NULL)))
+       {
+         fprintf (stderr,
+                  "fail: %s (%s) -> out of range\n", func_name, str);
+         exit (1);
+       }
+    }
+  else if (type_error)
+    {
+      if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
+                                           to_unsigned_func_body, &data,
+                                           wrong_type_handler, NULL)))
+       {
+         fprintf (stderr,
+                  "fail: %s (%s) -> wrong type\n", func_name, str);
+         exit (1);
+       }
+    }
+  else
+    {
+      if (scm_is_true (scm_internal_catch (SCM_BOOL_T,
+                                          to_unsigned_func_body, &data,
+                                          any_handler, NULL))
+         || data.result != result)
+       {
+         fprintf (stderr,
+                  "fail: %s (%s) = %Ld\n", func_name, str, result);
+         exit (1);
+       }
+    }
+}
+
+/* We can't rely on the scm_to functions being proper functions but we
+   want to pass them to test_8s and test_8u, so we wrap'em.  Also, we
+   need to give them a common return type.
+*/
+
+#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);
+#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);
+#endif
+
+#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)
+
+
 static void
 test_int_sizes ()
 {
-  SCM n = scm_from_int (91);
-
-  /* Just list them here to check whether the macros expand to correct
-     code. */
-     
-  scm_from_schar (91);
-  scm_from_uchar (91);
-  scm_from_char (91);
-  scm_from_short (91);
-  scm_from_int (91);
-  scm_from_long (91);
+  TEST_7U (scm_from_uchar,  91, "91");
+  TEST_7S (scm_from_schar,  91, "91");
+  TEST_7S (scm_from_char,   91, "91");
+  TEST_7S (scm_from_short, -911, "-911");
+  TEST_7U (scm_from_ushort, 911, "911");
+  TEST_7S (scm_from_int,    911, "911");
+  TEST_7U (scm_from_uint,   911, "911");
+  TEST_7S (scm_from_long,   911, "911");
+  TEST_7U (scm_from_ulong,  911, "911");
 #if SCM_SIZEOF_LONG_LONG != 0
-  scm_from_long_long (91);
-  scm_from_ulong_long (91);
+  TEST_7S (scm_from_long_long,   911, "911");
+  TEST_7U (scm_from_ulong_long,  911, "911");
 #endif
-  scm_from_size_t (91);
-  scm_from_ssize_t (91);
-  scm_from_int8 (91);
-  scm_from_uint8 (91);
-  scm_from_int16 (91);
-  scm_from_uint16 (91);
-  scm_from_int32 (91);
-  scm_from_uint32 (91);
+  TEST_7U (scm_from_size_t,  911, "911");
+  TEST_7S (scm_from_ssize_t, 911, "911");
+
+  TEST_7S (scm_from_int8, -128, "-128");
+  TEST_7S (scm_from_int8,  127,  "127");
+  TEST_7S (scm_from_int8,  128, "-128");
+  TEST_7U (scm_from_uint8, 255,  "255");
+
+  TEST_7S (scm_from_int16, -32768, "-32768");
+  TEST_7S (scm_from_int16,  32767,  "32767");
+  TEST_7S (scm_from_int16,  32768, "-32768");
+  TEST_7U (scm_from_uint16, 65535,  "65535");
+
+  TEST_7S (scm_from_int32,  SCM_T_INT32_MIN,     "-2147483648");
+  TEST_7S (scm_from_int32,  SCM_T_INT32_MAX,      "2147483647");
+  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
-  scm_from_int64 (91);
-  scm_from_uint64 (91);
+  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
 
-  scm_to_schar (n);
-  scm_to_uchar (n);
-  scm_to_char (n);
-  scm_to_short (n);
-  scm_to_int (n);
-  scm_to_long (n);
+  TEST_8S ("91",   scm_to_schar,   91, 0, 0);
+  TEST_8U ("91",   scm_to_uchar,   91, 0, 0);
+  TEST_8S ("91",   scm_to_char,    91, 0, 0);
+  TEST_8S ("-911", scm_to_short, -911, 0, 0);
+  TEST_8U ("911",  scm_to_ushort, 911, 0, 0);
+  TEST_8S ("-911", scm_to_int,   -911, 0, 0);
+  TEST_8U ("911",  scm_to_uint,   911, 0, 0);
+  TEST_8S ("-911", scm_to_long,  -911, 0, 0);
+  TEST_8U ("911",  scm_to_ulong,  911, 0, 0);
 #if SCM_SIZEOF_LONG_LONG != 0
-  scm_to_long_long (n);
-  scm_to_ulong_long (n);
+  TEST_8S ("-911", scm_to_long_long, -911, 0, 0);
+  TEST_8U ("911",  scm_to_ulong_long, 911, 0, 0);
 #endif
-  scm_to_size_t (n);
-  scm_to_ssize_t (n);
-  scm_to_int8 (n);
-  scm_to_uint8 (n);
-  scm_to_int16 (n);
-  scm_to_uint16 (n);
-  scm_to_int32 (n);
-  scm_to_uint32 (n);
+  TEST_8U ("911",  scm_to_size_t,   911, 0, 0);
+  TEST_8S ("911",  scm_to_ssize_t,  911, 0, 0);
+
+  TEST_8S ("-128", scm_to_int8,   SCM_T_INT8_MIN, 0, 0);
+  TEST_8S ("127",  scm_to_int8,   SCM_T_INT8_MAX, 0, 0);
+  TEST_8S ("128",  scm_to_int8,                0, 1, 0);
+  TEST_8S ("#f",   scm_to_int8,                0, 0, 1);
+  TEST_8U ("255",  scm_to_uint8, SCM_T_UINT8_MAX, 0, 0);
+  TEST_8U ("256",  scm_to_uint8,               0, 1, 0);
+  TEST_8U ("-1",   scm_to_uint8,               0, 1, 0);
+  TEST_8U ("#f",   scm_to_uint8,               0, 0, 1);
+
+  TEST_8S ("-32768", scm_to_int16,   SCM_T_INT16_MIN, 0, 0);
+  TEST_8S ("32767",  scm_to_int16,   SCM_T_INT16_MAX, 0, 0);
+  TEST_8S ("32768",  scm_to_int16,                 0, 1, 0);
+  TEST_8S ("#f",     scm_to_int16,                 0, 0, 1);
+  TEST_8U ("65535",  scm_to_uint16, SCM_T_UINT16_MAX, 0, 0);
+  TEST_8U ("65536",  scm_to_uint16,                0, 1, 0);
+  TEST_8U ("-1",     scm_to_uint16,                0, 1, 0);
+  TEST_8U ("#f",     scm_to_uint16,                0, 0, 1);
+
+  TEST_8S ("-2147483648", scm_to_int32,   SCM_T_INT32_MIN, 0, 0);
+  TEST_8S ("2147483647",  scm_to_int32,   SCM_T_INT32_MAX, 0, 0);
+  TEST_8S ("2147483648",  scm_to_int32,                 0, 1, 0);
+  TEST_8S ("#f",          scm_to_int32,                 0, 0, 1);
+  TEST_8U ("4294967295",  scm_to_uint32, SCM_T_UINT32_MAX, 0, 0);
+  TEST_8U ("4294967296",  scm_to_uint32,                0, 1, 0);
+  TEST_8U ("-1",          scm_to_uint32,                0, 1, 0);
+  TEST_8U ("#f",          scm_to_uint32,                0, 0, 1);
+
 #if SCM_HAVE_T_INT64
-  scm_to_int64 (n);
-  scm_to_uint64 (n);
+  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);
+  TEST_8S ("#f",                   scm_to_int64,                 0, 0, 1);
+  TEST_8U ("18446744073709551615", scm_to_uint64, SCM_T_UINT64_MAX, 0, 0);
+  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
 
 }
 
+static void
+test_9 (double val, const char *result)
+{
+  SCM res = scm_c_eval_string (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);
+    }
+}
+
+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");
+}
+
+typedef struct {
+  SCM val;
+  double result;
+} to_double_data;
+
+static SCM
+to_double_body (void *data)
+{
+  to_double_data *d = (to_double_data *)data;
+  d->result = scm_to_double (d->val);
+  return SCM_BOOL_F;
+}
+
+static void
+test_10 (const char *val, double result, int type_error)
+{
+  to_double_data data;
+  data.val = scm_c_eval_string (val);
+  
+  if (type_error)
+    {
+      if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
+                                           to_double_body, &data,
+                                           wrong_type_handler, NULL)))
+       {
+         fprintf (stderr,
+                  "fail: scm_double (%s) -> wrong type\n", val);
+         exit (1);
+       }
+    }
+  else
+    {
+      if (scm_is_true (scm_internal_catch (SCM_BOOL_T,
+                                          to_double_body, &data,
+                                          any_handler, NULL))
+         || data.result != result)
+       {
+         fprintf (stderr,
+                  "fail: scm_to_double (%s) = %g\n", val, result);
+         exit (1);
+       }
+    }
+}
+
+static void
+test_to_double ()
+{
+  test_10 ("#f",          0.0,  1);
+  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 ("+1i",         0.0,  1);
+}
+
+typedef struct {
+  SCM val;
+  char *result;
+} to_locale_string_data;
+
+static SCM
+to_locale_string_body (void *data)
+{
+  to_locale_string_data *d = (to_locale_string_data *)data;
+  d->result = scm_to_locale_string (d->val);
+  return SCM_BOOL_F;
+}
+
+static void
+test_11 (const char *str, const char *result, int misc_error, int type_error)
+{
+  to_locale_string_data data;
+  data.val = scm_c_eval_string (str);
+  data.result = NULL;
+
+  if (misc_error)
+    {
+      if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
+                                           to_locale_string_body, &data,
+                                           misc_error_handler, NULL)))
+       {
+         fprintf (stderr,
+                  "fail: scm_to_locale_string (%s) -> misc error\n", str);
+         exit (1);
+       }
+    }
+  else if (type_error)
+    {
+      if (scm_is_false (scm_internal_catch (SCM_BOOL_T,
+                                           to_locale_string_body, &data,
+                                           wrong_type_handler, NULL)))
+       {
+         fprintf (stderr,
+                  "fail: scm_to_locale_string (%s) -> wrong type\n", str);
+         exit (1);
+       }
+    }
+  else
+    {
+      if (scm_is_true (scm_internal_catch (SCM_BOOL_T,
+                                          to_locale_string_body, &data,
+                                          any_handler, NULL))
+         || data.result == NULL || strcmp (data.result, result))
+       {
+         fprintf (stderr,
+                  "fail: scm_to_locale_string (%s) = %s\n", str, result);
+         exit (1);
+       }
+    }
+
+  free (data.result);
+}
+
+static void
+test_locale_strings ()
+{
+  const char *lstr = "This is not a string.";
+  char *lstr2;
+  SCM str, str2;
+  char buf[20];
+  size_t len;
+
+  if (!scm_is_string (scm_c_eval_string ("\"foo\"")))
+    {
+      fprintf (stderr, "fail: scm_is_string (\"foo\") = true\n");
+      exit (1);
+    }
+
+  str = scm_from_locale_string (lstr);
+
+  if (!scm_is_string (str))
+    {
+      fprintf (stderr, "fail: scm_is_string (str) = true\n");
+      exit (1);
+    }
+
+  lstr2 = scm_to_locale_string (str);
+  if (strcmp (lstr, lstr2))
+    {
+      fprintf (stderr, "fail: lstr = lstr2\n");
+      exit (1);
+    }
+  free (lstr2);
+
+  buf[15] = 'x';
+  len = scm_to_locale_stringbuf (str, buf, 15);
+  if (len != strlen (lstr))
+    {
+      fprintf (stderr, "fail: scm_to_locale_stringbuf (...) = strlen(lstr)\n");
+      exit (1);
+    }
+  if (buf[15] != 'x')
+    {
+      fprintf (stderr, "fail: scm_to_locale_stringbuf (...) no overrun\n");
+      exit (1);
+    }
+  if (strncmp (lstr, buf, 15))
+    {
+      fprintf (stderr, "fail: scm_to_locale_stringbuf (...) = lstr\n");
+      exit (1);
+    }
+
+  str2 = scm_from_locale_stringn (lstr, 10);
+
+  if (!scm_is_string (str2))
+    {
+      fprintf (stderr, "fail: scm_is_string (str2) = true\n");
+      exit (1);
+    }
+
+  lstr2 = scm_to_locale_string (str2);
+  if (strncmp (lstr, lstr2, 10))
+    {
+      fprintf (stderr, "fail: lstr = lstr2\n");
+      exit (1);
+    }
+  free (lstr2);
+
+  buf[10] = 'x';
+  len = scm_to_locale_stringbuf (str2, buf, 20);
+  if (len != 10)
+    {
+      fprintf (stderr, "fail: scm_to_locale_stringbuf (...) = 10\n");
+      exit (1);
+    }
+  if (buf[10] != 'x')
+    {
+      fprintf (stderr, "fail: scm_to_locale_stringbuf (...) no overrun\n");
+      exit (1);
+    }
+  if (strncmp (lstr, buf, 10))
+    {
+      fprintf (stderr, "fail: scm_to_locale_stringbuf (...) = lstr\n");
+      exit (1);
+    }
+
+  lstr2 = scm_to_locale_stringn (str2, &len);
+  if (len != 10)
+    {
+      fprintf (stderr, "fail: scm_to_locale_stringn, len = 10\n");
+      exit (1);
+    }
+
+  test_11 ("#f", NULL, 0, 1);
+  test_11 ("\"foo\"", "foo", 0, 0);
+  test_11 ("(string #\\f #\\nul)", NULL, 1, 0);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -560,5 +1021,8 @@ main (int argc, char *argv[])
   test_from_signed_integer ();
   test_from_unsigned_integer ();
   test_int_sizes ();
+  test_from_double ();
+  test_to_double ();
+  test_locale_strings ();
   return 0;
 }