Thanks, Mike.
[bpt/guile.git] / libguile / strings.c
index 437cedc..03fb4b4 100644 (file)
@@ -26,6 +26,7 @@
 #include <stdio.h>
 #include <ctype.h>
 #include <unistr.h>
+#include <uniconv.h>
 
 #include "libguile/_scm.h"
 #include "libguile/chars.h"
@@ -1015,10 +1016,11 @@ SCM_DEFINE (scm_string, "string", 0, 0, 1,
 
   /* Verify that this is a list of chars.  */
   i = scm_ilength (chrs);
+  SCM_ASSERT (i >= 0, chrs, SCM_ARG1, FUNC_NAME);
+
   len = (size_t) i;
   rest = chrs;
 
-  SCM_ASSERT (len >= 0, chrs, SCM_ARG1, FUNC_NAME);
   while (len > 0 && scm_is_pair (rest))
     {
       SCM elt = SCM_CAR (rest);
@@ -1297,9 +1299,12 @@ SCM_DEFINE (scm_string_append, "string-append", 0, 0, 1,
   size_t len = 0;
   int wide = 0;
   SCM l, s;
-  char *data;
-  scm_t_wchar *wdata;
-  int i;
+  size_t i;
+  union
+  {
+    char *narrow;
+    scm_t_wchar *wide;
+  } data;
 
   SCM_VALIDATE_REST_ARGUMENT (args);
   for (l = args; !scm_is_null (l); l = SCM_CDR (l))
@@ -1310,10 +1315,11 @@ SCM_DEFINE (scm_string_append, "string-append", 0, 0, 1,
       if (!scm_i_is_narrow_string (s))
         wide = 1;
     }
+  data.narrow = NULL;
   if (!wide)
-    res = scm_i_make_string (len, &data);
+    res = scm_i_make_string (len, &data.narrow);
   else
-    res = scm_i_make_wide_string (len, &wdata);
+    res = scm_i_make_wide_string (len, &data.wide);
 
   for (l = args; !scm_is_null (l); l = SCM_CDR (l))
     {
@@ -1323,20 +1329,20 @@ SCM_DEFINE (scm_string_append, "string-append", 0, 0, 1,
       len = scm_i_string_length (s);
       if (!wide)
         {
-          memcpy (data, scm_i_string_chars (s), len);
-          data += len;
+          memcpy (data.narrow, scm_i_string_chars (s), len);
+          data.narrow += len;
         }
       else
         {
           if (scm_i_is_narrow_string (s))
             {
               for (i = 0; i < scm_i_string_length (s); i++)
-                wdata[i] = (unsigned char) scm_i_string_chars (s)[i];
+                data.wide[i] = (unsigned char) scm_i_string_chars (s)[i];
             }
           else
-            u32_cpy ((scm_t_uint32 *) wdata,
+            u32_cpy ((scm_t_uint32 *) data.wide,
                      (scm_t_uint32 *) scm_i_string_wide_chars (s), len);
-          wdata += len;
+          data.wide += len;
         }
       scm_remember_upto_here_1 (s);
     }
@@ -1468,13 +1474,14 @@ scm_to_locale_stringn (SCM str, size_t * lenp)
   /* In the future, enc will hold the port's encoding.  */
   enc = NULL;
 
-  return scm_to_stringn (str, lenp, enc, iconveh_escape_sequence);
+  return scm_to_stringn (str, lenp, enc, 
+                         SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE);
 }
 
 /* Low-level scheme to C string conversion function.  */
 char *
 scm_to_stringn (SCM str, size_t * lenp, const char *encoding,
-                enum iconv_ilseq_handler handler)
+                scm_t_string_failed_conversion_handler handler)
 {
   static const char iso[11] = "ISO-8859-1";
   char *buf;
@@ -1522,14 +1529,14 @@ scm_to_stringn (SCM str, size_t * lenp, const char *encoding,
   buf = NULL;
   len = 0;
   buf = u32_conv_to_encoding (iso,
-                              handler,
+                              (enum iconv_ilseq_handler) handler,
                               (scm_t_uint32 *) scm_i_string_wide_chars (str),
                               ilen, NULL, NULL, &len);
   if (buf == NULL)
     scm_misc_error (NULL, "cannot convert to output locale ~s: \"~s\"",
                     scm_list_2 (scm_from_locale_string (iso), str));
 
-  if (handler == iconveh_escape_sequence)
+  if (handler == SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE)
     unistring_escapes_to_guile_escapes (&buf, &len);
 
   if (lenp)