chiark / gitweb /
*** empty log message ***
[sympathy.git] / src / utf8.c
index 18ca3ebeab5e647126a6801d7ae2e2c032e66e64..9d04d19925e756f3dc409a2fff4a2cc0174675c9 100644 (file)
@@ -10,6 +10,12 @@ static char rcsid[] = "$Id$";
 
 /*
  * $Log$
+ * Revision 1.3  2008/02/23 11:48:37  james
+ * *** empty log message ***
+ *
+ * Revision 1.2  2008/02/22 23:39:27  james
+ * *** empty log message ***
+ *
  * Revision 1.1  2008/02/22 19:12:05  james
  * *** empty log message ***
  *
@@ -18,21 +24,118 @@ static char rcsid[] = "$Id$";
 #include "project.h"
 
 
-  /*FIXME: for the moment we bodge utf8 support*/
-  if ((ch>=0xc0) && (ch<0xe0)) /*Start of two byte unicode sequence*/
-  {
-       p->in_utf8=2;
-  } else if ((ch>=0xe0) && (ch<0xf0)) /*Start of three byte unicode sequence*/
-  {
-       p->in_utf8=3;
-  } else if ((ch>=0xf0) && (ch<0xf7)) /*Start of four byte unicode sequence*/
-       p->in_utf8=4;
-  }
-
-  if (p->utf_8) {
-       p->in_utf8--;
-       ch='?';
-  }  
-
-  if (!p->utf_8)  {
-       /*Not first or last byte in sequence*/
+void
+utf8_flush (Context * c)
+{
+  UTF8 *u = c->u;
+  int i;
+
+  switch (u->utf_ptr)
+    {
+    case 1:
+      log_f (c->l, "%s:%d invalid utf-8 sequence: \\%03o",
+             __FILE__, __LINE__, u->utf_buf[0]);
+      break;
+    case 2:
+      log_f (c->l, "%s:%d invalid utf-8 sequence: \\%03o \\%03o",
+             __FILE__, __LINE__, u->utf_buf[0], u->utf_buf[1]);
+      break;
+    case 3:
+      log_f (c->l, "%s:%d invalid utf-8 sequence: \\%03o \\%03o \\%03o",
+             __FILE__, __LINE__, u->utf_buf[0], u->utf_buf[1], u->utf_buf[2]);
+      break;
+    case 4:
+      log_f (c->l,
+             "%s:%d invalid utf-8 sequence: \\%03o \\%03o \\%03o \\%03o",
+             __FILE__, __LINE__,
+             u->utf_buf[0], u->utf_buf[1], u->utf_buf[2], u->utf_buf[3]);
+      break;
+    }
+
+  for (i = 0; i < u->utf_ptr; ++i)
+    vt102_parse_char (c, u->utf_buf[i]);
+
+  u->utf_ptr = 0;
+  u->in_utf8 = 0;
+}
+
+void
+utf8_parse (Context * c, int ch)
+{
+  UTF8 *u = c->u;
+
+  if (ch == SYM_CHAR_RESET)
+    {
+      u->in_utf8 = 0;
+      vt102_parse_char (c, ch);
+      return;
+    }
+
+  if (!u->in_utf8)
+    {
+      /*FIXME: for the moment we bodge utf8 support */
+      if (ch == 0xb9)
+        {                       /*CSI, not a valid utf8 start char */
+          vt102_parse_char (c, ch);
+        }
+      else if ((ch & 0xe0) == 0xc0)
+        {                       /*Start of two byte unicode sequence */
+          u->in_utf8 = 1;
+          u->utf_ptr = 0;
+          u->utf_buf[u->utf_ptr++] = ch;
+          u->ch = (ch & 0x1f) << 6;
+          u->sh = 0;
+        }
+      else if ((ch & 0xf0) == 0xe0)
+        {                       /*Start of three byte unicode sequence */
+          u->in_utf8 = 2;
+          u->utf_ptr = 0;
+          u->utf_buf[u->utf_ptr++] = ch;
+          u->ch = (ch & 0x0f) << 12;
+          u->sh = 6;
+        }
+      else if ((ch & 0xf8) == 0xf0)
+        {
+          u->in_utf8 = 3;
+          u->utf_ptr = 0;
+          u->utf_buf[u->utf_ptr++] = ch;
+          u->ch = (ch & 0x07) << 18;
+          u->sh = 12;
+        }
+      else
+        {
+          vt102_parse_char (c, ch);
+        }
+    }
+  else
+    {
+      if ((ch & 0xc0) != 0x80)
+        {
+          utf8_flush (c);
+          vt102_parse_char (c, ch);
+        }
+      else
+        {
+          u->utf_buf[u->utf_ptr++] = ch;
+          u->ch |= (ch & 0x3f) << u->sh;
+          u->sh -= 6;
+          u->in_utf8--;
+
+          if (!u->in_utf8)
+            vt102_parse_char (c, ch);
+        }
+    }
+}
+
+
+
+UTF8 *
+utf8_new (void)
+{
+  UTF8 *ret;
+
+  ret = (UTF8 *) malloc (sizeof (UTF8));
+
+  ret->in_utf8 = 0;
+
+}