summaryrefslogtreecommitdiff
path: root/Build/source/texk/ptexenc/unicode.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/ptexenc/unicode.c')
-rw-r--r--Build/source/texk/ptexenc/unicode.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/Build/source/texk/ptexenc/unicode.c b/Build/source/texk/ptexenc/unicode.c
new file mode 100644
index 00000000000..2e723f6cd31
--- /dev/null
+++ b/Build/source/texk/ptexenc/unicode.c
@@ -0,0 +1,112 @@
+/*
+ unicode.c -- utilities for Unicode
+ written by N. Tsuchimura
+*/
+
+#include <ptexenc/c-auto.h>
+#include <ptexenc/unicode.h>
+#include <ptexenc/kanjicnv.h>
+
+#include <stdio.h> /* for fprintf() */
+
+/* determine if UTF-8 character or not */
+boolean isUTF8(int length, int nth, int c)
+{
+ c &= 0xff;
+ switch (length * 8 + nth) {
+ case 011: return (0x00 <= c && c < 0x80);
+ case 021: return (0xc2 <= c && c < 0xe0);
+ case 031: return (0xe0 <= c && c < 0xf0);
+ case 041: return (0xf0 <= c && c < 0xf5);
+ case 022:
+ case 032: case 033:
+ case 042: case 043: case 044:
+ return (0x80 <= c && c < 0xc0);
+ default:
+ fprintf(stderr, "isUTF8: unexpected param length=%d, nth=%d\n",
+ length, nth);
+ }
+ return false;
+}
+
+
+int UTF8length(int first_byte)
+{
+ if (first_byte < 0x00) return -2; /* illegal */
+ if (first_byte < 0x80) return 1;
+ if (first_byte < 0xc2) return -2; /* illegal */
+ if (first_byte < 0xe0) return 2;
+ if (first_byte < 0xf0) return 3;
+ if (first_byte < 0xf5) return 4;
+ return -1; /* reserved/undefined */
+}
+
+
+/* with strict range check */
+int UTF8Slength(string buff, int buff_len)
+{
+ int i, len;
+
+ len = UTF8length(buff[0]);
+ if (len < 0) return -2; /* illegal */
+ if (len > buff_len) return -3; /* overflow */
+ for (i=0; i<len; i++) {
+ if (!isUTF8(len, 1+i, buff[i])) return -1; /* not UTF-8 */
+ }
+ return len;
+}
+
+
+/* WITHOUT strict range check */
+long UTF8StoUCS(string s)
+{
+ switch (UTF8length(s[0])) {
+ case 1: return s[0];
+ case 2: return UTF8BtoUCS(s[0], s[1]);
+ case 3: return UTF8CtoUCS(s[0], s[1], s[2]);
+ case 4: return UTF8DtoUCS(s[0], s[1], s[2], s[3]);
+ default: return 0; /* error */
+ }
+}
+
+int UCStoUTF8S(long ucs, string s)
+{
+ if (ucs < 0x80) {
+ *s = ucs;
+ return 1;
+ } else if (ucs < 0x800) {
+ *s++ = UCStoUTF8B1(ucs);
+ *s++ = UCStoUTF8B2(ucs);
+ return 2;
+ } else if (ucs < 0xFFFF) {
+ *s++ = UCStoUTF8C1(ucs);
+ *s++ = UCStoUTF8C2(ucs);
+ *s++ = UCStoUTF8C3(ucs);
+ return 3;
+ } else if (ucs < 0x10FFFF) {
+ *s++ = UCStoUTF8D1(ucs);
+ *s++ = UCStoUTF8D2(ucs);
+ *s++ = UCStoUTF8D3(ucs);
+ *s++ = UCStoUTF8D4(ucs);
+ return 4;
+ }
+ return 0; /* unsupported */
+}
+
+
+long UCStoUTF8(long ucs)
+{
+ if (ucs < 0x80) return ucs;
+ if (ucs < 0x800) return LONG(0,0,
+ UCStoUTF8B1(ucs),
+ UCStoUTF8B2(ucs));
+ if (ucs < 0xFFFF) return LONG(0,
+ UCStoUTF8C1(ucs),
+ UCStoUTF8C2(ucs),
+ UCStoUTF8C3(ucs));
+ if (ucs < 0x10FFFF) return LONG(UCStoUTF8D1(ucs),
+ UCStoUTF8D2(ucs),
+ UCStoUTF8D3(ucs),
+ UCStoUTF8D4(ucs));
+ return 0; /* unsupported */
+}