guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 06/09: Add scm_c_put_escaped_char, scm_c_can_put_char


From: Andy Wingo
Subject: [Guile-commits] 06/09: Add scm_c_put_escaped_char, scm_c_can_put_char
Date: Wed, 1 Jun 2016 10:11:30 +0000 (UTC)

wingo pushed a commit to branch master
in repository guile.

commit 2affb9accf4efae67de915c11300a742cede2d58
Author: Andy Wingo <address@hidden>
Date:   Mon May 30 18:48:09 2016 +0200

    Add scm_c_put_escaped_char, scm_c_can_put_char
    
    * libguile/ports.h:
    * libguile/ports.c (scm_c_put_escaped_char, scm_c_can_put_char): New
      helpers.
---
 libguile/ports.c |   49 ++++++++++++++++++++++++++++++++++++++++++++++++-
 libguile/ports.h |    2 ++
 2 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/libguile/ports.c b/libguile/ports.c
index 95f3337..5d518e8 100644
--- a/libguile/ports.c
+++ b/libguile/ports.c
@@ -2937,6 +2937,14 @@ encode_escape_sequence (scm_t_wchar ch, scm_t_uint8 
buf[ESCAPE_BUFFER_SIZE])
   return i;
 }
 
+void
+scm_c_put_escaped_char (SCM port, scm_t_wchar ch)
+{
+  scm_t_uint8 escape[ESCAPE_BUFFER_SIZE];
+  size_t len = encode_escape_sequence (ch, escape);
+  scm_c_put_latin1_chars (port, escape, len);
+}
+
 /* Convert CODEPOINT to UTF-8 and store the result in UTF8.  Return the
    number of bytes of the UTF-8-encoded string.  */
 static size_t
@@ -3277,6 +3285,45 @@ scm_c_put_char (SCM port, scm_t_wchar ch)
     }
 }
 
+/* Return 0 unless the port can be written out to the port's encoding
+   without errors, substitutions, or escapes.  */
+int
+scm_c_can_put_char (SCM port, scm_t_wchar ch)
+{
+  SCM encoding = SCM_PORT (port)->encoding;
+
+  if (scm_is_eq (encoding, sym_UTF_8)
+      || (scm_is_eq (encoding, sym_ISO_8859_1) && ch <= 0xff)
+      || scm_is_eq (encoding, sym_UTF_16)
+      || scm_is_eq (encoding, sym_UTF_16LE)
+      || scm_is_eq (encoding, sym_UTF_16BE)
+      || scm_is_eq (encoding, sym_UTF_32)
+      || scm_is_eq (encoding, sym_UTF_32LE)
+      || scm_is_eq (encoding, sym_UTF_32BE))
+    return 1;
+
+  {
+    SCM bv = scm_port_buffer_bytevector (scm_port_auxiliary_write_buffer 
(port));
+    scm_t_uint8 buf[UTF8_BUFFER_SIZE];
+    char *input = (char *) buf;
+    size_t input_len;
+    char *output = (char *) SCM_BYTEVECTOR_CONTENTS (bv);
+    size_t output_len = SCM_BYTEVECTOR_LENGTH (bv);
+    size_t result;
+    iconv_t output_cd;
+
+    input_len = codepoint_to_utf8 (ch, buf);
+
+    scm_port_acquire_iconv_descriptors (port, NULL, &output_cd);
+    iconv (output_cd, NULL, NULL, &output, &output_len);
+    result = iconv (output_cd, &input, &input_len, &output, &output_len);
+    iconv (output_cd, NULL, NULL, &output, &output_len);
+    scm_port_release_iconv_descriptors (port);
+
+    return result != (size_t) -1;
+  }
+}
+
 void
 scm_c_put_string (SCM port, SCM string, size_t start, size_t count)
 {
@@ -3361,7 +3408,7 @@ scm_lfwrite_substr (SCM str, size_t start, size_t end, 
SCM port)
   if (end == (size_t) -1)
     end = scm_i_string_length (str);
 
-  scm_i_display_substring (str, start, end, port);
+  scm_c_put_string (port, str, start, end - start);
 }
 
 
diff --git a/libguile/ports.h b/libguile/ports.h
index 7e0a4f3..f8d62c1 100644
--- a/libguile/ports.h
+++ b/libguile/ports.h
@@ -220,6 +220,8 @@ SCM_API void scm_c_put_utf32_chars (SCM port, const 
scm_t_uint32 *buf,
 SCM_API void scm_c_put_string (SCM port, SCM str, size_t start, size_t count);
 SCM_API SCM scm_put_string (SCM port, SCM str, SCM start, SCM count);
 SCM_API void scm_c_put_char (SCM port, scm_t_wchar ch);
+SCM_INTERNAL void scm_c_put_escaped_char (SCM port, scm_t_wchar ch);
+SCM_INTERNAL int scm_c_can_put_char (SCM port, scm_t_wchar ch);
 SCM_API void scm_putc (char c, SCM port);
 SCM_API void scm_puts (const char *str_data, SCM port);
 SCM_API void scm_lfwrite (const char *ptr, size_t size, SCM port);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]