From 9ee77561428da1b46b760282ea08c643ef4b05bb Mon Sep 17 00:00:00 2001
From: Han-Wen Nienhuys <hanwen@xs4all.nl>
Date: Mon, 9 May 2005 09:19:52 +0000
Subject: [PATCH] (LY_DEFINE): hand-convert utf8 to 32 bits. Patch by Matthias
 Neeracher.

---
 ChangeLog              |  5 +++++
 lily/general-scheme.cc | 33 ++++++++++++++++++++-------------
 2 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6118eea170..f94a1b5712 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2005-05-09  Han-Wen Nienhuys  <hanwen@xs4all.nl>
+
+	* lily/general-scheme.cc (LY_DEFINE): hand-convert utf8 to 32
+	bits. Patch by Matthias Neeracher.
+
 2005-05-09  Mats Bengtsson  <mabe@drongo.s3.kth.se>
 
 	* scripts/convert-ly.py: In the conversion to version 1.9.0, 
diff --git a/lily/general-scheme.cc b/lily/general-scheme.cc
index 7b9233fd10..ffe6875d63 100644
--- a/lily/general-scheme.cc
+++ b/lily/general-scheme.cc
@@ -12,11 +12,6 @@
 #include <math.h>  /* isinf */
 #include <stdio.h>
 #include <string.h>  /* memset */
-#if HAVE_UTF8_WCHAR_H
-#include <utf8/wchar.h>  /* wcrtomb */
-#else
-#include <wchar.h> /* wcrtomb */
-#endif
 
 #include "international.hh"
 #include "libc-extension.hh"
@@ -249,17 +244,29 @@ LY_DEFINE (ly_wchar_to_utf_8, "ly:wide-char->utf-8",
 	   1, 0, 0, (SCM wc),
 	   "Encode the Unicode codepoint @var{wc} as UTF-8")
 {
-  char buf[100];
+  char buf[5];
 
   SCM_ASSERT_TYPE (scm_is_integer (wc), wc, SCM_ARG1, __FUNCTION__, "integer");
-  wchar_t wide_char = (wchar_t) scm_to_int (wc);
-
-  mbstate_t state;
-  memset (&state, '\0', sizeof (state));
-  memset (buf, '\0', sizeof (buf));
+  unsigned wide_char = (unsigned) scm_to_int (wc);
+  char * p = buf;
+
+  if (wide_char < 0x0080) {
+    *p++ = (char)wide_char;
+  } else if (wide_char < 0x0800) {
+    *p++ = (char)(((wide_char >>  6)       ) | 0xC0);
+    *p++ = (char)(((wide_char      ) & 0x3F) | 0x80);
+  } else if (wide_char < 0x10000) {
+    *p++ = (char)(((wide_char >> 12)       ) | 0xE0);
+    *p++ = (char)(((wide_char >>  6) & 0x3F) | 0x80);
+    *p++ = (char)(((wide_char      ) & 0x3F) | 0x80);
+  } else {
+    *p++ = (char)(((wide_char >> 18)       ) | 0xF0);
+    *p++ = (char)(((wide_char >> 12) & 0x3F) | 0x80);
+    *p++ = (char)(((wide_char >>  6) & 0x3F) | 0x80);
+    *p++ = (char)(((wide_char      ) & 0x3F) | 0x80);
+  }
+  *p = 0;
 
-  wcrtomb (buf, wide_char, &state);
-  
   return scm_makfrom0str (buf);
 }
 	  
-- 
2.39.5