]> code.delx.au - gnu-emacs/commitdiff
* gtkutil.c (get_utf8_string): Try harder to convert to UTF8. Gtk+
authorJan Djärv <jan.h.d@swipnet.se>
Sat, 16 Sep 2006 17:18:03 +0000 (17:18 +0000)
committerJan Djärv <jan.h.d@swipnet.se>
Sat, 16 Sep 2006 17:18:03 +0000 (17:18 +0000)
 will simply crash if we fail.

src/ChangeLog
src/gtkutil.c

index f1c5996121b12168bac6537c26e0c6b4c90635cb..1a6f6edeb33d41dbfa5e7f1f36379f47a57d3543 100644 (file)
@@ -1,3 +1,8 @@
+2006-09-16  Jan Dj\e,Ad\e(Brv  <jan.h.d@swipnet.se>
+
+       * gtkutil.c (get_utf8_string): Try harder to convert to UTF8.  Gtk+
+       will simply crash if we fail.
+
 2006-09-16  Richard Stallman  <rms@gnu.org>
 
        * regex.c (re_compile_pattern): Set gl_state.current_syntax_table.
index cf6caafa942350b176f6ce9c1bc8b2511f1996d1..35c2cc0ba18b958105c85f3781656bcb2ac51f2d 100644 (file)
@@ -507,10 +507,66 @@ get_utf8_string (str)
 {
   char *utf8_str = str;
 
+  if (!str) return NULL;
+
   /* If not UTF-8, try current locale.  */
-  if (str && !g_utf8_validate (str, -1, NULL))
+  if (!g_utf8_validate (str, -1, NULL))
     utf8_str = g_locale_to_utf8 (str, -1, 0, 0, 0);
 
+  if (!utf8_str) 
+    {
+      /* Probably some control characters in str.  Escape them. */
+      size_t nr_bad = 0;
+      gsize bytes_read;
+      gsize bytes_written;
+      unsigned char *p = (unsigned char *)str;
+      char *cp, *up;
+      GError *error = NULL;
+
+      while (! (cp = g_locale_to_utf8 (p, -1, &bytes_read,
+                                             &bytes_written, &error))
+             && error->code == G_CONVERT_ERROR_ILLEGAL_SEQUENCE)
+        {
+          ++nr_bad;
+          p += bytes_written+1;
+          g_error_free (error);
+          error = NULL;
+        }
+
+      if (error) 
+        {
+          g_error_free (error);
+          error = NULL;
+        }
+      if (cp) g_free (cp);
+
+      up = utf8_str = xmalloc (strlen (str) + nr_bad * 4 + 1);
+      p = str;
+
+      while (! (cp = g_locale_to_utf8 (p, -1, &bytes_read,
+                                       &bytes_written, &error))
+             && error->code == G_CONVERT_ERROR_ILLEGAL_SEQUENCE)
+        {
+          strncpy (up, p, bytes_written);
+          sprintf (up + bytes_written, "\\%03o", p[bytes_written]);
+          up[bytes_written+4] = '\0';
+          up += bytes_written+4;
+          p += bytes_written+1;
+          g_error_free (error);
+          error = NULL;
+        }
+
+      if (cp) 
+        {
+          strcat (utf8_str, cp);
+          g_free (cp);
+        }
+      if (error) 
+        {
+          g_error_free (error);
+          error = NULL;
+        }
+    }
   return utf8_str;
 }