Merge commit '60617d819d77a1b92ed6c557a0b49b8e9a8e97b9'
[bpt/guile.git] / libguile / strings.c
index fa97a00..e8eb91c 100644 (file)
@@ -261,8 +261,34 @@ scm_i_pthread_mutex_t stringbuf_write_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
 
 #define IS_SH_STRING(str)   (SCM_CELL_TYPE(str)==SH_STRING_TAG)
 
+void
+scm_i_print_stringbuf (SCM exp, SCM port, scm_print_state *pstate) 
+{
+  SCM str;
+
+  scm_i_pthread_mutex_lock (&stringbuf_write_mutex);
+  SET_STRINGBUF_SHARED (exp);
+  scm_i_pthread_mutex_unlock (&stringbuf_write_mutex);
+
+  str =  scm_double_cell (RO_STRING_TAG, SCM_UNPACK(exp),
+                          0, STRINGBUF_LENGTH (exp));
+
+  scm_puts ("#<stringbuf ", port);
+  scm_iprin1 (str, port, pstate);
+  scm_puts (">", port);
+}
+
 SCM scm_nullstr;
 
+static SCM null_stringbuf;
+
+static void
+init_null_stringbuf (void)
+{
+  null_stringbuf = make_stringbuf (0);
+  SET_STRINGBUF_SHARED (null_stringbuf);
+}
+
 /* Create a scheme string with space for LEN 8-bit Latin-1-encoded
    characters.  CHARSP, if not NULL, will be set to location of the
    char array.  If READ_ONLY_P, the returned string is read-only;
@@ -270,17 +296,13 @@ SCM scm_nullstr;
 SCM
 scm_i_make_string (size_t len, char **charsp, int read_only_p)
 {
-  static SCM null_stringbuf = SCM_BOOL_F;
   SCM buf;
   SCM res;
 
   if (len == 0)
     {
-      if (SCM_UNLIKELY (scm_is_false (null_stringbuf)))
-        {
-          null_stringbuf = make_stringbuf (0);
-          SET_STRINGBUF_SHARED (null_stringbuf);
-        }
+      static scm_i_pthread_once_t once = SCM_I_PTHREAD_ONCE_INIT;
+      scm_i_pthread_once (&once, init_null_stringbuf);
       buf = null_stringbuf;
     }
   else
@@ -1740,7 +1762,8 @@ scm_from_port_stringn (const char *str, size_t len, SCM port)
   if (pti->encoding_mode == SCM_PORT_ENCODING_MODE_LATIN1)
     return scm_from_latin1_stringn (str, len);
   else if (pti->encoding_mode == SCM_PORT_ENCODING_MODE_UTF8
-           && pt->ilseq_handler == SCM_FAILED_CONVERSION_ERROR)
+           && (pt->ilseq_handler == SCM_FAILED_CONVERSION_ERROR
+               || (u8_check ((uint8_t *) str, len) == NULL)))
     return scm_from_utf8_stringn (str, len);
   else
     return scm_from_stringn (str, len, pt->encoding, pt->ilseq_handler);