summaryrefslogtreecommitdiffabout
path: root/src
authorSergey Poznyakoff <gray@gnu.org.ua>2011-06-04 10:27:59 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2011-06-04 10:27:59 (GMT)
commitceb837f01112d2cfde96ba9e6ddc9c9ccbd0d0a4 (patch) (side-by-side diff)
tree316933c27051392c5cd48b873ae0697cd389d52a /src
parent99076de629a6f5f2b654118cde3612f9ba05edf0 (diff)
downloadellinika-ceb837f01112d2cfde96ba9e6ddc9c9ccbd0d0a4.tar.gz
ellinika-ceb837f01112d2cfde96ba9e6ddc9c9ccbd0d0a4.tar.bz2
Implement new morphological functions. Move elmorph to scm/ellinika
git-svn-id: file:///home/puszcza/svnroot/ellinika/trunk@554 941c8c0f-9102-463b-b60b-cd22ce0e6858
Diffstat (limited to 'src') (more/less context) (ignore whitespace changes)
-rw-r--r--src/ellinika/Makefile.am44
-rw-r--r--src/ellinika/aorist.c73
-rw-r--r--src/ellinika/elchr.c701
-rw-r--r--src/ellinika/elmorph.c655
-rw-r--r--src/ellinika/elmorph.h46
-rw-r--r--src/ellinika/elmorph.scm45
-rw-r--r--src/ellinika/utf8.c2149
-rw-r--r--src/ellinika/utf8.h71
8 files changed, 3742 insertions, 2 deletions
diff --git a/src/ellinika/Makefile.am b/src/ellinika/Makefile.am
index 136b44f..274eea8 100644
--- a/src/ellinika/Makefile.am
+++ b/src/ellinika/Makefile.am
@@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
guiledir=$(GUILE_SITE)/$(PACKAGE)
-guile_DATA=xlat.scm cgi.scm i18n.scm config.scm dico.scm
+guile_DATA=xlat.scm cgi.scm i18n.scm config.scm dico.scm elmorph.scm
cgi.m4: Makefile
echo 'divert(-1)' > $@
@@ -31,13 +31,53 @@ cgi.m4: Makefile
echo 'define([SYSCONFDIR],$(sysconfdir))' >> $@
echo 'define([LOCALEDIR],$(datadir)/locale)' >> $@
echo 'define([HTMLDIR],$(HTMLDIR))' >> $@
+ echo 'define([VERSION],$(VERSION))' >> $@
+ echo 'define([LIBDIR],$(pkglibdir))' >> $@
echo 'divert(0)dnl' >> $@
echo '@AUTOGENERATED@' >> $@
-SUFFIXES = .scm4 .scm
+SUFFIXES = .scm4 .scm .x
.scm4.scm:
m4 cgi.m4 $< > $@
cgi.scm: cgi.scm4 cgi.m4
config.scm: config.scm4 cgi.m4
+elmorph.scm: elmorph.scm4 cgi.m4
+
+pkglib_LTLIBRARIES=libelmorph.la
+
+libelmorph_la_SOURCES = \
+ aorist.c\
+ utf8.c\
+ elchr.c\
+ elmorph.c\
+ elmorph.h
+
+DOT_X_FILES = elmorph.x
+
+BUILT_SOURCES = $(DOT_X_FILES)
+
+DISTCLEANFILES = $(DOT_X_FILES)
+
+snarfcppopts = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+
+.c.x:
+ AWK=$(AWK) \
+ guile-snarf -o $@ $< $(snarfcppopts)
+
+pkglibnames=elmorph
+
+install-data-hook:
+ here=`pwd`; \
+ cd $(DESTDIR)$(pkglibdir);\
+ for name in $(pkglibnames); do \
+ if test -f lib$$name.la; then \
+ dlname=`sed -n 's/dlname='\''\(.*\)'\''/\1/p' lib$$name.la`; \
+ test -z "$$dlname" && dlname='lib$$name.so'; \
+ $(LN_S) -f "$$dlname" libguile-$$name-v-$(VERSION).so; \
+ fi; \
+ done; \
+ cd $$here
+
+
diff --git a/src/ellinika/aorist.c b/src/ellinika/aorist.c
new file mode 100644
index 0000000..995fce8
--- a/dev/null
+++ b/src/ellinika/aorist.c
@@ -0,0 +1,73 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <errno.h>
+#include <stdlib.h>
+#include <libguile.h>
+#include "utf8.h"
+#include "elmorph.h"
+
+int
+elmorph_thema_aoristoy(unsigned *word, size_t len,
+ unsigned **thema, size_t *tlen)
+{
+ unsigned ch, *pw;
+
+ switch (word[len-1]) {
+ case 0x03B6: /* ζ */
+ /* FIXME: This can produce ξ as well: αλλάζω => άλλαξα */
+ case 0x03B8: /* θ */
+ ch = 0x03C3; /* σ */
+ break;
+
+ case 0x03B3: /* γ */
+ case 0x03C7: /* χ */
+ ch = 0x03BE; /* ξ */
+ break;
+
+ case 0x03BA: /* κ */
+ if (len > 1 && word[len-2] == 0x03C3 /* σκ */)
+ len--;
+ ch = 0x03BE; /* ξ */
+ break;
+
+ case 0x03BD: /* ν */
+ if (len > 1 && word[len-2] == 0x03C7 /* χν */) {
+ len--;
+ ch = 0x03BE; /* ξ */
+ } else
+ ch = 0x03C3; /* σ */
+ break;
+
+ case 0x03B2: /* β */
+ case 0x03C0: /* π */
+ case 0x03C6: /* φ */
+ ch = 0x03C8; /* ψ */
+ break;
+
+ case 0x03CD: /* ύ */
+ case 0x03C5: /* υ FIXME: This assumes the word has been deaccentized */
+ if (len > 1 && (word[len-2] == 0x03B1 /* αύ */ ||
+ word[len-2] == 0x03B5 /* εύ */)) {
+ ch = 0x03C8; /* ψ */
+ break;
+ }
+
+ default:
+ len++;
+ ch = 0x03C3; /* σ */
+ }
+
+ pw = calloc(len, sizeof(pw[0]));
+ if (!pw)
+ return -1;
+ memcpy(pw, word, sizeof(word[0]) * (len - 1));
+ pw[len-1] = ch;
+
+ *thema = pw;
+ *tlen = len;
+ return 0;
+}
+
+
+
diff --git a/src/ellinika/elchr.c b/src/ellinika/elchr.c
new file mode 100644
index 0000000..9b4e7ad
--- a/dev/null
+++ b/src/ellinika/elchr.c
@@ -0,0 +1,701 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <errno.h>
+#include <stdlib.h>
+#include <libguile.h>
+#include "utf8.h"
+#include "elmorph.h"
+
+struct char_info_st {
+ unsigned ch; /* Characters */
+ int flags; /* Flags (see above) */
+ unsigned base; /* for vowels - a corresponding vowel with all diacritics
+ removed */
+ unsigned trans; /* a counter-case equivalent, i.e. a corresponding uppercase
+ letter if flags & CHF_LOWER and a corresponding lowerrcase
+ letter if flags & CHF_UPPER */
+ unsigned numval; /* Numeric value */
+ unsigned accented[3]; /* For vowels - corresponding accented variant */
+ unsigned deaccent; /* For accented vowels with diaeresis - corresponding
+ non-accented character */
+};
+
+/* See http://www.unicode.org/charts/PDF/Unicode-5.1/U51-0370.pdf */
+struct char_info_st el_basic_ctype[] = {
+ { 0x0300, },
+ { 0x0301, },
+ { 0x0302, },
+ { 0x0303, },
+ { 0x0304, },
+ { 0x0305, },
+ { 0x0306, },
+ { 0x0307, },
+ { 0x0308, },
+ { 0x0309, },
+ { 0x030A, },
+ { 0x030B, },
+ { 0x030C, },
+ { 0x030D, },
+ { 0x030E, },
+ { 0x030F, },
+ { 0x0310, },
+ { 0x0311, },
+ { 0x0312, },
+ { 0x0313, },
+ { 0x0314, },
+ { 0x0315, },
+ { 0x0316, },
+ { 0x0317, },
+ { 0x0318, },
+ { 0x0319, },
+ { 0x031A, },
+ { 0x031B, },
+ { 0x031C, },
+ { 0x031D, },
+ { 0x031E, },
+ { 0x031F, },
+ { 0x0320, },
+ { 0x0321, },
+ { 0x0322, },
+ { 0x0323, },
+ { 0x0324, },
+ { 0x0325, },
+ { 0x0326, },
+ { 0x0327, },
+ { 0x0328, },
+ { 0x0329, },
+ { 0x032A, },
+ { 0x032B, },
+ { 0x032C, },
+ { 0x032D, },
+ { 0x032E, },
+ { 0x032F, },
+ { 0x0330, },
+ { 0x0331, },
+ { 0x0332, },
+ { 0x0333, },
+ { 0x0334, },
+ { 0x0335, },
+ { 0x0336, },
+ { 0x0337, },
+ { 0x0338, },
+ { 0x0339, },
+ { 0x033A, },
+ { 0x033B, },
+ { 0x033C, },
+ { 0x033D, },
+ { 0x033E, },
+ { 0x033F, },
+ { 0x0340, },
+ { 0x0341, },
+ { 0x0342, },
+ { 0x0343, },
+ { 0x0344, },
+ { 0x0345, },
+ { 0x0346, },
+ { 0x0347, },
+ { 0x0348, },
+ { 0x0349, },
+ { 0x034A, },
+ { 0x034B, },
+ { 0x034C, },
+ { 0x034D, },
+ { 0x034E, },
+ { 0x034F, },
+ { 0x0350, },
+ { 0x0351, },
+ { 0x0352, },
+ { 0x0353, },
+ { 0x0354, },
+ { 0x0355, },
+ { 0x0356, },
+ { 0x0357, },
+ { 0x0358, },
+ { 0x0359, },
+ { 0x035A, },
+ { 0x035B, },
+ { 0x035C, },
+ { 0x035D, },
+ { 0x035E, },
+ { 0x035F, },
+ { 0x0360, },
+ { 0x0361, },
+ { 0x0362, },
+ { 0x0363, },
+ { 0x0364, },
+ { 0x0365, },
+ { 0x0366, },
+ { 0x0367, },
+ { 0x0368, },
+ { 0x0369, },
+ { 0x036A, },
+ { 0x036B, },
+ { 0x036C, },
+ { 0x036D, },
+ { 0x036E, },
+ { 0x036F, },
+ { 0x0370, CHF_ARCHAIC|CHF_CONSONANT|CHF_UPPER, 0, 0x0371 }, /* CAPITAL HETTA */
+ { 0x0371, CHF_ARCHAIC|CHF_CONSONANT|CHF_LOWER, 0, 0x0370 }, /* SMALL HETA */
+ { 0x0372, CHF_ARCHAIC|CHF_CONSONANT|CHF_UPPER, 0, 0x0373 }, /* CAPITAL SAMPI */
+ { 0x0373, CHF_ARCHAIC|CHF_CONSONANT|CHF_LOWER, 0, 0x0372 }, /* SMALL SAMPI */
+ { 0x0374, CHF_MODIFIER|CHF_UPPER, 0, 0x0375 }, /* NUMERAL SIGN = dexia keraia */
+ { 0x0375, CHF_MODIFIER|CHF_LOWER, 0, 0x0374 }, /* aristeri keraia */
+ { 0x0376, CHF_ARCHAIC|CHF_SEMIVOWEL|CHF_UPPER, 0, 0x0377}, /* CAPITAL PAMPHYLIAN DIGAMMA */
+ { 0x0377, CHF_ARCHAIC|CHF_SEMIVOWEL|CHF_LOWER, 0, 0x0376}, /* SMALL PAMPHYLIAN DIGAMMA */
+ { 0x0378, },
+ { 0x0379, },
+ { 0x037A, CHF_ARCHAIC|CHF_MODIFIER }, /* YPOGEGRAMMENI */
+ { 0x037B, CHF_SYMBOL, 0, 0x03FD }, /* SMALL REVERSED LUNATE SIGMA */
+ { 0x037C, CHF_SYMBOL, 0, 0x03FE }, /* SMALL DOTTED LUNATE SIGMA */
+ { 0x037D, CHF_SYMBOL, 0, 0x03FF }, /* SMALL REVERSED DOTTED LUNATE SIGMA */
+ { 0x037E, CHF_PUNCT }, /* erotimatiko */
+ { 0x037F, },
+ { 0x0380, },
+ { 0x0381, },
+ { 0x0382, },
+ { 0x0383, },
+ { 0x0384, CHF_MODIFIER }, /* Oxeia */
+ { 0x0385, CHF_MODIFIER }, /* dialytika */
+ { 0x0386, CHF_VOWEL|CHF_UPPER|CHF_OXEIA, 0x0391, 0x03AC }, /* Ά */
+ { 0x0387, CHF_PUNCT }, /* ano teleia */
+ { 0x0388, CHF_VOWEL|CHF_UPPER|CHF_OXEIA, 0x0395, 0x03AD }, /* Έ */
+ { 0x0389, CHF_VOWEL|CHF_UPPER|CHF_OXEIA|CHF_DIPH2, 0x0397, 0x03AE }, /* Ή */
+ { 0x038A, CHF_VOWEL|CHF_UPPER|CHF_OXEIA|CHF_DIPH2, 0x0399, 0x03AF }, /* Ί */
+ { 0x038B, },
+ { 0x038C, CHF_VOWEL|CHF_UPPER|CHF_OXEIA, 0x039F, 0x03CC }, /* Ό */
+ { 0x038D, },
+ { 0x038E, CHF_VOWEL|CHF_UPPER|CHF_OXEIA|CHF_DIPH2, 0x03A5, 0x03CD }, /* Ύ */
+ { 0x038F, CHF_VOWEL|CHF_UPPER|CHF_OXEIA, 0x03A9, 0x03CE }, /* Ώ */
+ { 0x0390, CHF_VOWEL|CHF_LOWER|CHF_TREMA|CHF_OXEIA, 0x03B9, 0, 0, 0, 0, 0x03CA }, /* ΐ */
+ { 0x0391, CHF_VOWEL|CHF_UPPER|CHF_NUMERIC|CHF_DIPH1, 0, 0x03B1, 1, 0x0386 }, /* Α */
+ { 0x0392, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03B2, 2 }, /* Β */
+ { 0x0393, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03B3, 3 }, /* Γ */
+ { 0x0394, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03B4, 4 }, /* Δ */
+ { 0x0395, CHF_VOWEL|CHF_UPPER|CHF_NUMERIC|CHF_DIPH1, 0, 0x03B5, 5, 0x0388 }, /* Ε */
+ { 0x0396, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03B6, 7 }, /* Ζ */
+ { 0x0397, CHF_VOWEL|CHF_UPPER|CHF_NUMERIC, 0, 0x03B7, 8, 0x0389 }, /* Η */
+ { 0x0398, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03B8, 9 }, /* Θ */
+ { 0x0399, CHF_VOWEL|CHF_UPPER|CHF_NUMERIC|CHF_DIPH2, 0, 0x03B9, 10, 0x038A }, /* Ι */
+ { 0x039A, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03BA, 20 }, /* Κ */
+ { 0x039B, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03BB, 30 }, /* Λ */
+ { 0x039C, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03BC, 40 }, /* Μ */
+ { 0x039D, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03BD, 50 }, /* Ν */
+ { 0x039E, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03BE, 60 }, /* Ξ */
+ { 0x039F, CHF_VOWEL|CHF_UPPER|CHF_NUMERIC, 0, 0x03BF, 70, 0x038C }, /* Ο */
+ { 0x03A0, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03C0, 80 }, /* Π */
+ { 0x03A1, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03C1, 100 }, /* Ρ */
+ { 0x03A2, },
+ { 0x03A3, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03C3, 200 }, /* Σ */
+ { 0x03A4, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03C4, 300 }, /* Τ */
+ { 0x03A5, CHF_VOWEL|CHF_UPPER|CHF_NUMERIC|CHF_DIPH1|CHF_DIPH2, 0, 0x03C5, 400, 0x038E }, /* Υ */
+ { 0x03A6, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03C6, 500 }, /* Φ */
+ { 0x03A7, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03C7, 600 }, /* Χ */
+ { 0x03A8, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03C8, 700 }, /* Ψ */
+ { 0x03A9, CHF_VOWEL|CHF_UPPER|CHF_NUMERIC, 0, 0x03C9, 800, 0x038F }, /* Ω */
+ { 0x03AA, CHF_VOWEL|CHF_UPPER|CHF_TREMA|CHF_DIPH2, 0x0399, 0x03CA }, /* Ϊ */
+ { 0x03AB, CHF_VOWEL|CHF_UPPER|CHF_TREMA, 0x03A5, 0x03CB }, /* Ϋ */
+ { 0x03AC, CHF_VOWEL|CHF_LOWER|CHF_OXEIA, 0x03B1, 0x0386 }, /* ά */
+ { 0x03AD, CHF_VOWEL|CHF_LOWER|CHF_OXEIA, 0x03B4, 0x0388 }, /* έ */
+ { 0x03AE, CHF_VOWEL|CHF_LOWER|CHF_OXEIA|CHF_DIPH2, 0x03B7, 0x0389 }, /* ή */
+ { 0x03AF, CHF_VOWEL|CHF_LOWER|CHF_OXEIA|CHF_DIPH2, 0x03B9, 0x038A }, /* ί */
+ { 0x03B0, CHF_VOWEL|CHF_OXEIA|CHF_TREMA, 0x03C5, 0, 0, 0, 0, 0x03CB }, /* ΰ */
+ { 0x03B1, CHF_VOWEL|CHF_LOWER|CHF_NUMERIC|CHF_DIPH1, 0, 0x0391, 1, 0x03AC }, /* α */
+ { 0x03B2, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x0392, 2 }, /* β */
+ { 0x03B3, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x0393, 3 }, /* γ */
+ { 0x03B4, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x0394, 4 }, /* δ */
+ { 0x03B5, CHF_CONSONANT|CHF_VOWEL|CHF_LOWER|CHF_NUMERIC|CHF_DIPH1, 0, 0x0395, 5, 0x03AD }, /* ε */
+ { 0x03B6, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x0396, 7 }, /* ζ */
+ { 0x03B7, CHF_VOWEL|CHF_LOWER|CHF_NUMERIC|CHF_DIPH1|CHF_DIPH2, 0, 0x0397, 8, 0x03AE }, /* η */
+ { 0x03B8, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x0398, 9 }, /* θ */
+ { 0x03B9, CHF_VOWEL|CHF_LOWER|CHF_NUMERIC, 0, 0x0399, 10, 0x03AF }, /* ι */
+ { 0x03BA, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x039A, 20 }, /* κ */
+ { 0x03BB, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x039B, 30 }, /* λ */
+ { 0x03BC, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x039C, 40 }, /* μ */
+ { 0x03BD, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x039D, 50 }, /* ν */
+ { 0x03BE, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x039E, 60 }, /* ξ */
+
+ { 0x03BF, CHF_VOWEL|CHF_LOWER|CHF_NUMERIC, 0, 0x039F, 70, 0x03CC }, /* ο */
+ { 0x03C0, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x03A0, 80 }, /* π */
+ { 0x03C1, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x03A1, 100 }, /* ρ */
+ { 0x03C2, CHF_CONSONANT|CHF_LOWER, 0, 0x03A3 }, /* ς */
+ { 0x03C3, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x03A3, 200 }, /* σ */
+ { 0x03C4, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x03A4, 300 }, /* τ */
+ { 0x03C5, CHF_VOWEL|CHF_LOWER|CHF_NUMERIC|CHF_DIPH2, 0, 0x03A5, 400, 0x03CD }, /* υ */
+ { 0x03C6, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x03A6, 500 }, /* φ */
+ { 0x03C7, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x03A7, 600 }, /* χ */
+ { 0x03C8, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x03A8, 700 }, /* ψ */
+ { 0x03C9, CHF_VOWEL|CHF_LOWER|CHF_NUMERIC, 0, 0x03A9, 800, 0x03CE }, /* ω */
+ { 0x03CA, CHF_VOWEL|CHF_LOWER|CHF_TREMA|CHF_DIPH2, 0x03B9, 0x03AA, 0, 0x0390 }, /* ϊ */
+ { 0x03CB, CHF_VOWEL|CHF_LOWER|CHF_TREMA, 0x03C5, 0x03AB, 0, 0x03B0 }, /* ϋ */
+ { 0x03CC, CHF_VOWEL|CHF_LOWER|CHF_OXEIA, 0x03BF, 0x038C }, /* ό */
+ { 0x03CD, CHF_VOWEL|CHF_LOWER|CHF_OXEIA|CHF_DIPH2, 0x03C5, 0x038E }, /* ύ */
+ { 0x03CE, CHF_VOWEL|CHF_LOWER|CHF_OXEIA, 0x03CE, 0x038F }, /* ώ */
+ { 0x03CF, CHF_SYMBOL|CHF_UPPER, 0x03D7 }, /* KAI */
+ { 0x03D0, CHF_CONSONANT|CHF_LOWER, 0, 0x0392 }, /* curled beta */
+ { 0x03D1, CHF_CONSONANT|CHF_LOWER, 0, 0x0398 }, /* script theta */
+ { 0x03D2, CHF_VOWEL|CHF_UPPER, }, /* capital ypsilon with hook */
+ { 0x03D3, CHF_VOWEL|CHF_OXEIA, 0x03D2 }, /* capital ypsilon with acute & hook */
+ { 0x03D4, CHF_VOWEL|CHF_TREMA, 0x03D2 }, /* capital ypsilon with diaeresis & hook */
+ { 0x03D5, CHF_CONSONANT|CHF_LOWER, 0, 0x03A6 }, /* phi */
+ { 0x03D6, CHF_CONSONANT|CHF_LOWER, 0, 0x03A0 }, /* pi */
+ { 0x03D7, CHF_SYMBOL|CHF_LOWER, 0, 0x03CF }, /* kai */
+ { 0x03D8, CHF_ARCHAIC|CHF_CONSONANT|CHF_UPPER, 0, 0x03D9 }, /* QOPPA */
+ { 0x03D9, CHF_ARCHAIC|CHF_CONSONANT|CHF_LOWER, 0, 0x03D8 }, /* qoppa */
+ { 0x03DA, CHF_ARCHAIC|CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03DB, 6 }, /* STIGMA */
+ { 0x03DB, CHF_ARCHAIC|CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x03DA, 6 }, /* stigma */
+ { 0x03DC, CHF_ARCHAIC|CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03DD, 6 }, /* DIGAMMA */
+ { 0x03DD, CHF_ARCHAIC|CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x03DC, 6 }, /* digamma */
+ { 0x03DE, CHF_ARCHAIC|CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03DF, 6 }, /* KOPPA */
+ { 0x03DF, CHF_ARCHAIC|CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x03DE, 6 }, /* koppa */
+ { 0x03E0, CHF_ARCHAIC|CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03E1, 900 }, /* SAMPI */
+ { 0x03E1, CHF_ARCHAIC|CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x03E0, 900 }, /* sampi */
+ { 0x03E2, },
+ { 0x03E3, },
+ { 0x03E4, },
+ { 0x03E5, },
+ { 0x03E6, },
+ { 0x03E7, },
+ { 0x03E8, },
+ { 0x03E9, },
+ { 0x03EA, },
+ { 0x03EB, },
+ { 0x03EC, },
+ { 0x03ED, },
+ { 0x03EE, },
+ { 0x03EF, },
+ { 0x03F0, CHF_CONSONANT|CHF_LOWER, 0, 0x039A }, /* kappa */
+ { 0x03F1, CHF_CONSONANT|CHF_LOWER, 0, 0x03A1 }, /* tailed rho */
+ { 0x03F2, CHF_CONSONANT, 0, 0x03F9 }, /* lunate sigma */
+ { 0x03F3, CHF_SEMIVOWEL|CHF_LOWER, }, /* yot */
+ { 0x03F4, CHF_CONSONANT|CHF_UPPER, 0, 0x03B8 }, /* THETA */
+ { 0x03F5, CHF_SYMBOL|CHF_LOWER, 0, 0x0395 }, /* lunate epsilon */
+ { 0x03F6, CHF_SYMBOL|CHF_LOWER, }, /* reversed lunate epsilon */
+ { 0x03F7, },
+ { 0x03F8, },
+ { 0x03F9, CHF_CONSONANT|CHF_UPPER, 0, 0x03F2 }, /* LUNATE SIGMA */
+ { 0x03FA, CHF_ARCHAIC|CHF_CONSONANT|CHF_UPPER, 0, 0x03FB }, /* SAN */
+ { 0x03FB, CHF_ARCHAIC|CHF_CONSONANT|CHF_LOWER, 0, 0x03FA }, /* san */
+ { 0x03FC, CHF_SYMBOL|CHF_CONSONANT|CHF_LOWER, }, /* rho with stroke */
+ { 0x03FD, CHF_SYMBOL|CHF_CONSONANT|CHF_UPPER, 0, 0x037B}, /* CAPITAL REV. LUNATE SIGMA
+ antisigma */
+ { 0x03FE, CHF_SYMBOL|CHF_CONSONANT|CHF_UPPER, 0, 0x037C }, /* CAPITAL DOTTED LUNATE SIGMA
+ sigma periestigmenon */
+ { 0x03FF, CHF_SYMBOL|CHF_CONSONANT|CHF_UPPER, 0, 0x037D }, /* antisigma periestigmenon */
+};
+
+/* FIXME: Implement http://www.unicode.org/charts/PDF/U1F00.pdf */
+struct char_info_st el_extended_ctype[] = {
+ { 0x1F00, },
+ { 0x1F01, },
+ { 0x1F02, },
+ { 0x1F03, },
+ { 0x1F04, },
+ { 0x1F05, },
+ { 0x1F06, },
+ { 0x1F07, },
+ { 0x1F08, },
+ { 0x1F09, },
+ { 0x1F0A, },
+ { 0x1F0B, },
+ { 0x1F0C, },
+ { 0x1F0D, },
+ { 0x1F0E, },
+ { 0x1F0F, },
+ { 0x1F10, },
+ { 0x1F11, },
+ { 0x1F12, },
+ { 0x1F13, },
+ { 0x1F14, },
+ { 0x1F15, },
+ { 0x1F16, },
+ { 0x1F17, },
+ { 0x1F18, },
+ { 0x1F19, },
+ { 0x1F1A, },
+ { 0x1F1B, },
+ { 0x1F1C, },
+ { 0x1F1D, },
+ { 0x1F1E, },
+ { 0x1F1F, },
+ { 0x1F20, },
+ { 0x1F21, },
+ { 0x1F22, },
+ { 0x1F23, },
+ { 0x1F24, },
+ { 0x1F25, },
+ { 0x1F26, },
+ { 0x1F27, },
+ { 0x1F28, },
+ { 0x1F29, },
+ { 0x1F2A, },
+ { 0x1F2B, },
+ { 0x1F2C, },
+ { 0x1F2D, },
+ { 0x1F2E, },
+ { 0x1F2F, },
+ { 0x1F30, },
+ { 0x1F31, },
+ { 0x1F32, },
+ { 0x1F33, },
+ { 0x1F34, },
+ { 0x1F35, },
+ { 0x1F36, },
+ { 0x1F37, },
+ { 0x1F38, },
+ { 0x1F39, },
+ { 0x1F3A, },
+ { 0x1F3B, },
+ { 0x1F3C, },
+ { 0x1F3D, },
+ { 0x1F3E, },
+ { 0x1F3F, },
+ { 0x1F40, },
+ { 0x1F41, },
+ { 0x1F42, },
+ { 0x1F43, },
+ { 0x1F44, },
+ { 0x1F45, },
+ { 0x1F46, },
+ { 0x1F47, },
+ { 0x1F48, },
+ { 0x1F49, },
+ { 0x1F4A, },
+ { 0x1F4B, },
+ { 0x1F4C, },
+ { 0x1F4D, },
+ { 0x1F4E, },
+ { 0x1F4F, },
+ { 0x1F50, },
+ { 0x1F51, },
+ { 0x1F52, },
+ { 0x1F53, },
+ { 0x1F54, },
+ { 0x1F55, },
+ { 0x1F56, },
+ { 0x1F57, },
+ { 0x1F58, },
+ { 0x1F59, },
+ { 0x1F5A, },
+ { 0x1F5B, },
+ { 0x1F5C, },
+ { 0x1F5D, },
+ { 0x1F5E, },
+ { 0x1F5F, },
+ { 0x1F60, },
+ { 0x1F61, },
+ { 0x1F62, },
+ { 0x1F63, },
+ { 0x1F64, },
+ { 0x1F65, },
+ { 0x1F66, },
+ { 0x1F67, },
+ { 0x1F68, },
+ { 0x1F69, },
+ { 0x1F6A, },
+ { 0x1F6B, },
+ { 0x1F6C, },
+ { 0x1F6D, },
+ { 0x1F6E, },
+ { 0x1F6F, },
+ { 0x1F70, },
+ { 0x1F71, },
+ { 0x1F72, },
+ { 0x1F73, },
+ { 0x1F74, },
+ { 0x1F75, },
+ { 0x1F76, },
+ { 0x1F77, },
+ { 0x1F78, },
+ { 0x1F79, },
+ { 0x1F7A, },
+ { 0x1F7B, },
+ { 0x1F7C, },
+ { 0x1F7D, },
+ { 0x1F7E, },
+ { 0x1F7F, },
+ { 0x1F80, },
+ { 0x1F81, },
+ { 0x1F82, },
+ { 0x1F83, },
+ { 0x1F84, },
+ { 0x1F85, },
+ { 0x1F86, },
+ { 0x1F87, },
+ { 0x1F88, },
+ { 0x1F89, },
+ { 0x1F8A, },
+ { 0x1F8B, },
+ { 0x1F8C, },
+ { 0x1F8D, },
+ { 0x1F8E, },
+ { 0x1F8F, },
+ { 0x1F90, },
+ { 0x1F91, },
+ { 0x1F92, },
+ { 0x1F93, },
+ { 0x1F94, },
+ { 0x1F95, },
+ { 0x1F96, },
+ { 0x1F97, },
+ { 0x1F98, },
+ { 0x1F99, },
+ { 0x1F9A, },
+ { 0x1F9B, },
+ { 0x1F9C, },
+ { 0x1F9D, },
+ { 0x1F9E, },
+ { 0x1F9F, },
+ { 0x1FA0, },
+ { 0x1FA1, },
+ { 0x1FA2, },
+ { 0x1FA3, },
+ { 0x1FA4, },
+ { 0x1FA5, },
+ { 0x1FA6, },
+ { 0x1FA7, },
+ { 0x1FA8, },
+ { 0x1FA9, },
+ { 0x1FAA, },
+ { 0x1FAB, },
+ { 0x1FAC, },
+ { 0x1FAD, },
+ { 0x1FAE, },
+ { 0x1FAF, },
+ { 0x1FB0, },
+ { 0x1FB1, },
+ { 0x1FB2, },
+ { 0x1FB3, },
+ { 0x1FB4, },
+ { 0x1FB5, },
+ { 0x1FB6, },
+ { 0x1FB7, },
+ { 0x1FB8, },
+ { 0x1FB9, },
+ { 0x1FBA, },
+ { 0x1FBB, },
+ { 0x1FBC, },
+ { 0x1FBD, },
+ { 0x1FBE, },
+ { 0x1FBF, },
+ { 0x1FC0, },
+ { 0x1FC1, },
+ { 0x1FC2, },
+ { 0x1FC3, },
+ { 0x1FC4, },
+ { 0x1FC5, },
+ { 0x1FC6, },
+ { 0x1FC7, },
+ { 0x1FC8, },
+ { 0x1FC9, },
+ { 0x1FCA, },
+ { 0x1FCB, },
+ { 0x1FCC, },
+ { 0x1FCD, },
+ { 0x1FCE, },
+ { 0x1FCF, },
+ { 0x1FD0, },
+ { 0x1FD1, },
+ { 0x1FD2, },
+ { 0x1FD3, },
+ { 0x1FD4, },
+ { 0x1FD5, },
+ { 0x1FD6, },
+ { 0x1FD7, },
+ { 0x1FD8, },
+ { 0x1FD9, },
+ { 0x1FDA, },
+ { 0x1FDB, },
+ { 0x1FDC, },
+ { 0x1FDD, },
+ { 0x1FDE, },
+ { 0x1FDF, },
+ { 0x1FE0, },
+ { 0x1FE1, },
+ { 0x1FE2, },
+ { 0x1FE3, },
+ { 0x1FE4, },
+ { 0x1FE5, },
+ { 0x1FE6, },
+ { 0x1FE7, },
+ { 0x1FE8, },
+ { 0x1FE9, },
+ { 0x1FEA, },
+ { 0x1FEB, },
+ { 0x1FEC, },
+ { 0x1FED, },
+ { 0x1FEE, },
+ { 0x1FEF, },
+ { 0x1FF0, },
+ { 0x1FF1, },
+ { 0x1FF2, },
+ { 0x1FF3, },
+ { 0x1FF4, },
+ { 0x1FF5, },
+ { 0x1FF6, },
+ { 0x1FF7, },
+ { 0x1FF8, },
+ { 0x1FF9, },
+ { 0x1FFA, },
+ { 0x1FFB, },
+ { 0x1FFC, },
+ { 0x1FFD, },
+ { 0x1FFE, },
+ { 0x1FFF, }
+};
+
+static struct char_info_st *
+elchr_info(unsigned ch)
+{
+ if (ch >= 0x0300 && ch <= 0x03FF)
+ return el_basic_ctype + ch - 0x0300;
+ else if (ch >= 0x1F00 && ch <= 0x1FFF)
+ return el_extended_ctype + ch - 0x1F00;
+ return NULL;
+}
+
+int
+elchr_flags(unsigned ch)
+{
+ struct char_info_st *ci = elchr_info(ch);
+ return ci ? ci->flags : 0;
+}
+
+int
+elchr_isupper(unsigned ch)
+{
+ return elchr_flags(ch) & CHF_UPPER;
+}
+
+int
+elchr_islower(unsigned ch)
+{
+ return elchr_flags(ch) & CHF_LOWER;
+}
+
+int
+elchr_getaccent(unsigned ch)
+{
+ return elchr_flags(ch) & CHF_ACCENT_MASK;
+}
+
+int
+elchr_istrema(unsigned ch)
+{
+ return elchr_flags(ch) & CHF_TREMA;
+}
+
+
+int
+elchr_isvowel(unsigned ch)
+{
+ return elchr_flags(ch) & CHF_VOWEL;
+}
+
+int
+elchr_isconsonant(unsigned ch)
+{
+ return elchr_flags(ch) & CHF_CONSONANT;
+}
+
+int
+elchr_issemivowel(unsigned ch)
+{
+ return elchr_flags(ch) & CHF_SEMIVOWEL;
+}
+
+int
+elchr_ispunct(unsigned ch)
+{
+ return elchr_flags(ch) & CHF_PUNCT;
+}
+
+int
+elchr_issymbol(unsigned ch)
+{
+ return elchr_flags(ch) & CHF_SYMBOL;
+}
+
+int
+elchr_ismodifier(unsigned ch)
+{
+ return elchr_flags(ch) & CHF_MODIFIER;
+}
+
+int
+elchr_isarchaic(unsigned ch)
+{
+ return elchr_flags(ch) & CHF_ARCHAIC;
+}
+
+int
+elchr_isnumeric(unsigned ch)
+{
+ return elchr_flags(ch) & CHF_NUMERIC;
+}
+
+unsigned
+elchr_numeric_value(unsigned ch)
+{
+ struct char_info_st *ci = elchr_info(ch);
+ return (ci && (ci->flags & CHF_NUMERIC)) ? ci->numval: 0;
+}
+
+unsigned
+elchr_toupper(unsigned ch)
+{
+ struct char_info_st *ci = elchr_info(ch);
+ return (ci && (ci->flags & CHF_LOWER)) ? ci->trans: ch;
+}
+
+unsigned
+elchr_tolower(unsigned ch)
+{
+ struct char_info_st *ci = elchr_info(ch);
+ return (ci && (ci->flags & CHF_UPPER)) ? ci->trans : ch;
+}
+
+unsigned
+elchr_base(unsigned ch)
+{
+ struct char_info_st *ci = elchr_info(ch);
+ return (ci && (ci->flags & CHF_ACCENT_MASK) && ci->base) ? ci->base : ch;
+}
+
+unsigned
+elchr_deaccent(unsigned ch)
+{
+ struct char_info_st *ci = elchr_info(ch);
+ if (ci && (ci->flags & CHF_ACCENT_MASK))
+ return ci->deaccent ? ci->deaccent : ci->base ? ci->base : ch;
+ return ch;
+}
+
+unsigned
+elchr_accent(unsigned ch, int acc)
+{
+ struct char_info_st *ci = elchr_info(ch);
+ return (ci && ci->accented[acc-1]) ? ci->accented[acc-1] : ch;
+}
+
+int
+elchr_diphthong(unsigned ch, int state)
+{
+ struct char_info_st *ci = elchr_info(ch);
+
+ if (!ci || !(ci->flags & CHF_VOWEL))
+ return 0;
+ switch (state) {
+ case 0:
+ if (ci->flags & CHF_DIPH1)
+ state = 1;
+ break;
+ case 1:
+ if (ci->flags & CHF_DIPH2)
+ state = 2;
+ break;
+ default:
+ state = 0;
+ }
+ return state;
+}
diff --git a/src/ellinika/elmorph.c b/src/ellinika/elmorph.c
new file mode 100644
index 0000000..5234eda
--- a/dev/null
+++ b/src/ellinika/elmorph.c
@@ -0,0 +1,655 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <errno.h>
+#include <stdlib.h>
+#include <libguile.h>
+#include "utf8.h"
+#include "elmorph.h"
+
+struct elstr {
+ unsigned *str; /* UTF-8 string */
+ size_t len; /* Its length */
+ unsigned nsyl; /* Number of syllables. */
+ unsigned *sylmap; /* Syllable map (nsyl elements) */
+ unsigned acc_syl; /* Number of the accented syllable
+ (1-based, from the last syllable) */
+ unsigned acc_pos; /* Number of the accented character
+ (0-based, from str[0]) */
+};
+
+scm_t_bits _elstr_tag;
+
+static void
+_elstr_syllabize(struct elstr *elstr)
+{
+ unsigned *sylmap;
+ unsigned i, nsyl = 0, accsyl = 0, accchr = 0;
+ int dstate = 0;
+ int acc = 0;
+
+ sylmap = scm_gc_malloc(sizeof(sylmap[0])*elstr->len, "syllable map");
+
+ for (i = 0; i < elstr->len; i++) {
+ int nstate;
+
+ if (elchr_getaccent(elstr->str[i])) {
+ accsyl = nsyl;
+ accchr = i;
+ }
+ nstate = elchr_diphthong(elstr->str[i], dstate);
+ if (nstate)
+ /* skip */;
+ else if (dstate)
+ sylmap[nsyl++] = i - 1;
+ else if (elchr_isvowel(elstr->str[i]))
+ sylmap[nsyl++] = i;
+ dstate = nstate;
+ }
+ if (dstate)
+ sylmap[nsyl++] = i - 1;
+ else
+ sylmap[nsyl-1] = i - 1;
+ elstr->sylmap = sylmap;
+ elstr->nsyl = nsyl;
+ elstr->acc_pos = accchr;
+ elstr->acc_syl = nsyl - accsyl;
+}
+
+static SCM
+_elstr_alloc(const char *instr)
+{
+ struct elstr *elstr;
+ unsigned *wptr;
+ size_t wlen;
+
+ if (utf8_mbstr_to_wc(instr, &wptr, &wlen))
+ return SCM_EOL;
+
+ elstr = scm_gc_malloc(sizeof(*elstr), "Elstr");
+ elstr->str = wptr;
+ elstr->len = wlen;
+
+ _elstr_syllabize(elstr);
+
+ SCM_RETURN_NEWSMOB(_elstr_tag, elstr);
+}
+
+static SCM
+_elstr_dup(struct elstr *elstr)
+{
+ struct elstr *elnew;
+
+ elnew = scm_gc_malloc(sizeof(*elstr), "Elstr");
+ elnew->str = calloc(elstr->len, sizeof(elnew->str[0]));
+ if (!elnew->str)
+ scm_memory_error("_elstr_dup");
+ elnew->sylmap = calloc(elstr->nsyl, sizeof(elnew->sylmap[0]));
+ if (!elnew->sylmap) {
+ free(elnew->str);
+ scm_memory_error("_elstr_dup");
+ }
+ memcpy(elnew->str, elstr->str, sizeof(elstr->str[0]) * elstr->len);
+ elnew->len = elstr->len;
+ elnew->nsyl = elstr->nsyl;
+ memcpy(elnew->sylmap, elstr->sylmap,
+ sizeof(elstr->sylmap[0]) * elstr->nsyl);
+ elnew->acc_syl = elstr->acc_syl;
+ elnew->acc_pos = elstr->acc_pos;
+ SCM_RETURN_NEWSMOB(_elstr_tag, elnew);
+}
+
+static scm_sizet
+_elstr_free(SCM smob)
+{
+ struct elstr *elstr = (struct elstr *) SCM_CDR(smob);
+ free(elstr->str);
+ free(elstr->sylmap);
+ free(elstr);
+ return 0;
+}
+
+static int
+_elstr_print(SCM smob, SCM port, scm_print_state *pstate)
+{
+ struct elstr *elstr = (struct elstr *) SCM_CDR(smob);
+ int i, j, an;
+ char *s;
+
+ scm_puts("#<elstr ``", port);
+ an = elstr->nsyl - elstr->acc_syl;
+ if (an == 0)
+ scm_puts("[", port);
+ for (i = j = 0; i < elstr->len; i++) {
+ char r[6];
+ int n;
+
+ if (i == elstr->sylmap[j] + 1) {
+ if (j == an)
+ scm_puts("]", port);
+ scm_puts("-", port);
+ if (++j == an)
+ scm_puts("[", port);
+ }
+ n = utf8_wctomb(r, elstr->str[i]);
+ if (n == -1)
+ continue;
+ r[n] = 0;
+ scm_puts(r, port);
+ }
+ if (j == an)
+ scm_puts("]", port);
+ scm_puts("''>", port);
+ return 1;
+}
+
+static void
+_elstr_init()
+{
+ _elstr_tag = scm_make_smob_type("Elstr", sizeof(struct elstr));
+ scm_set_smob_free(_elstr_tag, _elstr_free);
+ scm_set_smob_print(_elstr_tag, _elstr_print);
+}
+
+SCM_DEFINE_PUBLIC(scm_string__elstr, "string->elstr", 1, 0, 0,
+ (SCM string),
+"Create new ELSTR from STRING\n")
+#define FUNC_NAME s_scm_string__elstr
+{
+ char *str;
+ SCM scm;
+
+ SCM_ASSERT(scm_is_string(string), string, SCM_ARG1, FUNC_NAME);
+ str = scm_to_locale_string(string);
+ scm = _elstr_alloc(str);
+ free(str);
+ if (scm == SCM_EOL)
+ scm_misc_error(FUNC_NAME,
+ "Invalid input string: ~S",
+ scm_list_1(string));
+ return scm;
+}
+#undef FUNC_NAME
+
+#define scm_is_elstr(s) (!SCM_IMP(s) && SCM_CELL_TYPE(s) == _elstr_tag)
+
+SCM_DEFINE_PUBLIC(scm_elstr__string, "elstr->string", 1, 0, 0,
+ (SCM el),
+"Convert EL to a STRING\n")
+#define FUNC_NAME s_scm_elstr__string
+{
+ struct elstr *elstr;
+ char *s;
+ SCM scm;
+
+ SCM_ASSERT(scm_is_elstr(el), el, SCM_ARG1, FUNC_NAME);
+ elstr = (struct elstr*) SCM_CDR(el);
+ if (utf8_wc_to_mbstr(elstr->str, elstr->len, &s))
+ scm_misc_error(FUNC_NAME,
+ "cannot convert elstr to Scheme",
+ SCM_EOL);
+ scm = scm_from_locale_string(s);
+ free(s);
+ return scm;
+}
+#undef FUNC_NAME
+
+SCM_DEFINE_PUBLIC(scm_elstr_length, "elstr-length", 1, 0, 0,
+ (SCM el),
+"Returns the number of characters in EL\n")
+#define FUNC_NAME s_scm_elstr_length
+{
+ struct elstr *elstr;
+
+ SCM_ASSERT(scm_is_elstr(el), el, SCM_ARG1, FUNC_NAME);
+ elstr = (struct elstr*) SCM_CDR(el);
+ return scm_from_uint(elstr->len);
+}
+#undef FUNC_NAME
+
+SCM_DEFINE_PUBLIC(scm_elstr_number_of_syllables, "elstr-number-of-syllables",
+ 1, 0, 0,
+ (SCM el),
+"Returns the number of characters in EL\n")
+#define FUNC_NAME s_scm_elstr_number_of_syllables
+{
+ struct elstr *elstr;
+
+ SCM_ASSERT(scm_is_elstr(el), el, SCM_ARG1, FUNC_NAME);
+ elstr = (struct elstr*) SCM_CDR(el);
+ return scm_from_uint(elstr->nsyl);
+}
+#undef FUNC_NAME
+
+SCM_DEFINE_PUBLIC(scm_elstr_syllable_prop, "elstr-syllable-prop",
+ 2, 0, 0,
+ (SCM el, SCM n),
+"Returns properties of the syllable N in EL\n")
+#define FUNC_NAME s_scm_elstr_syllable_prop
+{
+ struct elstr *elstr;
+ unsigned num, start;
+
+ SCM_ASSERT(scm_is_elstr(el), el, SCM_ARG1, FUNC_NAME);
+ elstr = (struct elstr*) SCM_CDR(el);
+ SCM_ASSERT(scm_is_integer(n), n, SCM_ARG2, FUNC_NAME);
+ num = scm_to_uint(n);
+ if (num > elstr->nsyl)
+ scm_misc_error(FUNC_NAME,
+ "cannot get syllable #~S: not enough syllables: ~S",
+ scm_list_2(el, n));
+ num = elstr->nsyl - num;
+ if (num == 0)
+ start = 0;
+ else
+ start = elstr->sylmap[num - 1] + 1;
+
+ return scm_cons(scm_from_uint(start),
+ scm_from_uint(elstr->sylmap[num]));
+}
+#undef FUNC_NAME
+
+SCM_DEFINE_PUBLIC(scm_elstr_accent_position, "elstr-accent-position", 1, 0, 0,
+ (SCM el),
+"Return position of the accented character in EL\n")
+#define FUNC_NAME s_scm_elstr_accent_position
+{
+ struct elstr *elstr;
+
+ SCM_ASSERT(scm_is_elstr(el), el, SCM_ARG1, FUNC_NAME);
+ elstr = (struct elstr*) SCM_CDR(el);
+ return scm_from_uint(elstr->acc_pos);
+}
+#undef FUNC_NAME
+
+SCM_DEFINE_PUBLIC(scm_elstr_accented_syllable, "elstr-accented-syllable",
+ 1, 0, 0,
+ (SCM el),
+"Return position of the accented syllable in EL\n")
+#define FUNC_NAME s_scm_elstr_accented_syllable
+{
+ struct elstr *elstr;
+
+ SCM_ASSERT(scm_is_elstr(el), el, SCM_ARG1, FUNC_NAME);
+ elstr = (struct elstr*) SCM_CDR(el);
+ return scm_from_uint(elstr->acc_syl);
+}
+#undef FUNC_NAME
+
+SCM_DEFINE_PUBLIC(scm_elstr_syllable, "elstr-syllable",
+ 2, 0, 0,
+ (SCM el, SCM n),
+"Return Nth syllable in EL\n")
+#define FUNC_NAME s_scm_elstr_accented_syllable
+{
+ struct elstr *elstr;
+ char *s;
+ SCM scm;
+ unsigned num, start;
+
+ SCM_ASSERT(scm_is_elstr(el), el, SCM_ARG1, FUNC_NAME);
+ elstr = (struct elstr*) SCM_CDR(el);
+ SCM_ASSERT(scm_is_integer(n), n, SCM_ARG2, FUNC_NAME);
+ num = scm_to_uint(n);
+ if (num > elstr->nsyl)
+ scm_misc_error(FUNC_NAME,
+ "cannot get syllable #~S: not enough syllables: ~S",
+ scm_list_2(el, n));
+ num = elstr->nsyl - num;
+ if (num == 0)
+ start = 0;
+ else
+ start = elstr->sylmap[num - 1] + 1;
+ if (utf8_wc_to_mbstr(elstr->str + start,
+ elstr->sylmap[num] - start + 1,
+ &s))
+ scm_misc_error(FUNC_NAME,
+ "cannot convert elstr to Scheme",
+ SCM_EOL);
+ scm = scm_from_locale_string(s);
+ free(s);
+ return scm;
+}
+#undef FUNC_NAME
+
+SCM_DEFINE_PUBLIC(scm_elstr_character, "elstr-character",
+ 2, 0, 0,
+ (SCM el, SCM n),
+"Return Nth character in EL\n")
+#define FUNC_NAME s_scm_elstr_character
+{
+ struct elstr *elstr;
+ unsigned num;
+ char r[6];
+ int len;
+
+ SCM_ASSERT(scm_is_elstr(el), el, SCM_ARG1, FUNC_NAME);
+ elstr = (struct elstr*) SCM_CDR(el);
+ SCM_ASSERT(scm_is_integer(n), n, SCM_ARG2, FUNC_NAME);
+ num = scm_to_uint(n);
+ if (num >= elstr->len)
+ scm_misc_error(FUNC_NAME,
+ "cannot get character #~S: not enough characters: ~S",
+ scm_list_2(el, n));
+ len = utf8_wctomb(r, elstr->str[num]);
+ if (len <= 0)
+ scm_misc_error(FUNC_NAME,
+ "cannot convert elchr to Scheme",
+ SCM_EOL);
+ r[len] = 0;
+ return scm_from_locale_string(r);
+}
+#undef FUNC_NAME
+
+static SCM
+_elstr_chgcase(SCM el, void (*chgfun)(unsigned *, size_t),
+ int destructive, const char *func_name)
+{
+ struct elstr *elstr;
+ SCM scm;
+
+ SCM_ASSERT(scm_is_elstr(el), el, SCM_ARG1, func_name);
+ elstr = (struct elstr*) SCM_CDR(el);
+ if (destructive)
+ scm = SCM_UNSPECIFIED;
+ else {
+ scm = _elstr_dup(elstr);
+ elstr = (struct elstr*) SCM_CDR(scm);
+ }
+ chgfun(elstr->str, elstr->len);
+ return scm;
+}
+
+SCM_DEFINE_PUBLIC(scm_elstr_toupper, "elstr-toupper",
+ 1, 0, 0,
+ (SCM el),
+"Convert EL to upper case\n")
+#define FUNC_NAME s_scm_elstr_toupper
+{
+ return _elstr_chgcase(el, utf8_wc_strnupper, 0, FUNC_NAME);
+}
+#undef FUNC_NAME
+
+SCM_DEFINE_PUBLIC(scm_elstr_tolower, "elstr-tolower",
+ 1, 0, 0,
+ (SCM el),
+"Convert EL to lower case\n")
+#define FUNC_NAME s_scm_elstr_tolower
+{
+ return _elstr_chgcase(el, utf8_wc_strnlower, 0, FUNC_NAME);
+}
+#undef FUNC_NAME
+
+SCM_DEFINE_PUBLIC(scm_elstr_toupper_x, "elstr-toupper!",
+ 1, 0, 0,
+ (SCM el),
+"Convert EL to upper case (destructive)\n")
+#define FUNC_NAME s_scm_elstr_toupper_x
+{
+ return _elstr_chgcase(el, utf8_wc_strnupper, 1, FUNC_NAME);
+}
+#undef FUNC_NAME
+
+SCM_DEFINE_PUBLIC(scm_elstr_tolower_x, "elstr-tolower!",
+ 1, 0, 0,
+ (SCM el),
+"Convert EL to lower case (destructive)\n")
+#define FUNC_NAME s_scm_elstr_tolower_x
+{
+ return _elstr_chgcase(el, utf8_wc_strnlower, 0, FUNC_NAME);
+}
+#undef FUNC_NAME
+
+static SCM
+_elstr_deaccent(SCM el, int destructive, const char *func_name)
+{
+ struct elstr *elstr;
+ unsigned i;
+ SCM scm;
+
+ SCM_ASSERT(scm_is_elstr(el), el, SCM_ARG1, func_name);
+ elstr = (struct elstr*) SCM_CDR(el);
+ if (destructive)
+ scm = SCM_UNSPECIFIED;
+ else {
+ scm = _elstr_dup(elstr);
+ elstr = (struct elstr*) SCM_CDR(scm);
+ }
+ for (i = 0; i < elstr->len; i++)
+ elstr->str[i] = elchr_deaccent(elstr->str[i]);
+ elstr->acc_pos = 0;
+ elstr->acc_syl = 0;
+ return scm;
+}
+
+SCM_DEFINE_PUBLIC(scm_elstr_deaccent, "elstr-deaccent",
+ 1, 0, 0,
+ (SCM el),
+"Remove all accents from EL\n")
+#define FUNC_NAME s_scm_elstr_deaccent
+{
+ return _elstr_deaccent(el, 0, FUNC_NAME);
+}
+#undef FUNC_NAME
+
+SCM_DEFINE_PUBLIC(scm_elstr_deaccent_x, "elstr-deaccent!",
+ 1, 0, 0,
+ (SCM el),
+"Remove all accents from EL (desctructive)\n")
+#define FUNC_NAME s_scm_elstr_deaccent_x
+{
+ return _elstr_deaccent(el, 1, FUNC_NAME);
+}
+#undef FUNC_NAME
+
+static SCM
+_elstr_set_accent(SCM el, SCM n, int destructive, const char *func_name)
+{
+ struct elstr *elstr;
+ unsigned i;
+ unsigned acc_num, num, len, start;
+ SCM scm;
+ int dstate;
+
+ SCM_ASSERT(scm_is_elstr(el), el, SCM_ARG1, func_name);
+ SCM_ASSERT(scm_is_integer(n), n, SCM_ARG2, func_name);
+ elstr = (struct elstr*) SCM_CDR(el);
+ num = scm_to_uint(n);
+ if (num > elstr->nsyl)
+ scm_misc_error(func_name,
+ "cannot get syllable #~S: not enough syllables: ~S",
+ scm_list_2(el, n));
+ acc_num = elstr->nsyl - num;
+ if (acc_num == 0)
+ start = 0;
+ else
+ start = elstr->sylmap[acc_num - 1] + 1;
+
+ if (destructive)
+ scm = SCM_UNSPECIFIED;
+ else {
+ scm = _elstr_dup(elstr);
+ elstr = (struct elstr*) SCM_CDR(scm);
+ }
+
+ /* Clear all accents */
+ for (i = 0; i < elstr->len; i++)
+ elstr->str[i] = elchr_deaccent(elstr->str[i]);
+ len = elstr->sylmap[acc_num] - start + 1;
+ dstate = 0;
+ for (i = start; i <= start + len; i++) {
+ int nstate;
+
+ if (!elchr_isvowel(elstr->str[i])) {
+ if (dstate) {
+ --i;
+ break;
+ }
+ continue;
+ }
+ nstate = elchr_diphthong(elstr->str[i], dstate);
+ if (!nstate)
+ break;
+ dstate = nstate;
+ }
+ elstr->str[i] = elchr_accent(elstr->str[i], CHF_OXEIA);
+ elstr->acc_syl = num;
+ return scm;
+}
+
+SCM_DEFINE_PUBLIC(scm_elstr_set_accent, "elstr-set-accent",
+ 2, 0, 0,
+ (SCM el, SCM n),
+"Set accent on Nth syllable of EL\n")
+{
+ return _elstr_set_accent(el, n, 0, s_scm_elstr_set_accent);
+}
+
+SCM_DEFINE_PUBLIC(scm_elstr_set_accent_x, "elstr-set-accent!",
+ 2, 0, 0,
+ (SCM el, SCM n),
+"Set accent on Nth syllable of EL (destructive)\n")
+{
+ return _elstr_set_accent(el, n, 1, s_scm_elstr_set_accent_x);
+}
+#undef FUNC_NAME
+
+SCM_DEFINE_PUBLIC(scm_elstr_char_prop_bitmask, "elstr-char-prop-bitmask",
+ 2, 0, 0,
+ (SCM el, SCM n),
+"Returns properties of the Nth char in EL, as a bitmask\n")
+#define FUNC_NAME s_scm_elstr_char_prop_bitmask
+{
+ struct elstr *elstr;
+ unsigned num;
+
+ SCM_ASSERT(scm_is_elstr(el), el, SCM_ARG1, FUNC_NAME);
+ elstr = (struct elstr*) SCM_CDR(el);
+ num = scm_to_uint(n);
+ if (num >= elstr->len)
+ scm_misc_error(FUNC_NAME,
+ "cannot get character #~S: not enough characters: ~S",
+ scm_list_2(el, n));
+ return scm_from_uint(elchr_flags(elstr->str[num]));
+}
+#undef FUNC_NAME
+
+static struct deftab {
+ unsigned val;
+ char *sym;
+} deftab[] = {
+ { CHF_OXEIA, "elmorph:oxeia" },
+ { CHF_PERISPWMENH, "elmorph:perispwmenh" },
+ { CHF_BAREIA, "elmorph:bareia" },
+ { CHF_ACCENT_MASK, "elmorph:accent-mask" },
+ { CHF_TREMA, "elmorph:trema" },
+ { CHF_VOWEL, "elmorph:vowel" },
+ { CHF_CONSONANT, "elmorph:consonant" },
+ { CHF_SEMIVOWEL, "elmorph:semivowel" },
+ { CHF_PUNCT, "elmorph:punct" },
+ { CHF_SYMBOL, "elmorph:symbol" },
+ { CHF_MODIFIER, "elmorph:modifier" },
+ { CHF_ARCHAIC, "elmorph:archaic" },
+ { CHF_LOWER, "elmorph:lower" },
+ { CHF_UPPER, "elmorph:upper" },
+ { CHF_NUMERIC, "elmorph:numeric" },
+
+ { CHF_DIPH1, "elmorph:diph1" },
+ { CHF_DIPH2, "elmorph:diph2" }
+};
+
+SCM_DEFINE_PUBLIC(scm_utf8_toupper, "utf8-toupper", 1, 0, 0,
+ (SCM string),
+"Convert STRING to uppercase\n")
+#define FUNC_NAME s_scm_utf8_toupper
+{
+ char *str;
+ SCM scm;
+
+ SCM_ASSERT(scm_is_string(string), string, SCM_ARG1, FUNC_NAME);
+ str = scm_to_locale_string(string);
+ if (utf8_toupper(str, strlen(str)))
+ scm_misc_error(FUNC_NAME,
+ "cannot convert to upper case: ~S",
+ scm_list_1(string));
+ scm = scm_from_locale_string(str);
+ free(str);
+ return scm;
+}
+#undef FUNC_NAME
+
+SCM_DEFINE_PUBLIC(scm_utf8_tolower, "utf8-tolower", 1, 0, 0,
+ (SCM string),
+"Convert STRING to lowercase\n")
+#define FUNC_NAME s_scm_utf8_tolower
+{
+ char *str;
+ SCM scm;
+
+ SCM_ASSERT(scm_is_string(string), string, SCM_ARG1, FUNC_NAME);
+ str = scm_to_locale_string(string);
+ if (utf8_tolower(str, strlen(str)))
+ scm_misc_error(FUNC_NAME,
+ "cannot convert to lower case: ~S",
+ scm_list_1(string));
+ scm = scm_from_locale_string(str);
+ free(str);
+ return scm;
+}
+#undef FUNC_NAME
+
+static SCM
+_elstr_thema_aoristoy(SCM el, int destructive, const char *func_name)
+{
+ struct elstr *elstr;
+ SCM scm;
+ unsigned *wc;
+ size_t wclen;
+
+ SCM_ASSERT(scm_is_elstr(el), el, SCM_ARG1, func_name);
+ elstr = (struct elstr*) SCM_CDR(el);
+ if (destructive)
+ scm = SCM_UNSPECIFIED;
+ else {
+ scm = _elstr_dup(elstr);
+ elstr = (struct elstr*) SCM_CDR(scm);
+ }
+ if (elmorph_thema_aoristoy(elstr->str, elstr->len, &wc, &wclen))
+ scm_memory_error(func_name);
+ free(elstr->str);
+ elstr->str = wc;
+ elstr->len = wclen;
+ return scm;
+}
+
+SCM_DEFINE_PUBLIC(scm_elstr_thema_aoristoy, "elstr-thema-aoristoy", 1, 0, 0,
+ (SCM thema),
+"Convert THEMA, which must be a root of present. to an aorist root\n")
+#define FUNC_NAME s_scm_elstr_thema_aoristoy
+{
+ return _elstr_thema_aoristoy(thema, 0, FUNC_NAME);
+}
+#undef FUNC_NAME
+
+SCM_DEFINE_PUBLIC(scm_elstr_thema_aoristoy_x, "elstr-thema-aoristoy!", 1, 0, 0,
+ (SCM thema),
+"Convert THEMA, which must be a root of present. to an aorist root (destructive)\n")
+#define FUNC_NAME s_scm_elstr_thema_aoristoy_x
+{
+ return _elstr_thema_aoristoy(thema, 1, FUNC_NAME);
+}
+#undef FUNC_NAME
+
+
+void
+scm_init_ellinika_elmorph_module()
+{
+ int i;
+
+ _elstr_init();
+ for (i = 0; i < sizeof(deftab)/sizeof(deftab[0]); i++) {
+ scm_c_define(deftab[i].sym, scm_from_uint(deftab[i].val));
+ scm_c_export(deftab[i].sym, NULL);
+ }
+#include "elmorph.x"
+}
diff --git a/src/ellinika/elmorph.h b/src/ellinika/elmorph.h
new file mode 100644
index 0000000..d91f513
--- a/dev/null
+++ b/src/ellinika/elmorph.h
@@ -0,0 +1,46 @@
+#define CHF_OXEIA 1
+#define CHF_PERISPWMENH 2
+#define CHF_BAREIA 3
+
+#define CHF_ACCENT_MASK 0x000f
+
+#define CHF_TREMA 0x0010
+
+#define CHF_VOWEL 0x00020
+#define CHF_CONSONANT 0x00040
+#define CHF_SEMIVOWEL 0x00080
+#define CHF_PUNCT 0x00100
+#define CHF_SYMBOL 0x00200
+#define CHF_MODIFIER 0x00400
+#define CHF_ARCHAIC 0x00800
+#define CHF_LOWER 0x01000
+#define CHF_UPPER 0x02000
+#define CHF_NUMERIC 0x04000
+
+#define CHF_DIPH1 0x10000
+#define CHF_DIPH2 0x20000
+
+int elchr_flags(unsigned ch);
+int elchr_isupper(unsigned ch);
+int elchr_islower(unsigned ch);
+int elchr_getaccent(unsigned ch);
+int elchr_istrema(unsigned ch);
+int elchr_isvowel(unsigned ch);
+int elchr_isconsonant(unsigned ch);
+int elchr_issemivowel(unsigned ch);
+int elchr_ispunct(unsigned ch);
+int elchr_issymbol(unsigned ch);
+int elchr_ismodifier(unsigned ch);
+int elchr_isarchaic(unsigned ch);
+int elchr_isnumeric(unsigned ch);
+unsigned elchr_numeric_value(unsigned ch);
+unsigned elchr_toupper(unsigned ch);
+unsigned elchr_tolower(unsigned ch);
+unsigned elchr_base(unsigned ch);
+unsigned elchr_deaccent(unsigned ch);
+unsigned elchr_accent(unsigned ch, int acc);
+int elchr_diphthong(unsigned ch, int state);
+
+
+int elmorph_thema_aoristoy(unsigned *word, size_t len,
+ unsigned **thema, size_t *tlen);
diff --git a/src/ellinika/elmorph.scm4 b/src/ellinika/elmorph.scm4
new file mode 100644
index 0000000..64c471e
--- a/dev/null
+++ b/src/ellinika/elmorph.scm4
@@ -0,0 +1,5 @@
+(define-module (ellinika elmorph))
+
+(load-extension
+ "LIBDIR/libguile-elmorph-v-VERSION"
+ "scm_init_ellinika_elmorph_module")
diff --git a/src/ellinika/utf8.c b/src/ellinika/utf8.c
new file mode 100644
index 0000000..952af07
--- a/dev/null
+++ b/src/ellinika/utf8.c
@@ -0,0 +1,2149 @@
+/* This file is part of GNU Dico
+ Copyright (C) 2007, 2008, 2010 Sergey Poznyakoff
+
+ GNU Dico is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Dico is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Dico. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <limits.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "utf8.h"
+
+struct unicase_info_st {
+ unsigned toupper;
+ unsigned tolower;
+ unsigned sort;
+};
+
+typedef struct unicase_info_st MY_UNICASE_INFO;
+
+/* UTF tables written by Alexander Barkov <bar@udm.net> */
+static MY_UNICASE_INFO plane00[] = {
+ {0x0000, 0x0000, 0x0000}, {0x0001, 0x0001, 0x0001},
+ {0x0002, 0x0002, 0x0002}, {0x0003, 0x0003, 0x0003},
+ {0x0004, 0x0004, 0x0004}, {0x0005, 0x0005, 0x0005},
+ {0x0006, 0x0006, 0x0006}, {0x0007, 0x0007, 0x0007},
+ {0x0008, 0x0008, 0x0008}, {0x0009, 0x0009, 0x0009},
+ {0x000A, 0x000A, 0x000A}, {0x000B, 0x000B, 0x000B},
+ {0x000C, 0x000C, 0x000C}, {0x000D, 0x000D, 0x000D},
+ {0x000E, 0x000E, 0x000E}, {0x000F, 0x000F, 0x000F},
+ {0x0010, 0x0010, 0x0010}, {0x0011, 0x0011, 0x0011},
+ {0x0012, 0x0012, 0x0012}, {0x0013, 0x0013, 0x0013},
+ {0x0014, 0x0014, 0x0014}, {0x0015, 0x0015, 0x0015},
+ {0x0016, 0x0016, 0x0016}, {0x0017, 0x0017, 0x0017},
+ {0x0018, 0x0018, 0x0018}, {0x0019, 0x0019, 0x0019},
+ {0x001A, 0x001A, 0x001A}, {0x001B, 0x001B, 0x001B},
+ {0x001C, 0x001C, 0x001C}, {0x001D, 0x001D, 0x001D},
+ {0x001E, 0x001E, 0x001E}, {0x001F, 0x001F, 0x001F},
+ {0x0020, 0x0020, 0x0020}, {0x0021, 0x0021, 0x0021},
+ {0x0022, 0x0022, 0x0022}, {0x0023, 0x0023, 0x0023},
+ {0x0024, 0x0024, 0x0024}, {0x0025, 0x0025, 0x0025},
+ {0x0026, 0x0026, 0x0026}, {0x0027, 0x0027, 0x0027},
+ {0x0028, 0x0028, 0x0028}, {0x0029, 0x0029, 0x0029},
+ {0x002A, 0x002A, 0x002A}, {0x002B, 0x002B, 0x002B},
+ {0x002C, 0x002C, 0x002C}, {0x002D, 0x002D, 0x002D},
+ {0x002E, 0x002E, 0x002E}, {0x002F, 0x002F, 0x002F},
+ {0x0030, 0x0030, 0x0030}, {0x0031, 0x0031, 0x0031},
+ {0x0032, 0x0032, 0x0032}, {0x0033, 0x0033, 0x0033},
+ {0x0034, 0x0034, 0x0034}, {0x0035, 0x0035, 0x0035},
+ {0x0036, 0x0036, 0x0036}, {0x0037, 0x0037, 0x0037},
+ {0x0038, 0x0038, 0x0038}, {0x0039, 0x0039, 0x0039},
+ {0x003A, 0x003A, 0x003A}, {0x003B, 0x003B, 0x003B},
+ {0x003C, 0x003C, 0x003C}, {0x003D, 0x003D, 0x003D},
+ {0x003E, 0x003E, 0x003E}, {0x003F, 0x003F, 0x003F},
+ {0x0040, 0x0040, 0x0040}, {0x0041, 0x0061, 0x0041},
+ {0x0042, 0x0062, 0x0042}, {0x0043, 0x0063, 0x0043},
+ {0x0044, 0x0064, 0x0044}, {0x0045, 0x0065, 0x0045},
+ {0x0046, 0x0066, 0x0046}, {0x0047, 0x0067, 0x0047},
+ {0x0048, 0x0068, 0x0048}, {0x0049, 0x0069, 0x0049},
+ {0x004A, 0x006A, 0x004A}, {0x004B, 0x006B, 0x004B},
+ {0x004C, 0x006C, 0x004C}, {0x004D, 0x006D, 0x004D},
+ {0x004E, 0x006E, 0x004E}, {0x004F, 0x006F, 0x004F},
+ {0x0050, 0x0070, 0x0050}, {0x0051, 0x0071, 0x0051},
+ {0x0052, 0x0072, 0x0052}, {0x0053, 0x0073, 0x0053},
+ {0x0054, 0x0074, 0x0054}, {0x0055, 0x0075, 0x0055},
+ {0x0056, 0x0076, 0x0056}, {0x0057, 0x0077, 0x0057},
+ {0x0058, 0x0078, 0x0058}, {0x0059, 0x0079, 0x0059},
+ {0x005A, 0x007A, 0x005A}, {0x005B, 0x005B, 0x005B},
+ {0x005C, 0x005C, 0x005C}, {0x005D, 0x005D, 0x005D},
+ {0x005E, 0x005E, 0x005E}, {0x005F, 0x005F, 0x005F},
+ {0x0060, 0x0060, 0x0060}, {0x0041, 0x0061, 0x0041},
+ {0x0042, 0x0062, 0x0042}, {0x0043, 0x0063, 0x0043},
+ {0x0044, 0x0064, 0x0044}, {0x0045, 0x0065, 0x0045},
+ {0x0046, 0x0066, 0x0046}, {0x0047, 0x0067, 0x0047},
+ {0x0048, 0x0068, 0x0048}, {0x0049, 0x0069, 0x0049},
+ {0x004A, 0x006A, 0x004A}, {0x004B, 0x006B, 0x004B},
+ {0x004C, 0x006C, 0x004C}, {0x004D, 0x006D, 0x004D},
+ {0x004E, 0x006E, 0x004E}, {0x004F, 0x006F, 0x004F},
+ {0x0050, 0x0070, 0x0050}, {0x0051, 0x0071, 0x0051},
+ {0x0052, 0x0072, 0x0052}, {0x0053, 0x0073, 0x0053},
+ {0x0054, 0x0074, 0x0054}, {0x0055, 0x0075, 0x0055},
+ {0x0056, 0x0076, 0x0056}, {0x0057, 0x0077, 0x0057},
+ {0x0058, 0x0078, 0x0058}, {0x0059, 0x0079, 0x0059},
+ {0x005A, 0x007A, 0x005A}, {0x007B, 0x007B, 0x007B},
+ {0x007C, 0x007C, 0x007C}, {0x007D, 0x007D, 0x007D},
+ {0x007E, 0x007E, 0x007E}, {0x007F, 0x007F, 0x007F},
+ {0x0080, 0x0080, 0x0080}, {0x0081, 0x0081, 0x0081},
+ {0x0082, 0x0082, 0x0082}, {0x0083, 0x0083, 0x0083},
+ {0x0084, 0x0084, 0x0084}, {0x0085, 0x0085, 0x0085},
+ {0x0086, 0x0086, 0x0086}, {0x0087, 0x0087, 0x0087},
+ {0x0088, 0x0088, 0x0088}, {0x0089, 0x0089, 0x0089},
+ {0x008A, 0x008A, 0x008A}, {0x008B, 0x008B, 0x008B},
+ {0x008C, 0x008C, 0x008C}, {0x008D, 0x008D, 0x008D},
+ {0x008E, 0x008E, 0x008E}, {0x008F, 0x008F, 0x008F},
+ {0x0090, 0x0090, 0x0090}, {0x0091, 0x0091, 0x0091},
+ {0x0092, 0x0092, 0x0092}, {0x0093, 0x0093, 0x0093},
+ {0x0094, 0x0094, 0x0094}, {0x0095, 0x0095, 0x0095},
+ {0x0096, 0x0096, 0x0096}, {0x0097, 0x0097, 0x0097},
+ {0x0098, 0x0098, 0x0098}, {0x0099, 0x0099, 0x0099},
+ {0x009A, 0x009A, 0x009A}, {0x009B, 0x009B, 0x009B},
+ {0x009C, 0x009C, 0x009C}, {0x009D, 0x009D, 0x009D},
+ {0x009E, 0x009E, 0x009E}, {0x009F, 0x009F, 0x009F},
+ {0x00A0, 0x00A0, 0x00A0}, {0x00A1, 0x00A1, 0x00A1},
+ {0x00A2, 0x00A2, 0x00A2}, {0x00A3, 0x00A3, 0x00A3},
+ {0x00A4, 0x00A4, 0x00A4}, {0x00A5, 0x00A5, 0x00A5},
+ {0x00A6, 0x00A6, 0x00A6}, {0x00A7, 0x00A7, 0x00A7},
+ {0x00A8, 0x00A8, 0x00A8}, {0x00A9, 0x00A9, 0x00A9},
+ {0x00AA, 0x00AA, 0x00AA}, {0x00AB, 0x00AB, 0x00AB},
+ {0x00AC, 0x00AC, 0x00AC}, {0x00AD, 0x00AD, 0x00AD},
+ {0x00AE, 0x00AE, 0x00AE}, {0x00AF, 0x00AF, 0x00AF},
+ {0x00B0, 0x00B0, 0x00B0}, {0x00B1, 0x00B1, 0x00B1},
+ {0x00B2, 0x00B2, 0x00B2}, {0x00B3, 0x00B3, 0x00B3},
+ {0x00B4, 0x00B4, 0x00B4}, {0x039C, 0x00B5, 0x039C},
+ {0x00B6, 0x00B6, 0x00B6}, {0x00B7, 0x00B7, 0x00B7},
+ {0x00B8, 0x00B8, 0x00B8}, {0x00B9, 0x00B9, 0x00B9},
+ {0x00BA, 0x00BA, 0x00BA}, {0x00BB, 0x00BB, 0x00BB},
+ {0x00BC, 0x00BC, 0x00BC}, {0x00BD, 0x00BD, 0x00BD},
+ {0x00BE, 0x00BE, 0x00BE}, {0x00BF, 0x00BF, 0x00BF},
+ {0x00C0, 0x00E0, 0x0041}, {0x00C1, 0x00E1, 0x0041},
+ {0x00C2, 0x00E2, 0x0041}, {0x00C3, 0x00E3, 0x0041},
+ {0x00C4, 0x00E4, 0x0041}, {0x00C5, 0x00E5, 0x0041},
+ {0x00C6, 0x00E6, 0x00C6}, {0x00C7, 0x00E7, 0x0043},
+ {0x00C8, 0x00E8, 0x0045}, {0x00C9, 0x00E9, 0x0045},
+ {0x00CA, 0x00EA, 0x0045}, {0x00CB, 0x00EB, 0x0045},
+ {0x00CC, 0x00EC, 0x0049}, {0x00CD, 0x00ED, 0x0049},
+ {0x00CE, 0x00EE, 0x0049}, {0x00CF, 0x00EF, 0x0049},
+ {0x00D0, 0x00F0, 0x00D0}, {0x00D1, 0x00F1, 0x004E},
+ {0x00D2, 0x00F2, 0x004F}, {0x00D3, 0x00F3, 0x004F},
+ {0x00D4, 0x00F4, 0x004F}, {0x00D5, 0x00F5, 0x004F},
+ {0x00D6, 0x00F6, 0x004F}, {0x00D7, 0x00D7, 0x00D7},
+ {0x00D8, 0x00F8, 0x00D8}, {0x00D9, 0x00F9, 0x0055},
+ {0x00DA, 0x00FA, 0x0055}, {0x00DB, 0x00FB, 0x0055},
+ {0x00DC, 0x00FC, 0x0055}, {0x00DD, 0x00FD, 0x0059},
+ {0x00DE, 0x00FE, 0x00DE}, {0x00DF, 0x00DF, 0x00DF},
+ {0x00C0, 0x00E0, 0x0041}, {0x00C1, 0x00E1, 0x0041},
+ {0x00C2, 0x00E2, 0x0041}, {0x00C3, 0x00E3, 0x0041},
+ {0x00C4, 0x00E4, 0x0041}, {0x00C5, 0x00E5, 0x0041},
+ {0x00C6, 0x00E6, 0x00C6}, {0x00C7, 0x00E7, 0x0043},
+ {0x00C8, 0x00E8, 0x0045}, {0x00C9, 0x00E9, 0x0045},
+ {0x00CA, 0x00EA, 0x0045}, {0x00CB, 0x00EB, 0x0045},
+ {0x00CC, 0x00EC, 0x0049}, {0x00CD, 0x00ED, 0x0049},
+ {0x00CE, 0x00EE, 0x0049}, {0x00CF, 0x00EF, 0x0049},
+ {0x00D0, 0x00F0, 0x00D0}, {0x00D1, 0x00F1, 0x004E},
+ {0x00D2, 0x00F2, 0x004F}, {0x00D3, 0x00F3, 0x004F},
+ {0x00D4, 0x00F4, 0x004F}, {0x00D5, 0x00F5, 0x004F},
+ {0x00D6, 0x00F6, 0x004F}, {0x00F7, 0x00F7, 0x00F7},
+ {0x00D8, 0x00F8, 0x00D8}, {0x00D9, 0x00F9, 0x0055},
+ {0x00DA, 0x00FA, 0x0055}, {0x00DB, 0x00FB, 0x0055},
+ {0x00DC, 0x00FC, 0x0055}, {0x00DD, 0x00FD, 0x0059},
+ {0x00DE, 0x00FE, 0x00DE}, {0x0178, 0x00FF, 0x0059}
+};
+
+static MY_UNICASE_INFO plane01[] = {
+ {0x0100, 0x0101, 0x0041}, {0x0100, 0x0101, 0x0041},
+ {0x0102, 0x0103, 0x0041}, {0x0102, 0x0103, 0x0041},
+ {0x0104, 0x0105, 0x0041}, {0x0104, 0x0105, 0x0041},
+ {0x0106, 0x0107, 0x0043}, {0x0106, 0x0107, 0x0043},
+ {0x0108, 0x0109, 0x0043}, {0x0108, 0x0109, 0x0043},
+ {0x010A, 0x010B, 0x0043}, {0x010A, 0x010B, 0x0043},
+ {0x010C, 0x010D, 0x0043}, {0x010C, 0x010D, 0x0043},
+ {0x010E, 0x010F, 0x0044}, {0x010E, 0x010F, 0x0044},
+ {0x0110, 0x0111, 0x0110}, {0x0110, 0x0111, 0x0110},
+ {0x0112, 0x0113, 0x0045}, {0x0112, 0x0113, 0x0045},
+ {0x0114, 0x0115, 0x0045}, {0x0114, 0x0115, 0x0045},
+ {0x0116, 0x0117, 0x0045}, {0x0116, 0x0117, 0x0045},
+ {0x0118, 0x0119, 0x0045}, {0x0118, 0x0119, 0x0045},
+ {0x011A, 0x011B, 0x0045}, {0x011A, 0x011B, 0x0045},
+ {0x011C, 0x011D, 0x0047}, {0x011C, 0x011D, 0x0047},
+ {0x011E, 0x011F, 0x0047}, {0x011E, 0x011F, 0x0047},
+ {0x0120, 0x0121, 0x0047}, {0x0120, 0x0121, 0x0047},
+ {0x0122, 0x0123, 0x0047}, {0x0122, 0x0123, 0x0047},
+ {0x0124, 0x0125, 0x0048}, {0x0124, 0x0125, 0x0048},
+ {0x0126, 0x0127, 0x0126}, {0x0126, 0x0127, 0x0126},
+ {0x0128, 0x0129, 0x0049}, {0x0128, 0x0129, 0x0049},
+ {0x012A, 0x012B, 0x0049}, {0x012A, 0x012B, 0x0049},
+ {0x012C, 0x012D, 0x0049}, {0x012C, 0x012D, 0x0049},
+ {0x012E, 0x012F, 0x0049}, {0x012E, 0x012F, 0x0049},
+ {0x0130, 0x0069, 0x0049}, {0x0049, 0x0131, 0x0049},
+ {0x0132, 0x0133, 0x0132}, {0x0132, 0x0133, 0x0132},
+ {0x0134, 0x0135, 0x004A}, {0x0134, 0x0135, 0x004A},
+ {0x0136, 0x0137, 0x004B}, {0x0136, 0x0137, 0x004B},
+ {0x0138, 0x0138, 0x0138}, {0x0139, 0x013A, 0x004C},
+ {0x0139, 0x013A, 0x004C}, {0x013B, 0x013C, 0x004C},
+ {0x013B, 0x013C, 0x004C}, {0x013D, 0x013E, 0x004C},
+ {0x013D, 0x013E, 0x004C}, {0x013F, 0x0140, 0x013F},
+ {0x013F, 0x0140, 0x013F}, {0x0141, 0x0142, 0x0141},
+ {0x0141, 0x0142, 0x0141}, {0x0143, 0x0144, 0x004E},
+ {0x0143, 0x0144, 0x004E}, {0x0145, 0x0146, 0x004E},
+ {0x0145, 0x0146, 0x004E}, {0x0147, 0x0148, 0x004E},
+ {0x0147, 0x0148, 0x004E}, {0x0149, 0x0149, 0x0149},
+ {0x014A, 0x014B, 0x014A}, {0x014A, 0x014B, 0x014A},
+ {0x014C, 0x014D, 0x004F}, {0x014C, 0x014D, 0x004F},
+ {0x014E, 0x014F, 0x004F}, {0x014E, 0x014F, 0x004F},
+ {0x0150, 0x0151, 0x004F}, {0x0150, 0x0151, 0x004F},
+ {0x0152, 0x0153, 0x0152}, {0x0152, 0x0153, 0x0152},
+ {0x0154, 0x0155, 0x0052}, {0x0154, 0x0155, 0x0052},
+ {0x0156, 0x0157, 0x0052}, {0x0156, 0x0157, 0x0052},
+ {0x0158, 0x0159, 0x0052}, {0x0158, 0x0159, 0x0052},
+ {0x015A, 0x015B, 0x0053}, {0x015A, 0x015B, 0x0053},
+ {0x015C, 0x015D, 0x0053}, {0x015C, 0x015D, 0x0053},
+ {0x015E, 0x015F, 0x0053}, {0x015E, 0x015F, 0x0053},
+ {0x0160, 0x0161, 0x0053}, {0x0160, 0x0161, 0x0053},
+ {0x0162, 0x0163, 0x0054}, {0x0162, 0x0163, 0x0054},
+ {0x0164, 0x0165, 0x0054}, {0x0164, 0x0165, 0x0054},
+ {0x0166, 0x0167, 0x0166}, {0x0166, 0x0167, 0x0166},
+ {0x0168, 0x0169, 0x0055}, {0x0168, 0x0169, 0x0055},
+ {0x016A, 0x016B, 0x0055}, {0x016A, 0x016B, 0x0055},
+ {0x016C, 0x016D, 0x0055}, {0x016C, 0x016D, 0x0055},
+ {0x016E, 0x016F, 0x0055}, {0x016E, 0x016F, 0x0055},
+ {0x0170, 0x0171, 0x0055}, {0x0170, 0x0171, 0x0055},
+ {0x0172, 0x0173, 0x0055}, {0x0172, 0x0173, 0x0055},
+ {0x0174, 0x0175, 0x0057}, {0x0174, 0x0175, 0x0057},
+ {0x0176, 0x0177, 0x0059}, {0x0176, 0x0177, 0x0059},
+ {0x0178, 0x00FF, 0x0059}, {0x0179, 0x017A, 0x005A},
+ {0x0179, 0x017A, 0x005A}, {0x017B, 0x017C, 0x005A},
+ {0x017B, 0x017C, 0x005A}, {0x017D, 0x017E, 0x005A},
+ {0x017D, 0x017E, 0x005A}, {0x0053, 0x017F, 0x0053},
+ {0x0180, 0x0180, 0x0180}, {0x0181, 0x0253, 0x0181},
+ {0x0182, 0x0183, 0x0182}, {0x0182, 0x0183, 0x0182},
+ {0x0184, 0x0185, 0x0184}, {0x0184, 0x0185, 0x0184},
+ {0x0186, 0x0254, 0x0186}, {0x0187, 0x0188, 0x0187},
+ {0x0187, 0x0188, 0x0187}, {0x0189, 0x0256, 0x0189},
+ {0x018A, 0x0257, 0x018A}, {0x018B, 0x018C, 0x018B},
+ {0x018B, 0x018C, 0x018B}, {0x018D, 0x018D, 0x018D},
+ {0x018E, 0x01DD, 0x018E}, {0x018F, 0x0259, 0x018F},
+ {0x0190, 0x025B, 0x0190}, {0x0191, 0x0192, 0x0191},
+ {0x0191, 0x0192, 0x0191}, {0x0193, 0x0260, 0x0193},
+ {0x0194, 0x0263, 0x0194}, {0x01F6, 0x0195, 0x01F6},
+ {0x0196, 0x0269, 0x0196}, {0x0197, 0x0268, 0x0197},
+ {0x0198, 0x0199, 0x0198}, {0x0198, 0x0199, 0x0198},
+ {0x019A, 0x019A, 0x019A}, {0x019B, 0x019B, 0x019B},
+ {0x019C, 0x026F, 0x019C}, {0x019D, 0x0272, 0x019D},
+ {0x019E, 0x019E, 0x019E}, {0x019F, 0x0275, 0x019F},
+ {0x01A0, 0x01A1, 0x004F}, {0x01A0, 0x01A1, 0x004F},
+ {0x01A2, 0x01A3, 0x01A2}, {0x01A2, 0x01A3, 0x01A2},
+ {0x01A4, 0x01A5, 0x01A4}, {0x01A4, 0x01A5, 0x01A4},
+ {0x01A6, 0x0280, 0x01A6}, {0x01A7, 0x01A8, 0x01A7},
+ {0x01A7, 0x01A8, 0x01A7}, {0x01A9, 0x0283, 0x01A9},
+ {0x01AA, 0x01AA, 0x01AA}, {0x01AB, 0x01AB, 0x01AB},
+ {0x01AC, 0x01AD, 0x01AC}, {0x01AC, 0x01AD, 0x01AC},
+ {0x01AE, 0x0288, 0x01AE}, {0x01AF, 0x01B0, 0x0055},
+ {0x01AF, 0x01B0, 0x0055}, {0x01B1, 0x028A, 0x01B1},
+ {0x01B2, 0x028B, 0x01B2}, {0x01B3, 0x01B4, 0x01B3},
+ {0x01B3, 0x01B4, 0x01B3}, {0x01B5, 0x01B6, 0x01B5},
+ {0x01B5, 0x01B6, 0x01B5}, {0x01B7, 0x0292, 0x01B7},
+ {0x01B8, 0x01B9, 0x01B8}, {0x01B8, 0x01B9, 0x01B8},
+ {0x01BA, 0x01BA, 0x01BA}, {0x01BB, 0x01BB, 0x01BB},
+ {0x01BC, 0x01BD, 0x01BC}, {0x01BC, 0x01BD, 0x01BC},
+ {0x01BE, 0x01BE, 0x01BE}, {0x01F7, 0x01BF, 0x01F7},
+ {0x01C0, 0x01C0, 0x01C0}, {0x01C1, 0x01C1, 0x01C1},
+ {0x01C2, 0x01C2, 0x01C2}, {0x01C3, 0x01C3, 0x01C3},
+ {0x01C4, 0x01C6, 0x01C4}, {0x01C4, 0x01C6, 0x01C4},
+ {0x01C4, 0x01C6, 0x01C4}, {0x01C7, 0x01C9, 0x01C7},
+ {0x01C7, 0x01C9, 0x01C7}, {0x01C7, 0x01C9, 0x01C7},
+ {0x01CA, 0x01CC, 0x01CA}, {0x01CA, 0x01CC, 0x01CA},
+ {0x01CA, 0x01CC, 0x01CA}, {0x01CD, 0x01CE, 0x0041},
+ {0x01CD, 0x01CE, 0x0041}, {0x01CF, 0x01D0, 0x0049},
+ {0x01CF, 0x01D0, 0x0049}, {0x01D1, 0x01D2, 0x004F},
+ {0x01D1, 0x01D2, 0x004F}, {0x01D3, 0x01D4, 0x0055},
+ {0x01D3, 0x01D4, 0x0055}, {0x01D5, 0x01D6, 0x0055},
+ {0x01D5, 0x01D6, 0x0055}, {0x01D7, 0x01D8, 0x0055},
+ {0x01D7, 0x01D8, 0x0055}, {0x01D9, 0x01DA, 0x0055},
+ {0x01D9, 0x01DA, 0x0055}, {0x01DB, 0x01DC, 0x0055},
+ {0x01DB, 0x01DC, 0x0055}, {0x018E, 0x01DD, 0x018E},
+ {0x01DE, 0x01DF, 0x0041}, {0x01DE, 0x01DF, 0x0041},
+ {0x01E0, 0x01E1, 0x0041}, {0x01E0, 0x01E1, 0x0041},
+ {0x01E2, 0x01E3, 0x00C6}, {0x01E2, 0x01E3, 0x00C6},
+ {0x01E4, 0x01E5, 0x01E4}, {0x01E4, 0x01E5, 0x01E4},
+ {0x01E6, 0x01E7, 0x0047}, {0x01E6, 0x01E7, 0x0047},
+ {0x01E8, 0x01E9, 0x004B}, {0x01E8, 0x01E9, 0x004B},
+ {0x01EA, 0x01EB, 0x004F}, {0x01EA, 0x01EB, 0x004F},
+ {0x01EC, 0x01ED, 0x004F}, {0x01EC, 0x01ED, 0x004F},
+ {0x01EE, 0x01EF, 0x01B7}, {0x01EE, 0x01EF, 0x01B7},
+ {0x01F0, 0x01F0, 0x004A}, {0x01F1, 0x01F3, 0x01F1},
+ {0x01F1, 0x01F3, 0x01F1}, {0x01F1, 0x01F3, 0x01F1},
+ {0x01F4, 0x01F5, 0x0047}, {0x01F4, 0x01F5, 0x0047},
+ {0x01F6, 0x0195, 0x01F6}, {0x01F7, 0x01BF, 0x01F7},
+ {0x01F8, 0x01F9, 0x004E}, {0x01F8, 0x01F9, 0x004E},
+ {0x01FA, 0x01FB, 0x0041}, {0x01FA, 0x01FB, 0x0041},
+ {0x01FC, 0x01FD, 0x00C6}, {0x01FC, 0x01FD, 0x00C6},
+ {0x01FE, 0x01FF, 0x00D8}, {0x01FE, 0x01FF, 0x00D8}
+};
+
+static MY_UNICASE_INFO plane02[] = {
+ {0x0200, 0x0201, 0x0041}, {0x0200, 0x0201, 0x0041},
+ {0x0202, 0x0203, 0x0041}, {0x0202, 0x0203, 0x0041},
+ {0x0204, 0x0205, 0x0045}, {0x0204, 0x0205, 0x0045},
+ {0x0206, 0x0207, 0x0045}, {0x0206, 0x0207, 0x0045},
+ {0x0208, 0x0209, 0x0049}, {0x0208, 0x0209, 0x0049},
+ {0x020A, 0x020B, 0x0049}, {0x020A, 0x020B, 0x0049},
+ {0x020C, 0x020D, 0x004F}, {0x020C, 0x020D, 0x004F},
+ {0x020E, 0x020F, 0x004F}, {0x020E, 0x020F, 0x004F},
+ {0x0210, 0x0211, 0x0052}, {0x0210, 0x0211, 0x0052},
+ {0x0212, 0x0213, 0x0052}, {0x0212, 0x0213, 0x0052},
+ {0x0214, 0x0215, 0x0055}, {0x0214, 0x0215, 0x0055},
+ {0x0216, 0x0217, 0x0055}, {0x0216, 0x0217, 0x0055},
+ {0x0218, 0x0219, 0x0053}, {0x0218, 0x0219, 0x0053},
+ {0x021A, 0x021B, 0x0054}, {0x021A, 0x021B, 0x0054},
+ {0x021C, 0x021D, 0x021C}, {0x021C, 0x021D, 0x021C},
+ {0x021E, 0x021F, 0x0048}, {0x021E, 0x021F, 0x0048},
+ {0x0220, 0x0220, 0x0220}, {0x0221, 0x0221, 0x0221},
+ {0x0222, 0x0223, 0x0222}, {0x0222, 0x0223, 0x0222},
+ {0x0224, 0x0225, 0x0224}, {0x0224, 0x0225, 0x0224},
+ {0x0226, 0x0227, 0x0041}, {0x0226, 0x0227, 0x0041},
+ {0x0228, 0x0229, 0x0045}, {0x0228, 0x0229, 0x0045},
+ {0x022A, 0x022B, 0x004F}, {0x022A, 0x022B, 0x004F},
+ {0x022C, 0x022D, 0x004F}, {0x022C, 0x022D, 0x004F},
+ {0x022E, 0x022F, 0x004F}, {0x022E, 0x022F, 0x004F},
+ {0x0230, 0x0231, 0x004F}, {0x0230, 0x0231, 0x004F},
+ {0x0232, 0x0233, 0x0059}, {0x0232, 0x0233, 0x0059},
+ {0x0234, 0x0234, 0x0234}, {0x0235, 0x0235, 0x0235},
+ {0x0236, 0x0236, 0x0236}, {0x0237, 0x0237, 0x0237},
+ {0x0238, 0x0238, 0x0238}, {0x0239, 0x0239, 0x0239},
+ {0x023A, 0x023A, 0x023A}, {0x023B, 0x023B, 0x023B},
+ {0x023C, 0x023C, 0x023C}, {0x023D, 0x023D, 0x023D},
+ {0x023E, 0x023E, 0x023E}, {0x023F, 0x023F, 0x023F},
+ {0x0240, 0x0240, 0x0240}, {0x0241, 0x0241, 0x0241},
+ {0x0242, 0x0242, 0x0242}, {0x0243, 0x0243, 0x0243},
+ {0x0244, 0x0244, 0x0244}, {0x0245, 0x0245, 0x0245},
+ {0x0246, 0x0246, 0x0246}, {0x0247, 0x0247, 0x0247},
+ {0x0248, 0x0248, 0x0248}, {0x0249, 0x0249, 0x0249},
+ {0x024A, 0x024A, 0x024A}, {0x024B, 0x024B, 0x024B},
+ {0x024C, 0x024C, 0x024C}, {0x024D, 0x024D, 0x024D},
+ {0x024E, 0x024E, 0x024E}, {0x024F, 0x024F, 0x024F},
+ {0x0250, 0x0250, 0x0250}, {0x0251, 0x0251, 0x0251},
+ {0x0252, 0x0252, 0x0252}, {0x0181, 0x0253, 0x0181},
+ {0x0186, 0x0254, 0x0186}, {0x0255, 0x0255, 0x0255},
+ {0x0189, 0x0256, 0x0189}, {0x018A, 0x0257, 0x018A},
+ {0x0258, 0x0258, 0x0258}, {0x018F, 0x0259, 0x018F},
+ {0x025A, 0x025A, 0x025A}, {0x0190, 0x025B, 0x0190},
+ {0x025C, 0x025C, 0x025C}, {0x025D, 0x025D, 0x025D},
+ {0x025E, 0x025E, 0x025E}, {0x025F, 0x025F, 0x025F},
+ {0x0193, 0x0260, 0x0193}, {0x0261, 0x0261, 0x0261},
+ {0x0262, 0x0262, 0x0262}, {0x0194, 0x0263, 0x0194},
+ {0x0264, 0x0264, 0x0264}, {0x0265, 0x0265, 0x0265},
+ {0x0266, 0x0266, 0x0266}, {0x0267, 0x0267, 0x0267},
+ {0x0197, 0x0268, 0x0197}, {0x0196, 0x0269, 0x0196},
+ {0x026A, 0x026A, 0x026A}, {0x026B, 0x026B, 0x026B},
+ {0x026C, 0x026C, 0x026C}, {0x026D, 0x026D, 0x026D},
+ {0x026E, 0x026E, 0x026E}, {0x019C, 0x026F, 0x019C},
+ {0x0270, 0x0270, 0x0270}, {0x0271, 0x0271, 0x0271},
+ {0x019D, 0x0272, 0x019D}, {0x0273, 0x0273, 0x0273},
+ {0x0274, 0x0274, 0x0274}, {0x019F, 0x0275, 0x019F},
+ {0x0276, 0x0276, 0x0276}, {0x0277, 0x0277, 0x0277},
+ {0x0278, 0x0278, 0x0278}, {0x0279, 0x0279, 0x0279},
+ {0x027A, 0x027A, 0x027A}, {0x027B, 0x027B, 0x027B},
+ {0x027C, 0x027C, 0x027C}, {0x027D, 0x027D, 0x027D},
+ {0x027E, 0x027E, 0x027E}, {0x027F, 0x027F, 0x027F},
+ {0x01A6, 0x0280, 0x01A6}, {0x0281, 0x0281, 0x0281},
+ {0x0282, 0x0282, 0x0282}, {0x01A9, 0x0283, 0x01A9},
+ {0x0284, 0x0284, 0x0284}, {0x0285, 0x0285, 0x0285},
+ {0x0286, 0x0286, 0x0286}, {0x0287, 0x0287, 0x0287},
+ {0x01AE, 0x0288, 0x01AE}, {0x0289, 0x0289, 0x0289},
+ {0x01B1, 0x028A, 0x01B1}, {0x01B2, 0x028B, 0x01B2},
+ {0x028C, 0x028C, 0x028C}, {0x028D, 0x028D, 0x028D},
+ {0x028E, 0x028E, 0x028E}, {0x028F, 0x028F, 0x028F},
+ {0x0290, 0x0290, 0x0290}, {0x0291, 0x0291, 0x0291},
+ {0x01B7, 0x0292, 0x01B7}, {0x0293, 0x0293, 0x0293},
+ {0x0294, 0x0294, 0x0294}, {0x0295, 0x0295, 0x0295},
+ {0x0296, 0x0296, 0x0296}, {0x0297, 0x0297, 0x0297},
+ {0x0298, 0x0298, 0x0298}, {0x0299, 0x0299, 0x0299},
+ {0x029A, 0x029A, 0x029A}, {0x029B, 0x029B, 0x029B},
+ {0x029C, 0x029C, 0x029C}, {0x029D, 0x029D, 0x029D},
+ {0x029E, 0x029E, 0x029E}, {0x029F, 0x029F, 0x029F},
+ {0x02A0, 0x02A0, 0x02A0}, {0x02A1, 0x02A1, 0x02A1},
+ {0x02A2, 0x02A2, 0x02A2}, {0x02A3, 0x02A3, 0x02A3},
+ {0x02A4, 0x02A4, 0x02A4}, {0x02A5, 0x02A5, 0x02A5},
+ {0x02A6, 0x02A6, 0x02A6}, {0x02A7, 0x02A7, 0x02A7},
+ {0x02A8, 0x02A8, 0x02A8}, {0x02A9, 0x02A9, 0x02A9},
+ {0x02AA, 0x02AA, 0x02AA}, {0x02AB, 0x02AB, 0x02AB},
+ {0x02AC, 0x02AC, 0x02AC}, {0x02AD, 0x02AD, 0x02AD},
+ {0x02AE, 0x02AE, 0x02AE}, {0x02AF, 0x02AF, 0x02AF},
+ {0x02B0, 0x02B0, 0x02B0}, {0x02B1, 0x02B1, 0x02B1},
+ {0x02B2, 0x02B2, 0x02B2}, {0x02B3, 0x02B3, 0x02B3},
+ {0x02B4, 0x02B4, 0x02B4}, {0x02B5, 0x02B5, 0x02B5},
+ {0x02B6, 0x02B6, 0x02B6}, {0x02B7, 0x02B7, 0x02B7},
+ {0x02B8, 0x02B8, 0x02B8}, {0x02B9, 0x02B9, 0x02B9},
+ {0x02BA, 0x02BA, 0x02BA}, {0x02BB, 0x02BB, 0x02BB},
+ {0x02BC, 0x02BC, 0x02BC}, {0x02BD, 0x02BD, 0x02BD},
+ {0x02BE, 0x02BE, 0x02BE}, {0x02BF, 0x02BF, 0x02BF},
+ {0x02C0, 0x02C0, 0x02C0}, {0x02C1, 0x02C1, 0x02C1},
+ {0x02C2, 0x02C2, 0x02C2}, {0x02C3, 0x02C3, 0x02C3},
+ {0x02C4, 0x02C4, 0x02C4}, {0x02C5, 0x02C5, 0x02C5},
+ {0x02C6, 0x02C6, 0x02C6}, {0x02C7, 0x02C7, 0x02C7},
+ {0x02C8, 0x02C8, 0x02C8}, {0x02C9, 0x02C9, 0x02C9},
+ {0x02CA, 0x02CA, 0x02CA}, {0x02CB, 0x02CB, 0x02CB},
+ {0x02CC, 0x02CC, 0x02CC}, {0x02CD, 0x02CD, 0x02CD},
+ {0x02CE, 0x02CE, 0x02CE}, {0x02CF, 0x02CF, 0x02CF},
+ {0x02D0, 0x02D0, 0x02D0}, {0x02D1, 0x02D1, 0x02D1},
+ {0x02D2, 0x02D2, 0x02D2}, {0x02D3, 0x02D3, 0x02D3},
+ {0x02D4, 0x02D4, 0x02D4}, {0x02D5, 0x02D5, 0x02D5},
+ {0x02D6, 0x02D6, 0x02D6}, {0x02D7, 0x02D7, 0x02D7},
+ {0x02D8, 0x02D8, 0x02D8}, {0x02D9, 0x02D9, 0x02D9},
+ {0x02DA, 0x02DA, 0x02DA}, {0x02DB, 0x02DB, 0x02DB},
+ {0x02DC, 0x02DC, 0x02DC}, {0x02DD, 0x02DD, 0x02DD},
+ {0x02DE, 0x02DE, 0x02DE}, {0x02DF, 0x02DF, 0x02DF},
+ {0x02E0, 0x02E0, 0x02E0}, {0x02E1, 0x02E1, 0x02E1},
+ {0x02E2, 0x02E2, 0x02E2}, {0x02E3, 0x02E3, 0x02E3},
+ {0x02E4, 0x02E4, 0x02E4}, {0x02E5, 0x02E5, 0x02E5},
+ {0x02E6, 0x02E6, 0x02E6}, {0x02E7, 0x02E7, 0x02E7},
+ {0x02E8, 0x02E8, 0x02E8}, {0x02E9, 0x02E9, 0x02E9},
+ {0x02EA, 0x02EA, 0x02EA}, {0x02EB, 0x02EB, 0x02EB},
+ {0x02EC, 0x02EC, 0x02EC}, {0x02ED, 0x02ED, 0x02ED},
+ {0x02EE, 0x02EE, 0x02EE}, {0x02EF, 0x02EF, 0x02EF},
+ {0x02F0, 0x02F0, 0x02F0}, {0x02F1, 0x02F1, 0x02F1},
+ {0x02F2, 0x02F2, 0x02F2}, {0x02F3, 0x02F3, 0x02F3},
+ {0x02F4, 0x02F4, 0x02F4}, {0x02F5, 0x02F5, 0x02F5},
+ {0x02F6, 0x02F6, 0x02F6}, {0x02F7, 0x02F7, 0x02F7},
+ {0x02F8, 0x02F8, 0x02F8}, {0x02F9, 0x02F9, 0x02F9},
+ {0x02FA, 0x02FA, 0x02FA}, {0x02FB, 0x02FB, 0x02FB},
+ {0x02FC, 0x02FC, 0x02FC}, {0x02FD, 0x02FD, 0x02FD},
+ {0x02FE, 0x02FE, 0x02FE}, {0x02FF, 0x02FF, 0x02FF}
+};
+
+static MY_UNICASE_INFO plane03[] = {
+ {0x0300, 0x0300, 0x0300}, {0x0301, 0x0301, 0x0301},
+ {0x0302, 0x0302, 0x0302}, {0x0303, 0x0303, 0x0303},
+ {0x0304, 0x0304, 0x0304}, {0x0305, 0x0305, 0x0305},
+ {0x0306, 0x0306, 0x0306}, {0x0307, 0x0307, 0x0307},
+ {0x0308, 0x0308, 0x0308}, {0x0309, 0x0309, 0x0309},
+ {0x030A, 0x030A, 0x030A}, {0x030B, 0x030B, 0x030B},
+ {0x030C, 0x030C, 0x030C}, {0x030D, 0x030D, 0x030D},
+ {0x030E, 0x030E, 0x030E}, {0x030F, 0x030F, 0x030F},
+ {0x0310, 0x0310, 0x0310}, {0x0311, 0x0311, 0x0311},
+ {0x0312, 0x0312, 0x0312}, {0x0313, 0x0313, 0x0313},
+ {0x0314, 0x0314, 0x0314}, {0x0315, 0x0315, 0x0315},
+ {0x0316, 0x0316, 0x0316}, {0x0317, 0x0317, 0x0317},
+ {0x0318, 0x0318, 0x0318}, {0x0319, 0x0319, 0x0319},
+ {0x031A, 0x031A, 0x031A}, {0x031B, 0x031B, 0x031B},
+ {0x031C, 0x031C, 0x031C}, {0x031D, 0x031D, 0x031D},
+ {0x031E, 0x031E, 0x031E}, {0x031F, 0x031F, 0x031F},
+ {0x0320, 0x0320, 0x0320}, {0x0321, 0x0321, 0x0321},
+ {0x0322, 0x0322, 0x0322}, {0x0323, 0x0323, 0x0323},
+ {0x0324, 0x0324, 0x0324}, {0x0325, 0x0325, 0x0325},
+ {0x0326, 0x0326, 0x0326}, {0x0327, 0x0327, 0x0327},
+ {0x0328, 0x0328, 0x0328}, {0x0329, 0x0329, 0x0329},
+ {0x032A, 0x032A, 0x032A}, {0x032B, 0x032B, 0x032B},
+ {0x032C, 0x032C, 0x032C}, {0x032D, 0x032D, 0x032D},
+ {0x032E, 0x032E, 0x032E}, {0x032F, 0x032F, 0x032F},
+ {0x0330, 0x0330, 0x0330}, {0x0331, 0x0331, 0x0331},
+ {0x0332, 0x0332, 0x0332}, {0x0333, 0x0333, 0x0333},
+ {0x0334, 0x0334, 0x0334}, {0x0335, 0x0335, 0x0335},
+ {0x0336, 0x0336, 0x0336}, {0x0337, 0x0337, 0x0337},
+ {0x0338, 0x0338, 0x0338}, {0x0339, 0x0339, 0x0339},
+ {0x033A, 0x033A, 0x033A}, {0x033B, 0x033B, 0x033B},
+ {0x033C, 0x033C, 0x033C}, {0x033D, 0x033D, 0x033D},
+ {0x033E, 0x033E, 0x033E}, {0x033F, 0x033F, 0x033F},
+ {0x0340, 0x0340, 0x0340}, {0x0341, 0x0341, 0x0341},
+ {0x0342, 0x0342, 0x0342}, {0x0343, 0x0343, 0x0343},
+ {0x0344, 0x0344, 0x0344}, {0x0399, 0x0345, 0x0399},
+ {0x0346, 0x0346, 0x0346}, {0x0347, 0x0347, 0x0347},
+ {0x0348, 0x0348, 0x0348}, {0x0349, 0x0349, 0x0349},
+ {0x034A, 0x034A, 0x034A}, {0x034B, 0x034B, 0x034B},
+ {0x034C, 0x034C, 0x034C}, {0x034D, 0x034D, 0x034D},
+ {0x034E, 0x034E, 0x034E}, {0x034F, 0x034F, 0x034F},
+ {0x0350, 0x0350, 0x0350}, {0x0351, 0x0351, 0x0351},
+ {0x0352, 0x0352, 0x0352}, {0x0353, 0x0353, 0x0353},
+ {0x0354, 0x0354, 0x0354}, {0x0355, 0x0355, 0x0355},
+ {0x0356, 0x0356, 0x0356}, {0x0357, 0x0357, 0x0357},
+ {0x0358, 0x0358, 0x0358}, {0x0359, 0x0359, 0x0359},
+ {0x035A, 0x035A, 0x035A}, {0x035B, 0x035B, 0x035B},
+ {0x035C, 0x035C, 0x035C}, {0x035D, 0x035D, 0x035D},
+ {0x035E, 0x035E, 0x035E}, {0x035F, 0x035F, 0x035F},
+ {0x0360, 0x0360, 0x0360}, {0x0361, 0x0361, 0x0361},
+ {0x0362, 0x0362, 0x0362}, {0x0363, 0x0363, 0x0363},
+ {0x0364, 0x0364, 0x0364}, {0x0365, 0x0365, 0x0365},
+ {0x0366, 0x0366, 0x0366}, {0x0367, 0x0367, 0x0367},
+ {0x0368, 0x0368, 0x0368}, {0x0369, 0x0369, 0x0369},
+ {0x036A, 0x036A, 0x036A}, {0x036B, 0x036B, 0x036B},
+ {0x036C, 0x036C, 0x036C}, {0x036D, 0x036D, 0x036D},
+ {0x036E, 0x036E, 0x036E}, {0x036F, 0x036F, 0x036F},
+ {0x0370, 0x0370, 0x0370}, {0x0371, 0x0371, 0x0371},
+ {0x0372, 0x0372, 0x0372}, {0x0373, 0x0373, 0x0373},
+ {0x0374, 0x0374, 0x0374}, {0x0375, 0x0375, 0x0375},
+ {0x0376, 0x0376, 0x0376}, {0x0377, 0x0377, 0x0377},
+ {0x0378, 0x0378, 0x0378}, {0x0379, 0x0379, 0x0379},
+ {0x037A, 0x037A, 0x037A}, {0x037B, 0x037B, 0x037B},
+ {0x037C, 0x037C, 0x037C}, {0x037D, 0x037D, 0x037D},
+ {0x037E, 0x037E, 0x037E}, {0x037F, 0x037F, 0x037F},
+ {0x0380, 0x0380, 0x0380}, {0x0381, 0x0381, 0x0381},
+ {0x0382, 0x0382, 0x0382}, {0x0383, 0x0383, 0x0383},
+ {0x0384, 0x0384, 0x0384}, {0x0385, 0x0385, 0x0385},
+ {0x0386, 0x03AC, 0x0391}, {0x0387, 0x0387, 0x0387},
+ {0x0388, 0x03AD, 0x0395}, {0x0389, 0x03AE, 0x0397},
+ {0x038A, 0x03AF, 0x0399}, {0x038B, 0x038B, 0x038B},
+ {0x038C, 0x03CC, 0x039F}, {0x038D, 0x038D, 0x038D},
+ {0x038E, 0x03CD, 0x03A5}, {0x038F, 0x03CE, 0x03A9},
+ {0x0390, 0x0390, 0x0399}, {0x0391, 0x03B1, 0x0391},
+ {0x0392, 0x03B2, 0x0392}, {0x0393, 0x03B3, 0x0393},
+ {0x0394, 0x03B4, 0x0394}, {0x0395, 0x03B5, 0x0395},
+ {0x0396, 0x03B6, 0x0396}, {0x0397, 0x03B7, 0x0397},
+ {0x0398, 0x03B8, 0x0398}, {0x0399, 0x03B9, 0x0399},
+ {0x039A, 0x03BA, 0x039A}, {0x039B, 0x03BB, 0x039B},
+ {0x039C, 0x03BC, 0x039C}, {0x039D, 0x03BD, 0x039D},
+ {0x039E, 0x03BE, 0x039E}, {0x039F, 0x03BF, 0x039F},
+ {0x03A0, 0x03C0, 0x03A0}, {0x03A1, 0x03C1, 0x03A1},
+ {0x03A2, 0x03A2, 0x03A2}, {0x03A3, 0x03C3, 0x03A3},
+ {0x03A4, 0x03C4, 0x03A4}, {0x03A5, 0x03C5, 0x03A5},
+ {0x03A6, 0x03C6, 0x03A6}, {0x03A7, 0x03C7, 0x03A7},
+ {0x03A8, 0x03C8, 0x03A8}, {0x03A9, 0x03C9, 0x03A9},
+ {0x03AA, 0x03CA, 0x0399}, {0x03AB, 0x03CB, 0x03A5},
+ {0x0386, 0x03AC, 0x0391}, {0x0388, 0x03AD, 0x0395},
+ {0x0389, 0x03AE, 0x0397}, {0x038A, 0x03AF, 0x0399},
+ {0x03B0, 0x03B0, 0x03A5}, {0x0391, 0x03B1, 0x0391},
+ {0x0392, 0x03B2, 0x0392}, {0x0393, 0x03B3, 0x0393},
+ {0x0394, 0x03B4, 0x0394}, {0x0395, 0x03B5, 0x0395},
+ {0x0396, 0x03B6, 0x0396}, {0x0397, 0x03B7, 0x0397},
+ {0x0398, 0x03B8, 0x0398}, {0x0399, 0x03B9, 0x0399},
+ {0x039A, 0x03BA, 0x039A}, {0x039B, 0x03BB, 0x039B},
+ {0x039C, 0x03BC, 0x039C}, {0x039D, 0x03BD, 0x039D},
+ {0x039E, 0x03BE, 0x039E}, {0x039F, 0x03BF, 0x039F},
+ {0x03A0, 0x03C0, 0x03A0}, {0x03A1, 0x03C1, 0x03A1},
+ {0x03A3, 0x03C2, 0x03A3}, {0x03A3, 0x03C3, 0x03A3},
+ {0x03A4, 0x03C4, 0x03A4}, {0x03A5, 0x03C5, 0x03A5},
+ {0x03A6, 0x03C6, 0x03A6}, {0x03A7, 0x03C7, 0x03A7},
+ {0x03A8, 0x03C8, 0x03A8}, {0x03A9, 0x03C9, 0x03A9},
+ {0x03AA, 0x03CA, 0x0399}, {0x03AB, 0x03CB, 0x03A5},
+ {0x038C, 0x03CC, 0x039F}, {0x038E, 0x03CD, 0x03A5},
+ {0x038F, 0x03CE, 0x03A9}, {0x03CF, 0x03CF, 0x03CF},
+ {0x0392, 0x03D0, 0x0392}, {0x0398, 0x03D1, 0x0398},
+ {0x03D2, 0x03D2, 0x03D2}, {0x03D3, 0x03D3, 0x03D2},
+ {0x03D4, 0x03D4, 0x03D2}, {0x03A6, 0x03D5, 0x03A6},
+ {0x03A0, 0x03D6, 0x03A0}, {0x03D7, 0x03D7, 0x03D7},
+ {0x03D8, 0x03D8, 0x03D8}, {0x03D9, 0x03D9, 0x03D9},
+ {0x03DA, 0x03DB, 0x03DA}, {0x03DA, 0x03DB, 0x03DA},
+ {0x03DC, 0x03DD, 0x03DC}, {0x03DC, 0x03DD, 0x03DC},
+ {0x03DE, 0x03DF, 0x03DE}, {0x03DE, 0x03DF, 0x03DE},
+ {0x03E0, 0x03E1, 0x03E0}, {0x03E0, 0x03E1, 0x03E0},
+ {0x03E2, 0x03E3, 0x03E2}, {0x03E2, 0x03E3, 0x03E2},
+ {0x03E4, 0x03E5, 0x03E4}, {0x03E4, 0x03E5, 0x03E4},
+ {0x03E6, 0x03E7, 0x03E6}, {0x03E6, 0x03E7, 0x03E6},
+ {0x03E8, 0x03E9, 0x03E8}, {0x03E8, 0x03E9, 0x03E8},
+ {0x03EA, 0x03EB, 0x03EA}, {0x03EA, 0x03EB, 0x03EA},
+ {0x03EC, 0x03ED, 0x03EC}, {0x03EC, 0x03ED, 0x03EC},
+ {0x03EE, 0x03EF, 0x03EE}, {0x03EE, 0x03EF, 0x03EE},
+ {0x039A, 0x03F0, 0x039A}, {0x03A1, 0x03F1, 0x03A1},
+ {0x03A3, 0x03F2, 0x03A3}, {0x03F3, 0x03F3, 0x03F3},
+ {0x03F4, 0x03F4, 0x03F4}, {0x03F5, 0x03F5, 0x03F5},
+ {0x03F6, 0x03F6, 0x03F6}, {0x03F7, 0x03F7, 0x03F7},
+ {0x03F8, 0x03F8, 0x03F8}, {0x03F9, 0x03F9, 0x03F9},
+ {0x03FA, 0x03FA, 0x03FA}, {0x03FB, 0x03FB, 0x03FB},
+ {0x03FC, 0x03FC, 0x03FC}, {0x03FD, 0x03FD, 0x03FD},
+ {0x03FE, 0x03FE, 0x03FE}, {0x03FF, 0x03FF, 0x03FF}
+};
+
+static MY_UNICASE_INFO plane04[] = {
+ {0x0400, 0x0450, 0x0415}, {0x0401, 0x0451, 0x0415},
+ {0x0402, 0x0452, 0x0402}, {0x0403, 0x0453, 0x0413},
+ {0x0404, 0x0454, 0x0404}, {0x0405, 0x0455, 0x0405},
+ {0x0406, 0x0456, 0x0406}, {0x0407, 0x0457, 0x0406},
+ {0x0408, 0x0458, 0x0408}, {0x0409, 0x0459, 0x0409},
+ {0x040A, 0x045A, 0x040A}, {0x040B, 0x045B, 0x040B},
+ {0x040C, 0x045C, 0x041A}, {0x040D, 0x045D, 0x0418},
+ {0x040E, 0x045E, 0x0423}, {0x040F, 0x045F, 0x040F},
+ {0x0410, 0x0430, 0x0410}, {0x0411, 0x0431, 0x0411},
+ {0x0412, 0x0432, 0x0412}, {0x0413, 0x0433, 0x0413},
+ {0x0414, 0x0434, 0x0414}, {0x0415, 0x0435, 0x0415},
+ {0x0416, 0x0436, 0x0416}, {0x0417, 0x0437, 0x0417},
+ {0x0418, 0x0438, 0x0418}, {0x0419, 0x0439, 0x0418},
+ {0x041A, 0x043A, 0x041A}, {0x041B, 0x043B, 0x041B},
+ {0x041C, 0x043C, 0x041C}, {0x041D, 0x043D, 0x041D},
+ {0x041E, 0x043E, 0x041E}, {0x041F, 0x043F, 0x041F},
+ {0x0420, 0x0440, 0x0420}, {0x0421, 0x0441, 0x0421},
+ {0x0422, 0x0442, 0x0422}, {0x0423, 0x0443, 0x0423},
+ {0x0424, 0x0444, 0x0424}, {0x0425, 0x0445, 0x0425},
+ {0x0426, 0x0446, 0x0426}, {0x0427, 0x0447, 0x0427},
+ {0x0428, 0x0448, 0x0428}, {0x0429, 0x0449, 0x0429},
+ {0x042A, 0x044A, 0x042A}, {0x042B, 0x044B, 0x042B},
+ {0x042C, 0x044C, 0x042C}, {0x042D, 0x044D, 0x042D},
+ {0x042E, 0x044E, 0x042E}, {0x042F, 0x044F, 0x042F},
+ {0x0410, 0x0430, 0x0410}, {0x0411, 0x0431, 0x0411},
+ {0x0412, 0x0432, 0x0412}, {0x0413, 0x0433, 0x0413},
+ {0x0414, 0x0434, 0x0414}, {0x0415, 0x0435, 0x0415},
+ {0x0416, 0x0436, 0x0416}, {0x0417, 0x0437, 0x0417},
+ {0x0418, 0x0438, 0x0418}, {0x0419, 0x0439, 0x0418},
+ {0x041A, 0x043A, 0x041A}, {0x041B, 0x043B, 0x041B},
+ {0x041C, 0x043C, 0x041C}, {0x041D, 0x043D, 0x041D},
+ {0x041E, 0x043E, 0x041E}, {0x041F, 0x043F, 0x041F},
+ {0x0420, 0x0440, 0x0420}, {0x0421, 0x0441, 0x0421},
+ {0x0422, 0x0442, 0x0422}, {0x0423, 0x0443, 0x0423},
+ {0x0424, 0x0444, 0x0424}, {0x0425, 0x0445, 0x0425},
+ {0x0426, 0x0446, 0x0426}, {0x0427, 0x0447, 0x0427},
+ {0x0428, 0x0448, 0x0428}, {0x0429, 0x0449, 0x0429},
+ {0x042A, 0x044A, 0x042A}, {0x042B, 0x044B, 0x042B},
+ {0x042C, 0x044C, 0x042C}, {0x042D, 0x044D, 0x042D},
+ {0x042E, 0x044E, 0x042E}, {0x042F, 0x044F, 0x042F},
+ {0x0400, 0x0450, 0x0415}, {0x0401, 0x0451, 0x0415},
+ {0x0402, 0x0452, 0x0402}, {0x0403, 0x0453, 0x0413},
+ {0x0404, 0x0454, 0x0404}, {0x0405, 0x0455, 0x0405},
+ {0x0406, 0x0456, 0x0406}, {0x0407, 0x0457, 0x0406},
+ {0x0408, 0x0458, 0x0408}, {0x0409, 0x0459, 0x0409},
+ {0x040A, 0x045A, 0x040A}, {0x040B, 0x045B, 0x040B},
+ {0x040C, 0x045C, 0x041A}, {0x040D, 0x045D, 0x0418},
+ {0x040E, 0x045E, 0x0423}, {0x040F, 0x045F, 0x040F},
+ {0x0460, 0x0461, 0x0460}, {0x0460, 0x0461, 0x0460},
+ {0x0462, 0x0463, 0x0462}, {0x0462, 0x0463, 0x0462},
+ {0x0464, 0x0465, 0x0464}, {0x0464, 0x0465, 0x0464},
+ {0x0466, 0x0467, 0x0466}, {0x0466, 0x0467, 0x0466},
+ {0x0468, 0x0469, 0x0468}, {0x0468, 0x0469, 0x0468},
+ {0x046A, 0x046B, 0x046A}, {0x046A, 0x046B, 0x046A},
+ {0x046C, 0x046D, 0x046C}, {0x046C, 0x046D, 0x046C},
+ {0x046E, 0x046F, 0x046E}, {0x046E, 0x046F, 0x046E},
+ {0x0470, 0x0471, 0x0470}, {0x0470, 0x0471, 0x0470},
+ {0x0472, 0x0473, 0x0472}, {0x0472, 0x0473, 0x0472},
+ {0x0474, 0x0475, 0x0474}, {0x0474, 0x0475, 0x0474},
+ {0x0476, 0x0477, 0x0474}, {0x0476, 0x0477, 0x0474},
+ {0x0478, 0x0479, 0x0478}, {0x0478, 0x0479, 0x0478},
+ {0x047A, 0x047B, 0x047A}, {0x047A, 0x047B, 0x047A},
+ {0x047C, 0x047D, 0x047C}, {0x047C, 0x047D, 0x047C},
+ {0x047E, 0x047F, 0x047E}, {0x047E, 0x047F, 0x047E},
+ {0x0480, 0x0481, 0x0480}, {0x0480, 0x0481, 0x0480},
+ {0x0482, 0x0482, 0x0482}, {0x0483, 0x0483, 0x0483},
+ {0x0484, 0x0484, 0x0484}, {0x0485, 0x0485, 0x0485},
+ {0x0486, 0x0486, 0x0486}, {0x0487, 0x0487, 0x0487},
+ {0x0488, 0x0488, 0x0488}, {0x0489, 0x0489, 0x0489},
+ {0x048A, 0x048A, 0x048A}, {0x048B, 0x048B, 0x048B},
+ {0x048C, 0x048D, 0x048C}, {0x048C, 0x048D, 0x048C},
+ {0x048E, 0x048F, 0x048E}, {0x048E, 0x048F, 0x048E},
+ {0x0490, 0x0491, 0x0490}, {0x0490, 0x0491, 0x0490},
+ {0x0492, 0x0493, 0x0492}, {0x0492, 0x0493, 0x0492},
+ {0x0494, 0x0495, 0x0494}, {0x0494, 0x0495, 0x0494},
+ {0x0496, 0x0497, 0x0496}, {0x0496, 0x0497, 0x0496},
+ {0x0498, 0x0499, 0x0498}, {0x0498, 0x0499, 0x0498},
+ {0x049A, 0x049B, 0x049A}, {0x049A, 0x049B, 0x049A},
+ {0x049C, 0x049D, 0x049C}, {0x049C, 0x049D, 0x049C},
+ {0x049E, 0x049F, 0x049E}, {0x049E, 0x049F, 0x049E},
+ {0x04A0, 0x04A1, 0x04A0}, {0x04A0, 0x04A1, 0x04A0},
+ {0x04A2, 0x04A3, 0x04A2}, {0x04A2, 0x04A3, 0x04A2},
+ {0x04A4, 0x04A5, 0x04A4}, {0x04A4, 0x04A5, 0x04A4},
+ {0x04A6, 0x04A7, 0x04A6}, {0x04A6, 0x04A7, 0x04A6},
+ {0x04A8, 0x04A9, 0x04A8}, {0x04A8, 0x04A9, 0x04A8},
+ {0x04AA, 0x04AB, 0x04AA}, {0x04AA, 0x04AB, 0x04AA},
+ {0x04AC, 0x04AD, 0x04AC}, {0x04AC, 0x04AD, 0x04AC},
+ {0x04AE, 0x04AF, 0x04AE}, {0x04AE, 0x04AF, 0x04AE},
+ {0x04B0, 0x04B1, 0x04B0}, {0x04B0, 0x04B1, 0x04B0},
+ {0x04B2, 0x04B3, 0x04B2}, {0x04B2, 0x04B3, 0x04B2},
+ {0x04B4, 0x04B5, 0x04B4}, {0x04B4, 0x04B5, 0x04B4},
+ {0x04B6, 0x04B7, 0x04B6}, {0x04B6, 0x04B7, 0x04B6},
+ {0x04B8, 0x04B9, 0x04B8}, {0x04B8, 0x04B9, 0x04B8},
+ {0x04BA, 0x04BB, 0x04BA}, {0x04BA, 0x04BB, 0x04BA},
+ {0x04BC, 0x04BD, 0x04BC}, {0x04BC, 0x04BD, 0x04BC},
+ {0x04BE, 0x04BF, 0x04BE}, {0x04BE, 0x04BF, 0x04BE},
+ {0x04C0, 0x04C0, 0x04C0}, {0x04C1, 0x04C2, 0x0416},
+ {0x04C1, 0x04C2, 0x0416}, {0x04C3, 0x04C4, 0x04C3},
+ {0x04C3, 0x04C4, 0x04C3}, {0x04C5, 0x04C5, 0x04C5},
+ {0x04C6, 0x04C6, 0x04C6}, {0x04C7, 0x04C8, 0x04C7},
+ {0x04C7, 0x04C8, 0x04C7}, {0x04C9, 0x04C9, 0x04C9},
+ {0x04CA, 0x04CA, 0x04CA}, {0x04CB, 0x04CC, 0x04CB},
+ {0x04CB, 0x04CC, 0x04CB}, {0x04CD, 0x04CD, 0x04CD},
+ {0x04CE, 0x04CE, 0x04CE}, {0x04CF, 0x04CF, 0x04CF},
+ {0x04D0, 0x04D1, 0x0410}, {0x04D0, 0x04D1, 0x0410},
+ {0x04D2, 0x04D3, 0x0410}, {0x04D2, 0x04D3, 0x0410},
+ {0x04D4, 0x04D5, 0x04D4}, {0x04D4, 0x04D5, 0x04D4},
+ {0x04D6, 0x04D7, 0x0415}, {0x04D6, 0x04D7, 0x0415},
+ {0x04D8, 0x04D9, 0x04D8}, {0x04D8, 0x04D9, 0x04D8},
+ {0x04DA, 0x04DB, 0x04D8}, {0x04DA, 0x04DB, 0x04D8},
+ {0x04DC, 0x04DD, 0x0416}, {0x04DC, 0x04DD, 0x0416},
+ {0x04DE, 0x04DF, 0x0417}, {0x04DE, 0x04DF, 0x0417},
+ {0x04E0, 0x04E1, 0x04E0}, {0x04E0, 0x04E1, 0x04E0},
+ {0x04E2, 0x04E3, 0x0418}, {0x04E2, 0x04E3, 0x0418},
+ {0x04E4, 0x04E5, 0x0418}, {0x04E4, 0x04E5, 0x0418},
+ {0x04E6, 0x04E7, 0x041E}, {0x04E6, 0x04E7, 0x041E},
+ {0x04E8, 0x04E9, 0x04E8}, {0x04E8, 0x04E9, 0x04E8},
+ {0x04EA, 0x04EB, 0x04E8}, {0x04EA, 0x04EB, 0x04E8},
+ {0x04EC, 0x04ED, 0x042D}, {0x04EC, 0x04ED, 0x042D},
+ {0x04EE, 0x04EF, 0x0423}, {0x04EE, 0x04EF, 0x0423},
+ {0x04F0, 0x04F1, 0x0423}, {0x04F0, 0x04F1, 0x0423},
+ {0x04F2, 0x04F3, 0x0423}, {0x04F2, 0x04F3, 0x0423},
+ {0x04F4, 0x04F5, 0x0427}, {0x04F4, 0x04F5, 0x0427},
+ {0x04F6, 0x04F6, 0x04F6}, {0x04F7, 0x04F7, 0x04F7},
+ {0x04F8, 0x04F9, 0x042B}, {0x04F8, 0x04F9, 0x042B},
+ {0x04FA, 0x04FA, 0x04FA}, {0x04FB, 0x04FB, 0x04FB},
+ {0x04FC, 0x04FC, 0x04FC}, {0x04FD, 0x04FD, 0x04FD},
+ {0x04FE, 0x04FE, 0x04FE}, {0x04FF, 0x04FF, 0x04FF}
+};
+
+static MY_UNICASE_INFO plane05[] = {
+ {0x0500, 0x0500, 0x0500}, {0x0501, 0x0501, 0x0501},
+ {0x0502, 0x0502, 0x0502}, {0x0503, 0x0503, 0x0503},
+ {0x0504, 0x0504, 0x0504}, {0x0505, 0x0505, 0x0505},
+ {0x0506, 0x0506, 0x0506}, {0x0507, 0x0507, 0x0507},
+ {0x0508, 0x0508, 0x0508}, {0x0509, 0x0509, 0x0509},
+ {0x050A, 0x050A, 0x050A}, {0x050B, 0x050B, 0x050B},
+ {0x050C, 0x050C, 0x050C}, {0x050D, 0x050D, 0x050D},
+ {0x050E, 0x050E, 0x050E}, {0x050F, 0x050F, 0x050F},
+ {0x0510, 0x0510, 0x0510}, {0x0511, 0x0511, 0x0511},
+ {0x0512, 0x0512, 0x0512}, {0x0513, 0x0513, 0x0513},
+ {0x0514, 0x0514, 0x0514}, {0x0515, 0x0515, 0x0515},
+ {0x0516, 0x0516, 0x0516}, {0x0517, 0x0517, 0x0517},
+ {0x0518, 0x0518, 0x0518}, {0x0519, 0x0519, 0x0519},
+ {0x051A, 0x051A, 0x051A}, {0x051B, 0x051B, 0x051B},
+ {0x051C, 0x051C, 0x051C}, {0x051D, 0x051D, 0x051D},
+ {0x051E, 0x051E, 0x051E}, {0x051F, 0x051F, 0x051F},
+ {0x0520, 0x0520, 0x0520}, {0x0521, 0x0521, 0x0521},
+ {0x0522, 0x0522, 0x0522}, {0x0523, 0x0523, 0x0523},
+ {0x0524, 0x0524, 0x0524}, {0x0525, 0x0525, 0x0525},
+ {0x0526, 0x0526, 0x0526}, {0x0527, 0x0527, 0x0527},
+ {0x0528, 0x0528, 0x0528}, {0x0529, 0x0529, 0x0529},
+ {0x052A, 0x052A, 0x052A}, {0x052B, 0x052B, 0x052B},
+ {0x052C, 0x052C, 0x052C}, {0x052D, 0x052D, 0x052D},
+ {0x052E, 0x052E, 0x052E}, {0x052F, 0x052F, 0x052F},
+ {0x0530, 0x0530, 0x0530}, {0x0531, 0x0561, 0x0531},
+ {0x0532, 0x0562, 0x0532}, {0x0533, 0x0563, 0x0533},
+ {0x0534, 0x0564, 0x0534}, {0x0535, 0x0565, 0x0535},
+ {0x0536, 0x0566, 0x0536}, {0x0537, 0x0567, 0x0537},
+ {0x0538, 0x0568, 0x0538}, {0x0539, 0x0569, 0x0539},
+ {0x053A, 0x056A, 0x053A}, {0x053B, 0x056B, 0x053B},
+ {0x053C, 0x056C, 0x053C}, {0x053D, 0x056D, 0x053D},
+ {0x053E, 0x056E, 0x053E}, {0x053F, 0x056F, 0x053F},
+ {0x0540, 0x0570, 0x0540}, {0x0541, 0x0571, 0x0541},
+ {0x0542, 0x0572, 0x0542}, {0x0543, 0x0573, 0x0543},
+ {0x0544, 0x0574, 0x0544}, {0x0545, 0x0575, 0x0545},
+ {0x0546, 0x0576, 0x0546}, {0x0547, 0x0577, 0x0547},
+ {0x0548, 0x0578, 0x0548}, {0x0549, 0x0579, 0x0549},
+ {0x054A, 0x057A, 0x054A}, {0x054B, 0x057B, 0x054B},
+ {0x054C, 0x057C, 0x054C}, {0x054D, 0x057D, 0x054D},
+ {0x054E, 0x057E, 0x054E}, {0x054F, 0x057F, 0x054F},
+ {0x0550, 0x0580, 0x0550}, {0x0551, 0x0581, 0x0551},
+ {0x0552, 0x0582, 0x0552}, {0x0553, 0x0583, 0x0553},
+ {0x0554, 0x0584, 0x0554}, {0x0555, 0x0585, 0x0555},
+ {0x0556, 0x0586, 0x0556}, {0x0557, 0x0557, 0x0557},
+ {0x0558, 0x0558, 0x0558}, {0x0559, 0x0559, 0x0559},
+ {0x055A, 0x055A, 0x055A}, {0x055B, 0x055B, 0x055B},
+ {0x055C, 0x055C, 0x055C}, {0x055D, 0x055D, 0x055D},
+ {0x055E, 0x055E, 0x055E}, {0x055F, 0x055F, 0x055F},
+ {0x0560, 0x0560, 0x0560}, {0x0531, 0x0561, 0x0531},
+ {0x0532, 0x0562, 0x0532}, {0x0533, 0x0563, 0x0533},
+ {0x0534, 0x0564, 0x0534}, {0x0535, 0x0565, 0x0535},
+ {0x0536, 0x0566, 0x0536}, {0x0537, 0x0567, 0x0537},
+ {0x0538, 0x0568, 0x0538}, {0x0539, 0x0569, 0x0539},
+ {0x053A, 0x056A, 0x053A}, {0x053B, 0x056B, 0x053B},
+ {0x053C, 0x056C, 0x053C}, {0x053D, 0x056D, 0x053D},
+ {0x053E, 0x056E, 0x053E}, {0x053F, 0x056F, 0x053F},
+ {0x0540, 0x0570, 0x0540}, {0x0541, 0x0571, 0x0541},
+ {0x0542, 0x0572, 0x0542}, {0x0543, 0x0573, 0x0543},
+ {0x0544, 0x0574, 0x0544}, {0x0545, 0x0575, 0x0545},
+ {0x0546, 0x0576, 0x0546}, {0x0547, 0x0577, 0x0547},
+ {0x0548, 0x0578, 0x0548}, {0x0549, 0x0579, 0x0549},
+ {0x054A, 0x057A, 0x054A}, {0x054B, 0x057B, 0x054B},
+ {0x054C, 0x057C, 0x054C}, {0x054D, 0x057D, 0x054D},
+ {0x054E, 0x057E, 0x054E}, {0x054F, 0x057F, 0x054F},
+ {0x0550, 0x0580, 0x0550}, {0x0551, 0x0581, 0x0551},
+ {0x0552, 0x0582, 0x0552}, {0x0553, 0x0583, 0x0553},
+ {0x0554, 0x0584, 0x0554}, {0x0555, 0x0585, 0x0555},
+ {0x0556, 0x0586, 0x0556}, {0x0587, 0x0587, 0x0587},
+ {0x0588, 0x0588, 0x0588}, {0x0589, 0x0589, 0x0589},
+ {0x058A, 0x058A, 0x058A}, {0x058B, 0x058B, 0x058B},
+ {0x058C, 0x058C, 0x058C}, {0x058D, 0x058D, 0x058D},
+ {0x058E, 0x058E, 0x058E}, {0x058F, 0x058F, 0x058F},
+ {0x0590, 0x0590, 0x0590}, {0x0591, 0x0591, 0x0591},
+ {0x0592, 0x0592, 0x0592}, {0x0593, 0x0593, 0x0593},
+ {0x0594, 0x0594, 0x0594}, {0x0595, 0x0595, 0x0595},
+ {0x0596, 0x0596, 0x0596}, {0x0597, 0x0597, 0x0597},
+ {0x0598, 0x0598, 0x0598}, {0x0599, 0x0599, 0x0599},
+ {0x059A, 0x059A, 0x059A}, {0x059B, 0x059B, 0x059B},
+ {0x059C, 0x059C, 0x059C}, {0x059D, 0x059D, 0x059D},
+ {0x059E, 0x059E, 0x059E}, {0x059F, 0x059F, 0x059F},
+ {0x05A0, 0x05A0, 0x05A0}, {0x05A1, 0x05A1, 0x05A1},
+ {0x05A2, 0x05A2, 0x05A2}, {0x05A3, 0x05A3, 0x05A3},
+ {0x05A4, 0x05A4, 0x05A4}, {0x05A5, 0x05A5, 0x05A5},
+ {0x05A6, 0x05A6, 0x05A6}, {0x05A7, 0x05A7, 0x05A7},
+ {0x05A8, 0x05A8, 0x05A8}, {0x05A9, 0x05A9, 0x05A9},
+ {0x05AA, 0x05AA, 0x05AA}, {0x05AB, 0x05AB, 0x05AB},
+ {0x05AC, 0x05AC, 0x05AC}, {0x05AD, 0x05AD, 0x05AD},
+ {0x05AE, 0x05AE, 0x05AE}, {0x05AF, 0x05AF, 0x05AF},
+ {0x05B0, 0x05B0, 0x05B0}, {0x05B1, 0x05B1, 0x05B1},
+ {0x05B2, 0x05B2, 0x05B2}, {0x05B3, 0x05B3, 0x05B3},
+ {0x05B4, 0x05B4, 0x05B4}, {0x05B5, 0x05B5, 0x05B5},
+ {0x05B6, 0x05B6, 0x05B6}, {0x05B7, 0x05B7, 0x05B7},
+ {0x05B8, 0x05B8, 0x05B8}, {0x05B9, 0x05B9, 0x05B9},
+ {0x05BA, 0x05BA, 0x05BA}, {0x05BB, 0x05BB, 0x05BB},
+ {0x05BC, 0x05BC, 0x05BC}, {0x05BD, 0x05BD, 0x05BD},
+ {0x05BE, 0x05BE, 0x05BE}, {0x05BF, 0x05BF, 0x05BF},
+ {0x05C0, 0x05C0, 0x05C0}, {0x05C1, 0x05C1, 0x05C1},
+ {0x05C2, 0x05C2, 0x05C2}, {0x05C3, 0x05C3, 0x05C3},
+ {0x05C4, 0x05C4, 0x05C4}, {0x05C5, 0x05C5, 0x05C5},
+ {0x05C6, 0x05C6, 0x05C6}, {0x05C7, 0x05C7, 0x05C7},
+ {0x05C8, 0x05C8, 0x05C8}, {0x05C9, 0x05C9, 0x05C9},
+ {0x05CA, 0x05CA, 0x05CA}, {0x05CB, 0x05CB, 0x05CB},
+ {0x05CC, 0x05CC, 0x05CC}, {0x05CD, 0x05CD, 0x05CD},
+ {0x05CE, 0x05CE, 0x05CE}, {0x05CF, 0x05CF, 0x05CF},
+ {0x05D0, 0x05D0, 0x05D0}, {0x05D1, 0x05D1, 0x05D1},
+ {0x05D2, 0x05D2, 0x05D2}, {0x05D3, 0x05D3, 0x05D3},
+ {0x05D4, 0x05D4, 0x05D4}, {0x05D5, 0x05D5, 0x05D5},
+ {0x05D6, 0x05D6, 0x05D6}, {0x05D7, 0x05D7, 0x05D7},
+ {0x05D8, 0x05D8, 0x05D8}, {0x05D9, 0x05D9, 0x05D9},
+ {0x05DA, 0x05DA, 0x05DA}, {0x05DB, 0x05DB, 0x05DB},
+ {0x05DC, 0x05DC, 0x05DC}, {0x05DD, 0x05DD, 0x05DD},
+ {0x05DE, 0x05DE, 0x05DE}, {0x05DF, 0x05DF, 0x05DF},
+ {0x05E0, 0x05E0, 0x05E0}, {0x05E1, 0x05E1, 0x05E1},
+ {0x05E2, 0x05E2, 0x05E2}, {0x05E3, 0x05E3, 0x05E3},
+ {0x05E4, 0x05E4, 0x05E4}, {0x05E5, 0x05E5, 0x05E5},
+ {0x05E6, 0x05E6, 0x05E6}, {0x05E7, 0x05E7, 0x05E7},
+ {0x05E8, 0x05E8, 0x05E8}, {0x05E9, 0x05E9, 0x05E9},
+ {0x05EA, 0x05EA, 0x05EA}, {0x05EB, 0x05EB, 0x05EB},
+ {0x05EC, 0x05EC, 0x05EC}, {0x05ED, 0x05ED, 0x05ED},
+ {0x05EE, 0x05EE, 0x05EE}, {0x05EF, 0x05EF, 0x05EF},
+ {0x05F0, 0x05F0, 0x05F0}, {0x05F1, 0x05F1, 0x05F1},
+ {0x05F2, 0x05F2, 0x05F2}, {0x05F3, 0x05F3, 0x05F3},
+ {0x05F4, 0x05F4, 0x05F4}, {0x05F5, 0x05F5, 0x05F5},
+ {0x05F6, 0x05F6, 0x05F6}, {0x05F7, 0x05F7, 0x05F7},
+ {0x05F8, 0x05F8, 0x05F8}, {0x05F9, 0x05F9, 0x05F9},
+ {0x05FA, 0x05FA, 0x05FA}, {0x05FB, 0x05FB, 0x05FB},
+ {0x05FC, 0x05FC, 0x05FC}, {0x05FD, 0x05FD, 0x05FD},
+ {0x05FE, 0x05FE, 0x05FE}, {0x05FF, 0x05FF, 0x05FF}
+};
+
+static MY_UNICASE_INFO plane1E[] = {
+ {0x1E00, 0x1E01, 0x0041}, {0x1E00, 0x1E01, 0x0041},
+ {0x1E02, 0x1E03, 0x0042}, {0x1E02, 0x1E03, 0x0042},
+ {0x1E04, 0x1E05, 0x0042}, {0x1E04, 0x1E05, 0x0042},
+ {0x1E06, 0x1E07, 0x0042}, {0x1E06, 0x1E07, 0x0042},
+ {0x1E08, 0x1E09, 0x0043}, {0x1E08, 0x1E09, 0x0043},
+ {0x1E0A, 0x1E0B, 0x0044}, {0x1E0A, 0x1E0B, 0x0044},
+ {0x1E0C, 0x1E0D, 0x0044}, {0x1E0C, 0x1E0D, 0x0044},
+ {0x1E0E, 0x1E0F, 0x0044}, {0x1E0E, 0x1E0F, 0x0044},
+ {0x1E10, 0x1E11, 0x0044}, {0x1E10, 0x1E11, 0x0044},
+ {0x1E12, 0x1E13, 0x0044}, {0x1E12, 0x1E13, 0x0044},
+ {0x1E14, 0x1E15, 0x0045}, {0x1E14, 0x1E15, 0x0045},
+ {0x1E16, 0x1E17, 0x0045}, {0x1E16, 0x1E17, 0x0045},
+ {0x1E18, 0x1E19, 0x0045}, {0x1E18, 0x1E19, 0x0045},
+ {0x1E1A, 0x1E1B, 0x0045}, {0x1E1A, 0x1E1B, 0x0045},
+ {0x1E1C, 0x1E1D, 0x0045}, {0x1E1C, 0x1E1D, 0x0045},
+ {0x1E1E, 0x1E1F, 0x0046}, {0x1E1E, 0x1E1F, 0x0046},
+ {0x1E20, 0x1E21, 0x0047}, {0x1E20, 0x1E21, 0x0047},
+ {0x1E22, 0x1E23, 0x0048}, {0x1E22, 0x1E23, 0x0048},
+ {0x1E24, 0x1E25, 0x0048}, {0x1E24, 0x1E25, 0x0048},
+ {0x1E26, 0x1E27, 0x0048}, {0x1E26, 0x1E27, 0x0048},
+ {0x1E28, 0x1E29, 0x0048}, {0x1E28, 0x1E29, 0x0048},
+ {0x1E2A, 0x1E2B, 0x0048}, {0x1E2A, 0x1E2B, 0x0048},
+ {0x1E2C, 0x1E2D, 0x0049}, {0x1E2C, 0x1E2D, 0x0049},
+ {0x1E2E, 0x1E2F, 0x0049}, {0x1E2E, 0x1E2F, 0x0049},
+ {0x1E30, 0x1E31, 0x004B}, {0x1E30, 0x1E31, 0x004B},
+ {0x1E32, 0x1E33, 0x004B}, {0x1E32, 0x1E33, 0x004B},
+ {0x1E34, 0x1E35, 0x004B}, {0x1E34, 0x1E35, 0x004B},
+ {0x1E36, 0x1E37, 0x004C}, {0x1E36, 0x1E37, 0x004C},
+ {0x1E38, 0x1E39, 0x004C}, {0x1E38, 0x1E39, 0x004C},
+ {0x1E3A, 0x1E3B, 0x004C}, {0x1E3A, 0x1E3B, 0x004C},
+ {0x1E3C, 0x1E3D, 0x004C}, {0x1E3C, 0x1E3D, 0x004C},
+ {0x1E3E, 0x1E3F, 0x004D}, {0x1E3E, 0x1E3F, 0x004D},
+ {0x1E40, 0x1E41, 0x004D}, {0x1E40, 0x1E41, 0x004D},
+ {0x1E42, 0x1E43, 0x004D}, {0x1E42, 0x1E43, 0x004D},
+ {0x1E44, 0x1E45, 0x004E}, {0x1E44, 0x1E45, 0x004E},
+ {0x1E46, 0x1E47, 0x004E}, {0x1E46, 0x1E47, 0x004E},
+ {0x1E48, 0x1E49, 0x004E}, {0x1E48, 0x1E49, 0x004E},
+ {0x1E4A, 0x1E4B, 0x004E}, {0x1E4A, 0x1E4B, 0x004E},
+ {0x1E4C, 0x1E4D, 0x004F}, {0x1E4C, 0x1E4D, 0x004F},
+ {0x1E4E, 0x1E4F, 0x004F}, {0x1E4E, 0x1E4F, 0x004F},
+ {0x1E50, 0x1E51, 0x004F}, {0x1E50, 0x1E51, 0x004F},
+ {0x1E52, 0x1E53, 0x004F}, {0x1E52, 0x1E53, 0x004F},
+ {0x1E54, 0x1E55, 0x0050}, {0x1E54, 0x1E55, 0x0050},
+ {0x1E56, 0x1E57, 0x0050}, {0x1E56, 0x1E57, 0x0050},
+ {0x1E58, 0x1E59, 0x0052}, {0x1E58, 0x1E59, 0x0052},
+ {0x1E5A, 0x1E5B, 0x0052}, {0x1E5A, 0x1E5B, 0x0052},
+ {0x1E5C, 0x1E5D, 0x0052}, {0x1E5C, 0x1E5D, 0x0052},
+ {0x1E5E, 0x1E5F, 0x0052}, {0x1E5E, 0x1E5F, 0x0052},
+ {0x1E60, 0x1E61, 0x0053}, {0x1E60, 0x1E61, 0x0053},
+ {0x1E62, 0x1E63, 0x0053}, {0x1E62, 0x1E63, 0x0053},
+ {0x1E64, 0x1E65, 0x0053}, {0x1E64, 0x1E65, 0x0053},
+ {0x1E66, 0x1E67, 0x0053}, {0x1E66, 0x1E67, 0x0053},
+ {0x1E68, 0x1E69, 0x0053}, {0x1E68, 0x1E69, 0x0053},
+ {0x1E6A, 0x1E6B, 0x0054}, {0x1E6A, 0x1E6B, 0x0054},
+ {0x1E6C, 0x1E6D, 0x0054}, {0x1E6C, 0x1E6D, 0x0054},
+ {0x1E6E, 0x1E6F, 0x0054}, {0x1E6E, 0x1E6F, 0x0054},
+ {0x1E70, 0x1E71, 0x0054}, {0x1E70, 0x1E71, 0x0054},
+ {0x1E72, 0x1E73, 0x0055}, {0x1E72, 0x1E73, 0x0055},
+ {0x1E74, 0x1E75, 0x0055}, {0x1E74, 0x1E75, 0x0055},
+ {0x1E76, 0x1E77, 0x0055}, {0x1E76, 0x1E77, 0x0055},
+ {0x1E78, 0x1E79, 0x0055}, {0x1E78, 0x1E79, 0x0055},
+ {0x1E7A, 0x1E7B, 0x0055}, {0x1E7A, 0x1E7B, 0x0055},
+ {0x1E7C, 0x1E7D, 0x0056}, {0x1E7C, 0x1E7D, 0x0056},
+ {0x1E7E, 0x1E7F, 0x0056}, {0x1E7E, 0x1E7F, 0x0056},
+ {0x1E80, 0x1E81, 0x0057}, {0x1E80, 0x1E81, 0x0057},
+ {0x1E82, 0x1E83, 0x0057}, {0x1E82, 0x1E83, 0x0057},
+ {0x1E84, 0x1E85, 0x0057}, {0x1E84, 0x1E85, 0x0057},
+ {0x1E86, 0x1E87, 0x0057}, {0x1E86, 0x1E87, 0x0057},
+ {0x1E88, 0x1E89, 0x0057}, {0x1E88, 0x1E89, 0x0057},
+ {0x1E8A, 0x1E8B, 0x0058}, {0x1E8A, 0x1E8B, 0x0058},
+ {0x1E8C, 0x1E8D, 0x0058}, {0x1E8C, 0x1E8D, 0x0058},
+ {0x1E8E, 0x1E8F, 0x0059}, {0x1E8E, 0x1E8F, 0x0059},
+ {0x1E90, 0x1E91, 0x005A}, {0x1E90, 0x1E91, 0x005A},
+ {0x1E92, 0x1E93, 0x005A}, {0x1E92, 0x1E93, 0x005A},
+ {0x1E94, 0x1E95, 0x005A}, {0x1E94, 0x1E95, 0x005A},
+ {0x1E96, 0x1E96, 0x0048}, {0x1E97, 0x1E97, 0x0054},
+ {0x1E98, 0x1E98, 0x0057}, {0x1E99, 0x1E99, 0x0059},
+ {0x1E9A, 0x1E9A, 0x1E9A}, {0x1E60, 0x1E9B, 0x0053},
+ {0x1E9C, 0x1E9C, 0x1E9C}, {0x1E9D, 0x1E9D, 0x1E9D},
+ {0x1E9E, 0x1E9E, 0x1E9E}, {0x1E9F, 0x1E9F, 0x1E9F},
+ {0x1EA0, 0x1EA1, 0x0041}, {0x1EA0, 0x1EA1, 0x0041},
+ {0x1EA2, 0x1EA3, 0x0041}, {0x1EA2, 0x1EA3, 0x0041},
+ {0x1EA4, 0x1EA5, 0x0041}, {0x1EA4, 0x1EA5, 0x0041},
+ {0x1EA6, 0x1EA7, 0x0041}, {0x1EA6, 0x1EA7, 0x0041},
+ {0x1EA8, 0x1EA9, 0x0041}, {0x1EA8, 0x1EA9, 0x0041},
+ {0x1EAA, 0x1EAB, 0x0041}, {0x1EAA, 0x1EAB, 0x0041},
+ {0x1EAC, 0x1EAD, 0x0041}, {0x1EAC, 0x1EAD, 0x0041},
+ {0x1EAE, 0x1EAF, 0x0041}, {0x1EAE, 0x1EAF, 0x0041},
+ {0x1EB0, 0x1EB1, 0x0041}, {0x1EB0, 0x1EB1, 0x0041},
+ {0x1EB2, 0x1EB3, 0x0041}, {0x1EB2, 0x1EB3, 0x0041},
+ {0x1EB4, 0x1EB5, 0x0041}, {0x1EB4, 0x1EB5, 0x0041},
+ {0x1EB6, 0x1EB7, 0x0041}, {0x1EB6, 0x1EB7, 0x0041},
+ {0x1EB8, 0x1EB9, 0x0045}, {0x1EB8, 0x1EB9, 0x0045},
+ {0x1EBA, 0x1EBB, 0x0045}, {0x1EBA, 0x1EBB, 0x0045},
+ {0x1EBC, 0x1EBD, 0x0045}, {0x1EBC, 0x1EBD, 0x0045},
+ {0x1EBE, 0x1EBF, 0x0045}, {0x1EBE, 0x1EBF, 0x0045},
+ {0x1EC0, 0x1EC1, 0x0045}, {0x1EC0, 0x1EC1, 0x0045},
+ {0x1EC2, 0x1EC3, 0x0045}, {0x1EC2, 0x1EC3, 0x0045},
+ {0x1EC4, 0x1EC5, 0x0045}, {0x1EC4, 0x1EC5, 0x0045},
+ {0x1EC6, 0x1EC7, 0x0045}, {0x1EC6, 0x1EC7, 0x0045},
+ {0x1EC8, 0x1EC9, 0x0049}, {0x1EC8, 0x1EC9, 0x0049},
+ {0x1ECA, 0x1ECB, 0x0049}, {0x1ECA, 0x1ECB, 0x0049},
+ {0x1ECC, 0x1ECD, 0x004F}, {0x1ECC, 0x1ECD, 0x004F},
+ {0x1ECE, 0x1ECF, 0x004F}, {0x1ECE, 0x1ECF, 0x004F},
+ {0x1ED0, 0x1ED1, 0x004F}, {0x1ED0, 0x1ED1, 0x004F},
+ {0x1ED2, 0x1ED3, 0x004F}, {0x1ED2, 0x1ED3, 0x004F},
+ {0x1ED4, 0x1ED5, 0x004F}, {0x1ED4, 0x1ED5, 0x004F},
+ {0x1ED6, 0x1ED7, 0x004F}, {0x1ED6, 0x1ED7, 0x004F},
+ {0x1ED8, 0x1ED9, 0x004F}, {0x1ED8, 0x1ED9, 0x004F},
+ {0x1EDA, 0x1EDB, 0x004F}, {0x1EDA, 0x1EDB, 0x004F},
+ {0x1EDC, 0x1EDD, 0x004F}, {0x1EDC, 0x1EDD, 0x004F},
+ {0x1EDE, 0x1EDF, 0x004F}, {0x1EDE, 0x1EDF, 0x004F},
+ {0x1EE0, 0x1EE1, 0x004F}, {0x1EE0, 0x1EE1, 0x004F},
+ {0x1EE2, 0x1EE3, 0x004F}, {0x1EE2, 0x1EE3, 0x004F},
+ {0x1EE4, 0x1EE5, 0x0055}, {0x1EE4, 0x1EE5, 0x0055},
+ {0x1EE6, 0x1EE7, 0x0055}, {0x1EE6, 0x1EE7, 0x0055},
+ {0x1EE8, 0x1EE9, 0x0055}, {0x1EE8, 0x1EE9, 0x0055},
+ {0x1EEA, 0x1EEB, 0x0055}, {0x1EEA, 0x1EEB, 0x0055},
+ {0x1EEC, 0x1EED, 0x0055}, {0x1EEC, 0x1EED, 0x0055},
+ {0x1EEE, 0x1EEF, 0x0055}, {0x1EEE, 0x1EEF, 0x0055},
+ {0x1EF0, 0x1EF1, 0x0055}, {0x1EF0, 0x1EF1, 0x0055},
+ {0x1EF2, 0x1EF3, 0x0059}, {0x1EF2, 0x1EF3, 0x0059},
+ {0x1EF4, 0x1EF5, 0x0059}, {0x1EF4, 0x1EF5, 0x0059},
+ {0x1EF6, 0x1EF7, 0x0059}, {0x1EF6, 0x1EF7, 0x0059},
+ {0x1EF8, 0x1EF9, 0x0059}, {0x1EF8, 0x1EF9, 0x0059},
+ {0x1EFA, 0x1EFA, 0x1EFA}, {0x1EFB, 0x1EFB, 0x1EFB},
+ {0x1EFC, 0x1EFC, 0x1EFC}, {0x1EFD, 0x1EFD, 0x1EFD},
+ {0x1EFE, 0x1EFE, 0x1EFE}, {0x1EFF, 0x1EFF, 0x1EFF}
+};
+
+static MY_UNICASE_INFO plane1F[] = {
+ {0x1F08, 0x1F00, 0x0391}, {0x1F09, 0x1F01, 0x0391},
+ {0x1F0A, 0x1F02, 0x0391}, {0x1F0B, 0x1F03, 0x0391},
+ {0x1F0C, 0x1F04, 0x0391}, {0x1F0D, 0x1F05, 0x0391},
+ {0x1F0E, 0x1F06, 0x0391}, {0x1F0F, 0x1F07, 0x0391},
+ {0x1F08, 0x1F00, 0x0391}, {0x1F09, 0x1F01, 0x0391},
+ {0x1F0A, 0x1F02, 0x0391}, {0x1F0B, 0x1F03, 0x0391},
+ {0x1F0C, 0x1F04, 0x0391}, {0x1F0D, 0x1F05, 0x0391},
+ {0x1F0E, 0x1F06, 0x0391}, {0x1F0F, 0x1F07, 0x0391},
+ {0x1F18, 0x1F10, 0x0395}, {0x1F19, 0x1F11, 0x0395},
+ {0x1F1A, 0x1F12, 0x0395}, {0x1F1B, 0x1F13, 0x0395},
+ {0x1F1C, 0x1F14, 0x0395}, {0x1F1D, 0x1F15, 0x0395},
+ {0x1F16, 0x1F16, 0x1F16}, {0x1F17, 0x1F17, 0x1F17},
+ {0x1F18, 0x1F10, 0x0395}, {0x1F19, 0x1F11, 0x0395},
+ {0x1F1A, 0x1F12, 0x0395}, {0x1F1B, 0x1F13, 0x0395},
+ {0x1F1C, 0x1F14, 0x0395}, {0x1F1D, 0x1F15, 0x0395},
+ {0x1F1E, 0x1F1E, 0x1F1E}, {0x1F1F, 0x1F1F, 0x1F1F},
+ {0x1F28, 0x1F20, 0x0397}, {0x1F29, 0x1F21, 0x0397},
+ {0x1F2A, 0x1F22, 0x0397}, {0x1F2B, 0x1F23, 0x0397},
+ {0x1F2C, 0x1F24, 0x0397}, {0x1F2D, 0x1F25, 0x0397},
+ {0x1F2E, 0x1F26, 0x0397}, {0x1F2F, 0x1F27, 0x0397},
+ {0x1F28, 0x1F20, 0x0397}, {0x1F29, 0x1F21, 0x0397},
+ {0x1F2A, 0x1F22, 0x0397}, {0x1F2B, 0x1F23, 0x0397},
+ {0x1F2C, 0x1F24, 0x0397}, {0x1F2D, 0x1F25, 0x0397},
+ {0x1F2E, 0x1F26, 0x0397}, {0x1F2F, 0x1F27, 0x0397},
+ {0x1F38, 0x1F30, 0x0399}, {0x1F39, 0x1F31, 0x0399},
+ {0x1F3A, 0x1F32, 0x0399}, {0x1F3B, 0x1F33, 0x0399},
+ {0x1F3C, 0x1F34, 0x0399}, {0x1F3D, 0x1F35, 0x0399},
+ {0x1F3E, 0x1F36, 0x0399}, {0x1F3F, 0x1F37, 0x0399},
+ {0x1F38, 0x1F30, 0x0399}, {0x1F39, 0x1F31, 0x0399},
+ {0x1F3A, 0x1F32, 0x0399}, {0x1F3B, 0x1F33, 0x0399},
+ {0x1F3C, 0x1F34, 0x0399}, {0x1F3D, 0x1F35, 0x0399},
+ {0x1F3E, 0x1F36, 0x0399}, {0x1F3F, 0x1F37, 0x0399},
+ {0x1F48, 0x1F40, 0x039F}, {0x1F49, 0x1F41, 0x039F},
+ {0x1F4A, 0x1F42, 0x039F}, {0x1F4B, 0x1F43, 0x039F},
+ {0x1F4C, 0x1F44, 0x039F}, {0x1F4D, 0x1F45, 0x039F},
+ {0x1F46, 0x1F46, 0x1F46}, {0x1F47, 0x1F47, 0x1F47},
+ {0x1F48, 0x1F40, 0x039F}, {0x1F49, 0x1F41, 0x039F},
+ {0x1F4A, 0x1F42, 0x039F}, {0x1F4B, 0x1F43, 0x039F},
+ {0x1F4C, 0x1F44, 0x039F}, {0x1F4D, 0x1F45, 0x039F},
+ {0x1F4E, 0x1F4E, 0x1F4E}, {0x1F4F, 0x1F4F, 0x1F4F},
+ {0x1F50, 0x1F50, 0x03A5}, {0x1F59, 0x1F51, 0x03A5},
+ {0x1F52, 0x1F52, 0x03A5}, {0x1F5B, 0x1F53, 0x03A5},
+ {0x1F54, 0x1F54, 0x03A5}, {0x1F5D, 0x1F55, 0x03A5},
+ {0x1F56, 0x1F56, 0x03A5}, {0x1F5F, 0x1F57, 0x03A5},
+ {0x1F58, 0x1F58, 0x1F58}, {0x1F59, 0x1F51, 0x03A5},
+ {0x1F5A, 0x1F5A, 0x1F5A}, {0x1F5B, 0x1F53, 0x03A5},
+ {0x1F5C, 0x1F5C, 0x1F5C}, {0x1F5D, 0x1F55, 0x03A5},
+ {0x1F5E, 0x1F5E, 0x1F5E}, {0x1F5F, 0x1F57, 0x03A5},
+ {0x1F68, 0x1F60, 0x03A9}, {0x1F69, 0x1F61, 0x03A9},
+ {0x1F6A, 0x1F62, 0x03A9}, {0x1F6B, 0x1F63, 0x03A9},
+ {0x1F6C, 0x1F64, 0x03A9}, {0x1F6D, 0x1F65, 0x03A9},
+ {0x1F6E, 0x1F66, 0x03A9}, {0x1F6F, 0x1F67, 0x03A9},
+ {0x1F68, 0x1F60, 0x03A9}, {0x1F69, 0x1F61, 0x03A9},
+ {0x1F6A, 0x1F62, 0x03A9}, {0x1F6B, 0x1F63, 0x03A9},
+ {0x1F6C, 0x1F64, 0x03A9}, {0x1F6D, 0x1F65, 0x03A9},
+ {0x1F6E, 0x1F66, 0x03A9}, {0x1F6F, 0x1F67, 0x03A9},
+ {0x1FBA, 0x1F70, 0x0391}, {0x1FBB, 0x1F71, 0x1FBB},
+ {0x1FC8, 0x1F72, 0x0395}, {0x1FC9, 0x1F73, 0x1FC9},
+ {0x1FCA, 0x1F74, 0x0397}, {0x1FCB, 0x1F75, 0x1FCB},
+ {0x1FDA, 0x1F76, 0x0399}, {0x1FDB, 0x1F77, 0x1FDB},
+ {0x1FF8, 0x1F78, 0x039F}, {0x1FF9, 0x1F79, 0x1FF9},
+ {0x1FEA, 0x1F7A, 0x03A5}, {0x1FEB, 0x1F7B, 0x1FEB},
+ {0x1FFA, 0x1F7C, 0x03A9}, {0x1FFB, 0x1F7D, 0x1FFB},
+ {0x1F7E, 0x1F7E, 0x1F7E}, {0x1F7F, 0x1F7F, 0x1F7F},
+ {0x1F88, 0x1F80, 0x0391}, {0x1F89, 0x1F81, 0x0391},
+ {0x1F8A, 0x1F82, 0x0391}, {0x1F8B, 0x1F83, 0x0391},
+ {0x1F8C, 0x1F84, 0x0391}, {0x1F8D, 0x1F85, 0x0391},
+ {0x1F8E, 0x1F86, 0x0391}, {0x1F8F, 0x1F87, 0x0391},
+ {0x1F88, 0x1F80, 0x0391}, {0x1F89, 0x1F81, 0x0391},
+ {0x1F8A, 0x1F82, 0x0391}, {0x1F8B, 0x1F83, 0x0391},
+ {0x1F8C, 0x1F84, 0x0391}, {0x1F8D, 0x1F85, 0x0391},
+ {0x1F8E, 0x1F86, 0x0391}, {0x1F8F, 0x1F87, 0x0391},
+ {0x1F98, 0x1F90, 0x0397}, {0x1F99, 0x1F91, 0x0397},
+ {0x1F9A, 0x1F92, 0x0397}, {0x1F9B, 0x1F93, 0x0397},
+ {0x1F9C, 0x1F94, 0x0397}, {0x1F9D, 0x1F95, 0x0397},
+ {0x1F9E, 0x1F96, 0x0397}, {0x1F9F, 0x1F97, 0x0397},
+ {0x1F98, 0x1F90, 0x0397}, {0x1F99, 0x1F91, 0x0397},
+ {0x1F9A, 0x1F92, 0x0397}, {0x1F9B, 0x1F93, 0x0397},
+ {0x1F9C, 0x1F94, 0x0397}, {0x1F9D, 0x1F95, 0x0397},
+ {0x1F9E, 0x1F96, 0x0397}, {0x1F9F, 0x1F97, 0x0397},
+ {0x1FA8, 0x1FA0, 0x03A9}, {0x1FA9, 0x1FA1, 0x03A9},
+ {0x1FAA, 0x1FA2, 0x03A9}, {0x1FAB, 0x1FA3, 0x03A9},
+ {0x1FAC, 0x1FA4, 0x03A9}, {0x1FAD, 0x1FA5, 0x03A9},
+ {0x1FAE, 0x1FA6, 0x03A9}, {0x1FAF, 0x1FA7, 0x03A9},
+ {0x1FA8, 0x1FA0, 0x03A9}, {0x1FA9, 0x1FA1, 0x03A9},
+ {0x1FAA, 0x1FA2, 0x03A9}, {0x1FAB, 0x1FA3, 0x03A9},
+ {0x1FAC, 0x1FA4, 0x03A9}, {0x1FAD, 0x1FA5, 0x03A9},
+ {0x1FAE, 0x1FA6, 0x03A9}, {0x1FAF, 0x1FA7, 0x03A9},
+ {0x1FB8, 0x1FB0, 0x0391}, {0x1FB9, 0x1FB1, 0x0391},
+ {0x1FB2, 0x1FB2, 0x0391}, {0x1FBC, 0x1FB3, 0x0391},
+ {0x1FB4, 0x1FB4, 0x0391}, {0x1FB5, 0x1FB5, 0x1FB5},
+ {0x1FB6, 0x1FB6, 0x0391}, {0x1FB7, 0x1FB7, 0x0391},
+ {0x1FB8, 0x1FB0, 0x0391}, {0x1FB9, 0x1FB1, 0x0391},
+ {0x1FBA, 0x1F70, 0x0391}, {0x1FBB, 0x1F71, 0x1FBB},
+ {0x1FBC, 0x1FB3, 0x0391}, {0x1FBD, 0x1FBD, 0x1FBD},
+ {0x0399, 0x1FBE, 0x0399}, {0x1FBF, 0x1FBF, 0x1FBF},
+ {0x1FC0, 0x1FC0, 0x1FC0}, {0x1FC1, 0x1FC1, 0x1FC1},
+ {0x1FC2, 0x1FC2, 0x0397}, {0x1FCC, 0x1FC3, 0x0397},
+ {0x1FC4, 0x1FC4, 0x0397}, {0x1FC5, 0x1FC5, 0x1FC5},
+ {0x1FC6, 0x1FC6, 0x0397}, {0x1FC7, 0x1FC7, 0x0397},
+ {0x1FC8, 0x1F72, 0x0395}, {0x1FC9, 0x1F73, 0x1FC9},
+ {0x1FCA, 0x1F74, 0x0397}, {0x1FCB, 0x1F75, 0x1FCB},
+ {0x1FCC, 0x1FC3, 0x0397}, {0x1FCD, 0x1FCD, 0x1FCD},
+ {0x1FCE, 0x1FCE, 0x1FCE}, {0x1FCF, 0x1FCF, 0x1FCF},
+ {0x1FD8, 0x1FD0, 0x0399}, {0x1FD9, 0x1FD1, 0x0399},
+ {0x1FD2, 0x1FD2, 0x0399}, {0x1FD3, 0x1FD3, 0x1FD3},
+ {0x1FD4, 0x1FD4, 0x1FD4}, {0x1FD5, 0x1FD5, 0x1FD5},
+ {0x1FD6, 0x1FD6, 0x0399}, {0x1FD7, 0x1FD7, 0x0399},
+ {0x1FD8, 0x1FD0, 0x0399}, {0x1FD9, 0x1FD1, 0x0399},
+ {0x1FDA, 0x1F76, 0x0399}, {0x1FDB, 0x1F77, 0x1FDB},
+ {0x1FDC, 0x1FDC, 0x1FDC}, {0x1FDD, 0x1FDD, 0x1FDD},
+ {0x1FDE, 0x1FDE, 0x1FDE}, {0x1FDF, 0x1FDF, 0x1FDF},
+ {0x1FE8, 0x1FE0, 0x03A5}, {0x1FE9, 0x1FE1, 0x03A5},
+ {0x1FE2, 0x1FE2, 0x03A5}, {0x1FE3, 0x1FE3, 0x1FE3},
+ {0x1FE4, 0x1FE4, 0x03A1}, {0x1FEC, 0x1FE5, 0x03A1},
+ {0x1FE6, 0x1FE6, 0x03A5}, {0x1FE7, 0x1FE7, 0x03A5},
+ {0x1FE8, 0x1FE0, 0x03A5}, {0x1FE9, 0x1FE1, 0x03A5},
+ {0x1FEA, 0x1F7A, 0x03A5}, {0x1FEB, 0x1F7B, 0x1FEB},
+ {0x1FEC, 0x1FE5, 0x03A1}, {0x1FED, 0x1FED, 0x1FED},
+ {0x1FEE, 0x1FEE, 0x1FEE}, {0x1FEF, 0x1FEF, 0x1FEF},
+ {0x1FF0, 0x1FF0, 0x1FF0}, {0x1FF1, 0x1FF1, 0x1FF1},
+ {0x1FF2, 0x1FF2, 0x03A9}, {0x1FFC, 0x1FF3, 0x03A9},
+ {0x1FF4, 0x1FF4, 0x03A9}, {0x1FF5, 0x1FF5, 0x1FF5},
+ {0x1FF6, 0x1FF6, 0x03A9}, {0x1FF7, 0x1FF7, 0x03A9},
+ {0x1FF8, 0x1F78, 0x039F}, {0x1FF9, 0x1F79, 0x1FF9},
+ {0x1FFA, 0x1F7C, 0x03A9}, {0x1FFB, 0x1F7D, 0x1FFB},
+ {0x1FFC, 0x1FF3, 0x03A9}, {0x1FFD, 0x1FFD, 0x1FFD},
+ {0x1FFE, 0x1FFE, 0x1FFE}, {0x1FFF, 0x1FFF, 0x1FFF}
+};
+
+static MY_UNICASE_INFO plane21[] = {
+ {0x2100, 0x2100, 0x2100}, {0x2101, 0x2101, 0x2101},
+ {0x2102, 0x2102, 0x2102}, {0x2103, 0x2103, 0x2103},
+ {0x2104, 0x2104, 0x2104}, {0x2105, 0x2105, 0x2105},
+ {0x2106, 0x2106, 0x2106}, {0x2107, 0x2107, 0x2107},
+ {0x2108, 0x2108, 0x2108}, {0x2109, 0x2109, 0x2109},
+ {0x210A, 0x210A, 0x210A}, {0x210B, 0x210B, 0x210B},
+ {0x210C, 0x210C, 0x210C}, {0x210D, 0x210D, 0x210D},
+ {0x210E, 0x210E, 0x210E}, {0x210F, 0x210F, 0x210F},
+ {0x2110, 0x2110, 0x2110}, {0x2111, 0x2111, 0x2111},
+ {0x2112, 0x2112, 0x2112}, {0x2113, 0x2113, 0x2113},
+ {0x2114, 0x2114, 0x2114}, {0x2115, 0x2115, 0x2115},
+ {0x2116, 0x2116, 0x2116}, {0x2117, 0x2117, 0x2117},
+ {0x2118, 0x2118, 0x2118}, {0x2119, 0x2119, 0x2119},
+ {0x211A, 0x211A, 0x211A}, {0x211B, 0x211B, 0x211B},
+ {0x211C, 0x211C, 0x211C}, {0x211D, 0x211D, 0x211D},
+ {0x211E, 0x211E, 0x211E}, {0x211F, 0x211F, 0x211F},
+ {0x2120, 0x2120, 0x2120}, {0x2121, 0x2121, 0x2121},
+ {0x2122, 0x2122, 0x2122}, {0x2123, 0x2123, 0x2123},
+ {0x2124, 0x2124, 0x2124}, {0x2125, 0x2125, 0x2125},
+ {0x2126, 0x03C9, 0x2126}, {0x2127, 0x2127, 0x2127},
+ {0x2128, 0x2128, 0x2128}, {0x2129, 0x2129, 0x2129},
+ {0x212A, 0x006B, 0x212A}, {0x212B, 0x00E5, 0x212B},
+ {0x212C, 0x212C, 0x212C}, {0x212D, 0x212D, 0x212D},
+ {0x212E, 0x212E, 0x212E}, {0x212F, 0x212F, 0x212F},
+ {0x2130, 0x2130, 0x2130}, {0x2131, 0x2131, 0x2131},
+ {0x2132, 0x2132, 0x2132}, {0x2133, 0x2133, 0x2133},
+ {0x2134, 0x2134, 0x2134}, {0x2135, 0x2135, 0x2135},
+ {0x2136, 0x2136, 0x2136}, {0x2137, 0x2137, 0x2137},
+ {0x2138, 0x2138, 0x2138}, {0x2139, 0x2139, 0x2139},
+ {0x213A, 0x213A, 0x213A}, {0x213B, 0x213B, 0x213B},
+ {0x213C, 0x213C, 0x213C}, {0x213D, 0x213D, 0x213D},
+ {0x213E, 0x213E, 0x213E}, {0x213F, 0x213F, 0x213F},
+ {0x2140, 0x2140, 0x2140}, {0x2141, 0x2141, 0x2141},
+ {0x2142, 0x2142, 0x2142}, {0x2143, 0x2143, 0x2143},
+ {0x2144, 0x2144, 0x2144}, {0x2145, 0x2145, 0x2145},
+ {0x2146, 0x2146, 0x2146}, {0x2147, 0x2147, 0x2147},
+ {0x2148, 0x2148, 0x2148}, {0x2149, 0x2149, 0x2149},
+ {0x214A, 0x214A, 0x214A}, {0x214B, 0x214B, 0x214B},
+ {0x214C, 0x214C, 0x214C}, {0x214D, 0x214D, 0x214D},
+ {0x214E, 0x214E, 0x214E}, {0x214F, 0x214F, 0x214F},
+ {0x2150, 0x2150, 0x2150}, {0x2151, 0x2151, 0x2151},
+ {0x2152, 0x2152, 0x2152}, {0x2153, 0x2153, 0x2153},
+ {0x2154, 0x2154, 0x2154}, {0x2155, 0x2155, 0x2155},
+ {0x2156, 0x2156, 0x2156}, {0x2157, 0x2157, 0x2157},
+ {0x2158, 0x2158, 0x2158}, {0x2159, 0x2159, 0x2159},
+ {0x215A, 0x215A, 0x215A}, {0x215B, 0x215B, 0x215B},
+ {0x215C, 0x215C, 0x215C}, {0x215D, 0x215D, 0x215D},
+ {0x215E, 0x215E, 0x215E}, {0x215F, 0x215F, 0x215F},
+ {0x2160, 0x2170, 0x2160}, {0x2161, 0x2171, 0x2161},
+ {0x2162, 0x2172, 0x2162}, {0x2163, 0x2173, 0x2163},
+ {0x2164, 0x2174, 0x2164}, {0x2165, 0x2175, 0x2165},
+ {0x2166, 0x2176, 0x2166}, {0x2167, 0x2177, 0x2167},
+ {0x2168, 0x2178, 0x2168}, {0x2169, 0x2179, 0x2169},
+ {0x216A, 0x217A, 0x216A}, {0x216B, 0x217B, 0x216B},
+ {0x216C, 0x217C, 0x216C}, {0x216D, 0x217D, 0x216D},
+ {0x216E, 0x217E, 0x216E}, {0x216F, 0x217F, 0x216F},
+ {0x2160, 0x2170, 0x2160}, {0x2161, 0x2171, 0x2161},
+ {0x2162, 0x2172, 0x2162}, {0x2163, 0x2173, 0x2163},
+ {0x2164, 0x2174, 0x2164}, {0x2165, 0x2175, 0x2165},
+ {0x2166, 0x2176, 0x2166}, {0x2167, 0x2177, 0x2167},
+ {0x2168, 0x2178, 0x2168}, {0x2169, 0x2179, 0x2169},
+ {0x216A, 0x217A, 0x216A}, {0x216B, 0x217B, 0x216B},
+ {0x216C, 0x217C, 0x216C}, {0x216D, 0x217D, 0x216D},
+ {0x216E, 0x217E, 0x216E}, {0x216F, 0x217F, 0x216F},
+ {0x2180, 0x2180, 0x2180}, {0x2181, 0x2181, 0x2181},
+ {0x2182, 0x2182, 0x2182}, {0x2183, 0x2183, 0x2183},
+ {0x2184, 0x2184, 0x2184}, {0x2185, 0x2185, 0x2185},
+ {0x2186, 0x2186, 0x2186}, {0x2187, 0x2187, 0x2187},
+ {0x2188, 0x2188, 0x2188}, {0x2189, 0x2189, 0x2189},
+ {0x218A, 0x218A, 0x218A}, {0x218B, 0x218B, 0x218B},
+ {0x218C, 0x218C, 0x218C}, {0x218D, 0x218D, 0x218D},
+ {0x218E, 0x218E, 0x218E}, {0x218F, 0x218F, 0x218F},
+ {0x2190, 0x2190, 0x2190}, {0x2191, 0x2191, 0x2191},
+ {0x2192, 0x2192, 0x2192}, {0x2193, 0x2193, 0x2193},
+ {0x2194, 0x2194, 0x2194}, {0x2195, 0x2195, 0x2195},
+ {0x2196, 0x2196, 0x2196}, {0x2197, 0x2197, 0x2197},
+ {0x2198, 0x2198, 0x2198}, {0x2199, 0x2199, 0x2199},
+ {0x219A, 0x219A, 0x219A}, {0x219B, 0x219B, 0x219B},
+ {0x219C, 0x219C, 0x219C}, {0x219D, 0x219D, 0x219D},
+ {0x219E, 0x219E, 0x219E}, {0x219F, 0x219F, 0x219F},
+ {0x21A0, 0x21A0, 0x21A0}, {0x21A1, 0x21A1, 0x21A1},
+ {0x21A2, 0x21A2, 0x21A2}, {0x21A3, 0x21A3, 0x21A3},
+ {0x21A4, 0x21A4, 0x21A4}, {0x21A5, 0x21A5, 0x21A5},
+ {0x21A6, 0x21A6, 0x21A6}, {0x21A7, 0x21A7, 0x21A7},
+ {0x21A8, 0x21A8, 0x21A8}, {0x21A9, 0x21A9, 0x21A9},
+ {0x21AA, 0x21AA, 0x21AA}, {0x21AB, 0x21AB, 0x21AB},
+ {0x21AC, 0x21AC, 0x21AC}, {0x21AD, 0x21AD, 0x21AD},
+ {0x21AE, 0x21AE, 0x21AE}, {0x21AF, 0x21AF, 0x21AF},
+ {0x21B0, 0x21B0, 0x21B0}, {0x21B1, 0x21B1, 0x21B1},
+ {0x21B2, 0x21B2, 0x21B2}, {0x21B3, 0x21B3, 0x21B3},
+ {0x21B4, 0x21B4, 0x21B4}, {0x21B5, 0x21B5, 0x21B5},
+ {0x21B6, 0x21B6, 0x21B6}, {0x21B7, 0x21B7, 0x21B7},
+ {0x21B8, 0x21B8, 0x21B8}, {0x21B9, 0x21B9, 0x21B9},
+ {0x21BA, 0x21BA, 0x21BA}, {0x21BB, 0x21BB, 0x21BB},
+ {0x21BC, 0x21BC, 0x21BC}, {0x21BD, 0x21BD, 0x21BD},
+ {0x21BE, 0x21BE, 0x21BE}, {0x21BF, 0x21BF, 0x21BF},
+ {0x21C0, 0x21C0, 0x21C0}, {0x21C1, 0x21C1, 0x21C1},
+ {0x21C2, 0x21C2, 0x21C2}, {0x21C3, 0x21C3, 0x21C3},
+ {0x21C4, 0x21C4, 0x21C4}, {0x21C5, 0x21C5, 0x21C5},
+ {0x21C6, 0x21C6, 0x21C6}, {0x21C7, 0x21C7, 0x21C7},
+ {0x21C8, 0x21C8, 0x21C8}, {0x21C9, 0x21C9, 0x21C9},
+ {0x21CA, 0x21CA, 0x21CA}, {0x21CB, 0x21CB, 0x21CB},
+ {0x21CC, 0x21CC, 0x21CC}, {0x21CD, 0x21CD, 0x21CD},
+ {0x21CE, 0x21CE, 0x21CE}, {0x21CF, 0x21CF, 0x21CF},
+ {0x21D0, 0x21D0, 0x21D0}, {0x21D1, 0x21D1, 0x21D1},
+ {0x21D2, 0x21D2, 0x21D2}, {0x21D3, 0x21D3, 0x21D3},
+ {0x21D4, 0x21D4, 0x21D4}, {0x21D5, 0x21D5, 0x21D5},
+ {0x21D6, 0x21D6, 0x21D6}, {0x21D7, 0x21D7, 0x21D7},
+ {0x21D8, 0x21D8, 0x21D8}, {0x21D9, 0x21D9, 0x21D9},
+ {0x21DA, 0x21DA, 0x21DA}, {0x21DB, 0x21DB, 0x21DB},
+ {0x21DC, 0x21DC, 0x21DC}, {0x21DD, 0x21DD, 0x21DD},
+ {0x21DE, 0x21DE, 0x21DE}, {0x21DF, 0x21DF, 0x21DF},
+ {0x21E0, 0x21E0, 0x21E0}, {0x21E1, 0x21E1, 0x21E1},
+ {0x21E2, 0x21E2, 0x21E2}, {0x21E3, 0x21E3, 0x21E3},
+ {0x21E4, 0x21E4, 0x21E4}, {0x21E5, 0x21E5, 0x21E5},
+ {0x21E6, 0x21E6, 0x21E6}, {0x21E7, 0x21E7, 0x21E7},
+ {0x21E8, 0x21E8, 0x21E8}, {0x21E9, 0x21E9, 0x21E9},
+ {0x21EA, 0x21EA, 0x21EA}, {0x21EB, 0x21EB, 0x21EB},
+ {0x21EC, 0x21EC, 0x21EC}, {0x21ED, 0x21ED, 0x21ED},
+ {0x21EE, 0x21EE, 0x21EE}, {0x21EF, 0x21EF, 0x21EF},
+ {0x21F0, 0x21F0, 0x21F0}, {0x21F1, 0x21F1, 0x21F1},
+ {0x21F2, 0x21F2, 0x21F2}, {0x21F3, 0x21F3, 0x21F3},
+ {0x21F4, 0x21F4, 0x21F4}, {0x21F5, 0x21F5, 0x21F5},
+ {0x21F6, 0x21F6, 0x21F6}, {0x21F7, 0x21F7, 0x21F7},
+ {0x21F8, 0x21F8, 0x21F8}, {0x21F9, 0x21F9, 0x21F9},
+ {0x21FA, 0x21FA, 0x21FA}, {0x21FB, 0x21FB, 0x21FB},
+ {0x21FC, 0x21FC, 0x21FC}, {0x21FD, 0x21FD, 0x21FD},
+ {0x21FE, 0x21FE, 0x21FE}, {0x21FF, 0x21FF, 0x21FF}
+};
+
+static MY_UNICASE_INFO plane24[] = {
+ {0x2400, 0x2400, 0x2400}, {0x2401, 0x2401, 0x2401},
+ {0x2402, 0x2402, 0x2402}, {0x2403, 0x2403, 0x2403},
+ {0x2404, 0x2404, 0x2404}, {0x2405, 0x2405, 0x2405},
+ {0x2406, 0x2406, 0x2406}, {0x2407, 0x2407, 0x2407},
+ {0x2408, 0x2408, 0x2408}, {0x2409, 0x2409, 0x2409},
+ {0x240A, 0x240A, 0x240A}, {0x240B, 0x240B, 0x240B},
+ {0x240C, 0x240C, 0x240C}, {0x240D, 0x240D, 0x240D},
+ {0x240E, 0x240E, 0x240E}, {0x240F, 0x240F, 0x240F},
+ {0x2410, 0x2410, 0x2410}, {0x2411, 0x2411, 0x2411},
+ {0x2412, 0x2412, 0x2412}, {0x2413, 0x2413, 0x2413},
+ {0x2414, 0x2414, 0x2414}, {0x2415, 0x2415, 0x2415},
+ {0x2416, 0x2416, 0x2416}, {0x2417, 0x2417, 0x2417},
+ {0x2418, 0x2418, 0x2418}, {0x2419, 0x2419, 0x2419},
+ {0x241A, 0x241A, 0x241A}, {0x241B, 0x241B, 0x241B},
+ {0x241C, 0x241C, 0x241C}, {0x241D, 0x241D, 0x241D},
+ {0x241E, 0x241E, 0x241E}, {0x241F, 0x241F, 0x241F},
+ {0x2420, 0x2420, 0x2420}, {0x2421, 0x2421, 0x2421},
+ {0x2422, 0x2422, 0x2422}, {0x2423, 0x2423, 0x2423},
+ {0x2424, 0x2424, 0x2424}, {0x2425, 0x2425, 0x2425},
+ {0x2426, 0x2426, 0x2426}, {0x2427, 0x2427, 0x2427},
+ {0x2428, 0x2428, 0x2428}, {0x2429, 0x2429, 0x2429},
+ {0x242A, 0x242A, 0x242A}, {0x242B, 0x242B, 0x242B},
+ {0x242C, 0x242C, 0x242C}, {0x242D, 0x242D, 0x242D},
+ {0x242E, 0x242E, 0x242E}, {0x242F, 0x242F, 0x242F},
+ {0x2430, 0x2430, 0x2430}, {0x2431, 0x2431, 0x2431},
+ {0x2432, 0x2432, 0x2432}, {0x2433, 0x2433, 0x2433},
+ {0x2434, 0x2434, 0x2434}, {0x2435, 0x2435, 0x2435},
+ {0x2436, 0x2436, 0x2436}, {0x2437, 0x2437, 0x2437},
+ {0x2438, 0x2438, 0x2438}, {0x2439, 0x2439, 0x2439},
+ {0x243A, 0x243A, 0x243A}, {0x243B, 0x243B, 0x243B},
+ {0x243C, 0x243C, 0x243C}, {0x243D, 0x243D, 0x243D},
+ {0x243E, 0x243E, 0x243E}, {0x243F, 0x243F, 0x243F},
+ {0x2440, 0x2440, 0x2440}, {0x2441, 0x2441, 0x2441},
+ {0x2442, 0x2442, 0x2442}, {0x2443, 0x2443, 0x2443},
+ {0x2444, 0x2444, 0x2444}, {0x2445, 0x2445, 0x2445},
+ {0x2446, 0x2446, 0x2446}, {0x2447, 0x2447, 0x2447},
+ {0x2448, 0x2448, 0x2448}, {0x2449, 0x2449, 0x2449},
+ {0x244A, 0x244A, 0x244A}, {0x244B, 0x244B, 0x244B},
+ {0x244C, 0x244C, 0x244C}, {0x244D, 0x244D, 0x244D},
+ {0x244E, 0x244E, 0x244E}, {0x244F, 0x244F, 0x244F},
+ {0x2450, 0x2450, 0x2450}, {0x2451, 0x2451, 0x2451},
+ {0x2452, 0x2452, 0x2452}, {0x2453, 0x2453, 0x2453},
+ {0x2454, 0x2454, 0x2454}, {0x2455, 0x2455, 0x2455},
+ {0x2456, 0x2456, 0x2456}, {0x2457, 0x2457, 0x2457},
+ {0x2458, 0x2458, 0x2458}, {0x2459, 0x2459, 0x2459},
+ {0x245A, 0x245A, 0x245A}, {0x245B, 0x245B, 0x245B},
+ {0x245C, 0x245C, 0x245C}, {0x245D, 0x245D, 0x245D},
+ {0x245E, 0x245E, 0x245E}, {0x245F, 0x245F, 0x245F},
+ {0x2460, 0x2460, 0x2460}, {0x2461, 0x2461, 0x2461},
+ {0x2462, 0x2462, 0x2462}, {0x2463, 0x2463, 0x2463},
+ {0x2464, 0x2464, 0x2464}, {0x2465, 0x2465, 0x2465},
+ {0x2466, 0x2466, 0x2466}, {0x2467, 0x2467, 0x2467},
+ {0x2468, 0x2468, 0x2468}, {0x2469, 0x2469, 0x2469},
+ {0x246A, 0x246A, 0x246A}, {0x246B, 0x246B, 0x246B},
+ {0x246C, 0x246C, 0x246C}, {0x246D, 0x246D, 0x246D},
+ {0x246E, 0x246E, 0x246E}, {0x246F, 0x246F, 0x246F},
+ {0x2470, 0x2470, 0x2470}, {0x2471, 0x2471, 0x2471},
+ {0x2472, 0x2472, 0x2472}, {0x2473, 0x2473, 0x2473},
+ {0x2474, 0x2474, 0x2474}, {0x2475, 0x2475, 0x2475},
+ {0x2476, 0x2476, 0x2476}, {0x2477, 0x2477, 0x2477},
+ {0x2478, 0x2478, 0x2478}, {0x2479, 0x2479, 0x2479},
+ {0x247A, 0x247A, 0x247A}, {0x247B, 0x247B, 0x247B},
+ {0x247C, 0x247C, 0x247C}, {0x247D, 0x247D, 0x247D},
+ {0x247E, 0x247E, 0x247E}, {0x247F, 0x247F, 0x247F},
+ {0x2480, 0x2480, 0x2480}, {0x2481, 0x2481, 0x2481},
+ {0x2482, 0x2482, 0x2482}, {0x2483, 0x2483, 0x2483},
+ {0x2484, 0x2484, 0x2484}, {0x2485, 0x2485, 0x2485},
+ {0x2486, 0x2486, 0x2486}, {0x2487, 0x2487, 0x2487},
+ {0x2488, 0x2488, 0x2488}, {0x2489, 0x2489, 0x2489},
+ {0x248A, 0x248A, 0x248A}, {0x248B, 0x248B, 0x248B},
+ {0x248C, 0x248C, 0x248C}, {0x248D, 0x248D, 0x248D},
+ {0x248E, 0x248E, 0x248E}, {0x248F, 0x248F, 0x248F},
+ {0x2490, 0x2490, 0x2490}, {0x2491, 0x2491, 0x2491},
+ {0x2492, 0x2492, 0x2492}, {0x2493, 0x2493, 0x2493},
+ {0x2494, 0x2494, 0x2494}, {0x2495, 0x2495, 0x2495},
+ {0x2496, 0x2496, 0x2496}, {0x2497, 0x2497, 0x2497},
+ {0x2498, 0x2498, 0x2498}, {0x2499, 0x2499, 0x2499},
+ {0x249A, 0x249A, 0x249A}, {0x249B, 0x249B, 0x249B},
+ {0x249C, 0x249C, 0x249C}, {0x249D, 0x249D, 0x249D},
+ {0x249E, 0x249E, 0x249E}, {0x249F, 0x249F, 0x249F},
+ {0x24A0, 0x24A0, 0x24A0}, {0x24A1, 0x24A1, 0x24A1},
+ {0x24A2, 0x24A2, 0x24A2}, {0x24A3, 0x24A3, 0x24A3},
+ {0x24A4, 0x24A4, 0x24A4}, {0x24A5, 0x24A5, 0x24A5},
+ {0x24A6, 0x24A6, 0x24A6}, {0x24A7, 0x24A7, 0x24A7},
+ {0x24A8, 0x24A8, 0x24A8}, {0x24A9, 0x24A9, 0x24A9},
+ {0x24AA, 0x24AA, 0x24AA}, {0x24AB, 0x24AB, 0x24AB},
+ {0x24AC, 0x24AC, 0x24AC}, {0x24AD, 0x24AD, 0x24AD},
+ {0x24AE, 0x24AE, 0x24AE}, {0x24AF, 0x24AF, 0x24AF},
+ {0x24B0, 0x24B0, 0x24B0}, {0x24B1, 0x24B1, 0x24B1},
+ {0x24B2, 0x24B2, 0x24B2}, {0x24B3, 0x24B3, 0x24B3},
+ {0x24B4, 0x24B4, 0x24B4}, {0x24B5, 0x24B5, 0x24B5},
+ {0x24B6, 0x24D0, 0x24B6}, {0x24B7, 0x24D1, 0x24B7},
+ {0x24B8, 0x24D2, 0x24B8}, {0x24B9, 0x24D3, 0x24B9},
+ {0x24BA, 0x24D4, 0x24BA}, {0x24BB, 0x24D5, 0x24BB},
+ {0x24BC, 0x24D6, 0x24BC}, {0x24BD, 0x24D7, 0x24BD},
+ {0x24BE, 0x24D8, 0x24BE}, {0x24BF, 0x24D9, 0x24BF},
+ {0x24C0, 0x24DA, 0x24C0}, {0x24C1, 0x24DB, 0x24C1},
+ {0x24C2, 0x24DC, 0x24C2}, {0x24C3, 0x24DD, 0x24C3},
+ {0x24C4, 0x24DE, 0x24C4}, {0x24C5, 0x24DF, 0x24C5},
+ {0x24C6, 0x24E0, 0x24C6}, {0x24C7, 0x24E1, 0x24C7},
+ {0x24C8, 0x24E2, 0x24C8}, {0x24C9, 0x24E3, 0x24C9},
+ {0x24CA, 0x24E4, 0x24CA}, {0x24CB, 0x24E5, 0x24CB},
+ {0x24CC, 0x24E6, 0x24CC}, {0x24CD, 0x24E7, 0x24CD},
+ {0x24CE, 0x24E8, 0x24CE}, {0x24CF, 0x24E9, 0x24CF},
+ {0x24B6, 0x24D0, 0x24B6}, {0x24B7, 0x24D1, 0x24B7},
+ {0x24B8, 0x24D2, 0x24B8}, {0x24B9, 0x24D3, 0x24B9},
+ {0x24BA, 0x24D4, 0x24BA}, {0x24BB, 0x24D5, 0x24BB},
+ {0x24BC, 0x24D6, 0x24BC}, {0x24BD, 0x24D7, 0x24BD},
+ {0x24BE, 0x24D8, 0x24BE}, {0x24BF, 0x24D9, 0x24BF},
+ {0x24C0, 0x24DA, 0x24C0}, {0x24C1, 0x24DB, 0x24C1},
+ {0x24C2, 0x24DC, 0x24C2}, {0x24C3, 0x24DD, 0x24C3},
+ {0x24C4, 0x24DE, 0x24C4}, {0x24C5, 0x24DF, 0x24C5},
+ {0x24C6, 0x24E0, 0x24C6}, {0x24C7, 0x24E1, 0x24C7},
+ {0x24C8, 0x24E2, 0x24C8}, {0x24C9, 0x24E3, 0x24C9},
+ {0x24CA, 0x24E4, 0x24CA}, {0x24CB, 0x24E5, 0x24CB},
+ {0x24CC, 0x24E6, 0x24CC}, {0x24CD, 0x24E7, 0x24CD},
+ {0x24CE, 0x24E8, 0x24CE}, {0x24CF, 0x24E9, 0x24CF},
+ {0x24EA, 0x24EA, 0x24EA}, {0x24EB, 0x24EB, 0x24EB},
+ {0x24EC, 0x24EC, 0x24EC}, {0x24ED, 0x24ED, 0x24ED},
+ {0x24EE, 0x24EE, 0x24EE}, {0x24EF, 0x24EF, 0x24EF},
+ {0x24F0, 0x24F0, 0x24F0}, {0x24F1, 0x24F1, 0x24F1},
+ {0x24F2, 0x24F2, 0x24F2}, {0x24F3, 0x24F3, 0x24F3},
+ {0x24F4, 0x24F4, 0x24F4}, {0x24F5, 0x24F5, 0x24F5},
+ {0x24F6, 0x24F6, 0x24F6}, {0x24F7, 0x24F7, 0x24F7},
+ {0x24F8, 0x24F8, 0x24F8}, {0x24F9, 0x24F9, 0x24F9},
+ {0x24FA, 0x24FA, 0x24FA}, {0x24FB, 0x24FB, 0x24FB},
+ {0x24FC, 0x24FC, 0x24FC}, {0x24FD, 0x24FD, 0x24FD},
+ {0x24FE, 0x24FE, 0x24FE}, {0x24FF, 0x24FF, 0x24FF}
+};
+
+static MY_UNICASE_INFO planeFF[] = {
+ {0xFF00, 0xFF00, 0xFF00}, {0xFF01, 0xFF01, 0xFF01},
+ {0xFF02, 0xFF02, 0xFF02}, {0xFF03, 0xFF03, 0xFF03},
+ {0xFF04, 0xFF04, 0xFF04}, {0xFF05, 0xFF05, 0xFF05},
+ {0xFF06, 0xFF06, 0xFF06}, {0xFF07, 0xFF07, 0xFF07},
+ {0xFF08, 0xFF08, 0xFF08}, {0xFF09, 0xFF09, 0xFF09},
+ {0xFF0A, 0xFF0A, 0xFF0A}, {0xFF0B, 0xFF0B, 0xFF0B},
+ {0xFF0C, 0xFF0C, 0xFF0C}, {0xFF0D, 0xFF0D, 0xFF0D},
+ {0xFF0E, 0xFF0E, 0xFF0E}, {0xFF0F, 0xFF0F, 0xFF0F},
+ {0xFF10, 0xFF10, 0xFF10}, {0xFF11, 0xFF11, 0xFF11},
+ {0xFF12, 0xFF12, 0xFF12}, {0xFF13, 0xFF13, 0xFF13},
+ {0xFF14, 0xFF14, 0xFF14}, {0xFF15, 0xFF15, 0xFF15},
+ {0xFF16, 0xFF16, 0xFF16}, {0xFF17, 0xFF17, 0xFF17},
+ {0xFF18, 0xFF18, 0xFF18}, {0xFF19, 0xFF19, 0xFF19},
+ {0xFF1A, 0xFF1A, 0xFF1A}, {0xFF1B, 0xFF1B, 0xFF1B},
+ {0xFF1C, 0xFF1C, 0xFF1C}, {0xFF1D, 0xFF1D, 0xFF1D},
+ {0xFF1E, 0xFF1E, 0xFF1E}, {0xFF1F, 0xFF1F, 0xFF1F},
+ {0xFF20, 0xFF20, 0xFF20}, {0xFF21, 0xFF41, 0xFF21},
+ {0xFF22, 0xFF42, 0xFF22}, {0xFF23, 0xFF43, 0xFF23},
+ {0xFF24, 0xFF44, 0xFF24}, {0xFF25, 0xFF45, 0xFF25},
+ {0xFF26, 0xFF46, 0xFF26}, {0xFF27, 0xFF47, 0xFF27},
+ {0xFF28, 0xFF48, 0xFF28}, {0xFF29, 0xFF49, 0xFF29},
+ {0xFF2A, 0xFF4A, 0xFF2A}, {0xFF2B, 0xFF4B, 0xFF2B},
+ {0xFF2C, 0xFF4C, 0xFF2C}, {0xFF2D, 0xFF4D, 0xFF2D},
+ {0xFF2E, 0xFF4E, 0xFF2E}, {0xFF2F, 0xFF4F, 0xFF2F},
+ {0xFF30, 0xFF50, 0xFF30}, {0xFF31, 0xFF51, 0xFF31},
+ {0xFF32, 0xFF52, 0xFF32}, {0xFF33, 0xFF53, 0xFF33},
+ {0xFF34, 0xFF54, 0xFF34}, {0xFF35, 0xFF55, 0xFF35},
+ {0xFF36, 0xFF56, 0xFF36}, {0xFF37, 0xFF57, 0xFF37},
+ {0xFF38, 0xFF58, 0xFF38}, {0xFF39, 0xFF59, 0xFF39},
+ {0xFF3A, 0xFF5A, 0xFF3A}, {0xFF3B, 0xFF3B, 0xFF3B},
+ {0xFF3C, 0xFF3C, 0xFF3C}, {0xFF3D, 0xFF3D, 0xFF3D},
+ {0xFF3E, 0xFF3E, 0xFF3E}, {0xFF3F, 0xFF3F, 0xFF3F},
+ {0xFF40, 0xFF40, 0xFF40}, {0xFF21, 0xFF41, 0xFF21},
+ {0xFF22, 0xFF42, 0xFF22}, {0xFF23, 0xFF43, 0xFF23},
+ {0xFF24, 0xFF44, 0xFF24}, {0xFF25, 0xFF45, 0xFF25},
+ {0xFF26, 0xFF46, 0xFF26}, {0xFF27, 0xFF47, 0xFF27},
+ {0xFF28, 0xFF48, 0xFF28}, {0xFF29, 0xFF49, 0xFF29},
+ {0xFF2A, 0xFF4A, 0xFF2A}, {0xFF2B, 0xFF4B, 0xFF2B},
+ {0xFF2C, 0xFF4C, 0xFF2C}, {0xFF2D, 0xFF4D, 0xFF2D},
+ {0xFF2E, 0xFF4E, 0xFF2E}, {0xFF2F, 0xFF4F, 0xFF2F},
+ {0xFF30, 0xFF50, 0xFF30}, {0xFF31, 0xFF51, 0xFF31},
+ {0xFF32, 0xFF52, 0xFF32}, {0xFF33, 0xFF53, 0xFF33},
+ {0xFF34, 0xFF54, 0xFF34}, {0xFF35, 0xFF55, 0xFF35},
+ {0xFF36, 0xFF56, 0xFF36}, {0xFF37, 0xFF57, 0xFF37},
+ {0xFF38, 0xFF58, 0xFF38}, {0xFF39, 0xFF59, 0xFF39},
+ {0xFF3A, 0xFF5A, 0xFF3A}, {0xFF5B, 0xFF5B, 0xFF5B},
+ {0xFF5C, 0xFF5C, 0xFF5C}, {0xFF5D, 0xFF5D, 0xFF5D},
+ {0xFF5E, 0xFF5E, 0xFF5E}, {0xFF5F, 0xFF5F, 0xFF5F},
+ {0xFF60, 0xFF60, 0xFF60}, {0xFF61, 0xFF61, 0xFF61},
+ {0xFF62, 0xFF62, 0xFF62}, {0xFF63, 0xFF63, 0xFF63},
+ {0xFF64, 0xFF64, 0xFF64}, {0xFF65, 0xFF65, 0xFF65},
+ {0xFF66, 0xFF66, 0xFF66}, {0xFF67, 0xFF67, 0xFF67},
+ {0xFF68, 0xFF68, 0xFF68}, {0xFF69, 0xFF69, 0xFF69},
+ {0xFF6A, 0xFF6A, 0xFF6A}, {0xFF6B, 0xFF6B, 0xFF6B},
+ {0xFF6C, 0xFF6C, 0xFF6C}, {0xFF6D, 0xFF6D, 0xFF6D},
+ {0xFF6E, 0xFF6E, 0xFF6E}, {0xFF6F, 0xFF6F, 0xFF6F},
+ {0xFF70, 0xFF70, 0xFF70}, {0xFF71, 0xFF71, 0xFF71},
+ {0xFF72, 0xFF72, 0xFF72}, {0xFF73, 0xFF73, 0xFF73},
+ {0xFF74, 0xFF74, 0xFF74}, {0xFF75, 0xFF75, 0xFF75},
+ {0xFF76, 0xFF76, 0xFF76}, {0xFF77, 0xFF77, 0xFF77},
+ {0xFF78, 0xFF78, 0xFF78}, {0xFF79, 0xFF79, 0xFF79},
+ {0xFF7A, 0xFF7A, 0xFF7A}, {0xFF7B, 0xFF7B, 0xFF7B},
+ {0xFF7C, 0xFF7C, 0xFF7C}, {0xFF7D, 0xFF7D, 0xFF7D},
+ {0xFF7E, 0xFF7E, 0xFF7E}, {0xFF7F, 0xFF7F, 0xFF7F},
+ {0xFF80, 0xFF80, 0xFF80}, {0xFF81, 0xFF81, 0xFF81},
+ {0xFF82, 0xFF82, 0xFF82}, {0xFF83, 0xFF83, 0xFF83},
+ {0xFF84, 0xFF84, 0xFF84}, {0xFF85, 0xFF85, 0xFF85},
+ {0xFF86, 0xFF86, 0xFF86}, {0xFF87, 0xFF87, 0xFF87},
+ {0xFF88, 0xFF88, 0xFF88}, {0xFF89, 0xFF89, 0xFF89},
+ {0xFF8A, 0xFF8A, 0xFF8A}, {0xFF8B, 0xFF8B, 0xFF8B},
+ {0xFF8C, 0xFF8C, 0xFF8C}, {0xFF8D, 0xFF8D, 0xFF8D},
+ {0xFF8E, 0xFF8E, 0xFF8E}, {0xFF8F, 0xFF8F, 0xFF8F},
+ {0xFF90, 0xFF90, 0xFF90}, {0xFF91, 0xFF91, 0xFF91},
+ {0xFF92, 0xFF92, 0xFF92}, {0xFF93, 0xFF93, 0xFF93},
+ {0xFF94, 0xFF94, 0xFF94}, {0xFF95, 0xFF95, 0xFF95},
+ {0xFF96, 0xFF96, 0xFF96}, {0xFF97, 0xFF97, 0xFF97},
+ {0xFF98, 0xFF98, 0xFF98}, {0xFF99, 0xFF99, 0xFF99},
+ {0xFF9A, 0xFF9A, 0xFF9A}, {0xFF9B, 0xFF9B, 0xFF9B},
+ {0xFF9C, 0xFF9C, 0xFF9C}, {0xFF9D, 0xFF9D, 0xFF9D},
+ {0xFF9E, 0xFF9E, 0xFF9E}, {0xFF9F, 0xFF9F, 0xFF9F},
+ {0xFFA0, 0xFFA0, 0xFFA0}, {0xFFA1, 0xFFA1, 0xFFA1},
+ {0xFFA2, 0xFFA2, 0xFFA2}, {0xFFA3, 0xFFA3, 0xFFA3},
+ {0xFFA4, 0xFFA4, 0xFFA4}, {0xFFA5, 0xFFA5, 0xFFA5},
+ {0xFFA6, 0xFFA6, 0xFFA6}, {0xFFA7, 0xFFA7, 0xFFA7},
+ {0xFFA8, 0xFFA8, 0xFFA8}, {0xFFA9, 0xFFA9, 0xFFA9},
+ {0xFFAA, 0xFFAA, 0xFFAA}, {0xFFAB, 0xFFAB, 0xFFAB},
+ {0xFFAC, 0xFFAC, 0xFFAC}, {0xFFAD, 0xFFAD, 0xFFAD},
+ {0xFFAE, 0xFFAE, 0xFFAE}, {0xFFAF, 0xFFAF, 0xFFAF},
+ {0xFFB0, 0xFFB0, 0xFFB0}, {0xFFB1, 0xFFB1, 0xFFB1},
+ {0xFFB2, 0xFFB2, 0xFFB2}, {0xFFB3, 0xFFB3, 0xFFB3},
+ {0xFFB4, 0xFFB4, 0xFFB4}, {0xFFB5, 0xFFB5, 0xFFB5},
+ {0xFFB6, 0xFFB6, 0xFFB6}, {0xFFB7, 0xFFB7, 0xFFB7},
+ {0xFFB8, 0xFFB8, 0xFFB8}, {0xFFB9, 0xFFB9, 0xFFB9},
+ {0xFFBA, 0xFFBA, 0xFFBA}, {0xFFBB, 0xFFBB, 0xFFBB},
+ {0xFFBC, 0xFFBC, 0xFFBC}, {0xFFBD, 0xFFBD, 0xFFBD},
+ {0xFFBE, 0xFFBE, 0xFFBE}, {0xFFBF, 0xFFBF, 0xFFBF},
+ {0xFFC0, 0xFFC0, 0xFFC0}, {0xFFC1, 0xFFC1, 0xFFC1},
+ {0xFFC2, 0xFFC2, 0xFFC2}, {0xFFC3, 0xFFC3, 0xFFC3},
+ {0xFFC4, 0xFFC4, 0xFFC4}, {0xFFC5, 0xFFC5, 0xFFC5},
+ {0xFFC6, 0xFFC6, 0xFFC6}, {0xFFC7, 0xFFC7, 0xFFC7},
+ {0xFFC8, 0xFFC8, 0xFFC8}, {0xFFC9, 0xFFC9, 0xFFC9},
+ {0xFFCA, 0xFFCA, 0xFFCA}, {0xFFCB, 0xFFCB, 0xFFCB},
+ {0xFFCC, 0xFFCC, 0xFFCC}, {0xFFCD, 0xFFCD, 0xFFCD},
+ {0xFFCE, 0xFFCE, 0xFFCE}, {0xFFCF, 0xFFCF, 0xFFCF},
+ {0xFFD0, 0xFFD0, 0xFFD0}, {0xFFD1, 0xFFD1, 0xFFD1},
+ {0xFFD2, 0xFFD2, 0xFFD2}, {0xFFD3, 0xFFD3, 0xFFD3},
+ {0xFFD4, 0xFFD4, 0xFFD4}, {0xFFD5, 0xFFD5, 0xFFD5},
+ {0xFFD6, 0xFFD6, 0xFFD6}, {0xFFD7, 0xFFD7, 0xFFD7},
+ {0xFFD8, 0xFFD8, 0xFFD8}, {0xFFD9, 0xFFD9, 0xFFD9},
+ {0xFFDA, 0xFFDA, 0xFFDA}, {0xFFDB, 0xFFDB, 0xFFDB},
+ {0xFFDC, 0xFFDC, 0xFFDC}, {0xFFDD, 0xFFDD, 0xFFDD},
+ {0xFFDE, 0xFFDE, 0xFFDE}, {0xFFDF, 0xFFDF, 0xFFDF},
+ {0xFFE0, 0xFFE0, 0xFFE0}, {0xFFE1, 0xFFE1, 0xFFE1},
+ {0xFFE2, 0xFFE2, 0xFFE2}, {0xFFE3, 0xFFE3, 0xFFE3},
+ {0xFFE4, 0xFFE4, 0xFFE4}, {0xFFE5, 0xFFE5, 0xFFE5},
+ {0xFFE6, 0xFFE6, 0xFFE6}, {0xFFE7, 0xFFE7, 0xFFE7},
+ {0xFFE8, 0xFFE8, 0xFFE8}, {0xFFE9, 0xFFE9, 0xFFE9},
+ {0xFFEA, 0xFFEA, 0xFFEA}, {0xFFEB, 0xFFEB, 0xFFEB},
+ {0xFFEC, 0xFFEC, 0xFFEC}, {0xFFED, 0xFFED, 0xFFED},
+ {0xFFEE, 0xFFEE, 0xFFEE}, {0xFFEF, 0xFFEF, 0xFFEF},
+ {0xFFF0, 0xFFF0, 0xFFF0}, {0xFFF1, 0xFFF1, 0xFFF1},
+ {0xFFF2, 0xFFF2, 0xFFF2}, {0xFFF3, 0xFFF3, 0xFFF3},
+ {0xFFF4, 0xFFF4, 0xFFF4}, {0xFFF5, 0xFFF5, 0xFFF5},
+ {0xFFF6, 0xFFF6, 0xFFF6}, {0xFFF7, 0xFFF7, 0xFFF7},
+ {0xFFF8, 0xFFF8, 0xFFF8}, {0xFFF9, 0xFFF9, 0xFFF9},
+ {0xFFFA, 0xFFFA, 0xFFFA}, {0xFFFB, 0xFFFB, 0xFFFB},
+ {0xFFFC, 0xFFFC, 0xFFFC}, {0xFFFD, 0xFFFD, 0xFFFD},
+ {0xFFFE, 0xFFFE, 0xFFFE}, {0xFFFF, 0xFFFF, 0xFFFF}
+};
+
+MY_UNICASE_INFO *uni_plane[256] = {
+ plane00, plane01, plane02, plane03, plane04, plane05, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, plane1E, plane1F,
+ NULL, plane21, NULL, NULL, plane24, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, planeFF
+};
+
+
+size_t
+utf8_char_width(const char *ch)
+{
+ const unsigned char *p = (const unsigned char *)ch;
+ if (*p <= 0x7f)
+ return 1;
+ if (0xc2 <= *p && *p <= 0xdf)
+ return 2;
+ if (0xe0 <= *p && *p <= 0xef)
+ return 3;
+ if (0xf0 <= *p && *p <= 0xf4)
+ return 4;
+ return 0;
+}
+
+size_t
+utf8_strlen(const char *s)
+{
+ size_t len = 0;
+ size_t n;
+
+ while (*s && (n = utf8_char_width(s)) != 0) {
+ len++;
+ s += n;
+ }
+ return len;
+}
+
+
+static int
+utf8_iter0(struct utf8_iterator *itr)
+{
+ size_t n = utf8_char_width(itr->curptr);
+ if (n == 0)
+ return 1;
+ itr->curwidth = n;
+ return 0;
+}
+
+int
+utf8_iter_end_p(struct utf8_iterator *itr)
+{
+ return *itr->curptr == 0;
+}
+
+int
+utf8_iter_first(struct utf8_iterator *itr, char *ptr)
+{
+ itr->string = ptr;
+ itr->curptr = ptr;
+ return utf8_iter0(itr);
+}
+
+int
+utf8_iter_next(struct utf8_iterator *itr)
+{
+ if (*itr->curptr == 0)
+ return -1;
+ itr->curptr += itr->curwidth;
+ return utf8_iter0(itr);
+}
+
+
+/* Stores the UTF-8 representation of the Unicode character wc in r[0..5].
+ Returns the number of bytes stored, or -1 if wc is out of range. */
+int
+utf8_wctomb(char *r, unsigned int wc)
+{
+ int count;
+
+ if (wc < 0x80)
+ count = 1;
+ else if (wc < 0x800)
+ count = 2;
+ else if (wc < 0x10000)
+ count = 3;
+ else if (wc < 0x200000)
+ count = 4;
+ else if (wc < 0x4000000)
+ count = 5;
+ else if (wc <= 0x7fffffff)
+ count = 6;
+ else
+ return -1;
+
+ switch (count) {
+ /* Note: code falls through cases! */
+ case 6:
+ r[5] = 0x80 | (wc & 0x3f);
+ wc = wc >> 6;
+ wc |= 0x4000000;
+ case 5:
+ r[4] = 0x80 | (wc & 0x3f);
+ wc = wc >> 6;
+ wc |= 0x200000;
+ case 4:
+ r[3] = 0x80 | (wc & 0x3f);
+ wc = wc >> 6;
+ wc |= 0x10000;
+ case 3:
+ r[2] = 0x80 | (wc & 0x3f);
+ wc = wc >> 6;
+ wc |= 0x800;
+ case 2:
+ r[1] = 0x80 | (wc & 0x3f);
+ wc = wc >> 6;
+ wc |= 0xc0;
+ case 1:
+ r[0] = wc;
+ }
+
+ return count;
+}
+
+int
+utf8_mbtowc_internal(void *data, int (*read) (void *), unsigned int *pwc)
+{
+ int s[4];
+#define nextc(n) if (((n) = read (data)) <= 0) { errno = ENODATA; return -1; }
+
+ nextc(s[0]);
+ if (s[0] < 0x80) {
+ *pwc = s[0];
+ return 1;
+ }
+
+ if (s[0] < 0xc2) {
+ errno = EILSEQ;
+ return -1;
+ } else if (s[0] < 0xe0) {
+ nextc(s[1]);
+ if (!((s[1] ^ 0x80) < 0x40)) {
+ errno = EILSEQ;
+ return -1;
+ }
+ *pwc = ((unsigned int) (s[0] & 0x1f) << 6) |
+ (unsigned int) (s[1] ^ 0x80);
+ return 2;
+ }
+
+ if (s[0] < 0xf0) {
+ nextc(s[1]);
+ nextc(s[2]);
+
+ if (!((s[1] ^ 0x80) < 0x40
+ && (s[2] ^ 0x80) < 0x40 && (s[0] >= 0xe1 || s[1] >= 0xa0))) {
+ errno = EILSEQ;
+ return -1;
+ }
+
+ *pwc = ((unsigned long) (s[0] & 0x0f) << 12) |
+ ((unsigned long) (s[1] ^ 0x80) << 6) |
+ (unsigned long) (s[2] ^ 0x80);
+
+ return 3;
+ }
+
+ if (s[0] < 0xf8) {
+ nextc(s[1]);
+ nextc(s[2]);
+ nextc(s[3]);
+
+ if (!((s[1] ^ 0x80) < 0x40 &&
+ (s[2] ^ 0x80) < 0x40 &&
+ (s[3] ^ 0x80) < 0x40 && (s[0] >= 0xf1 || s[1] >= 0x90))) {
+ errno = EILSEQ;
+ return -1;
+ }
+
+ *pwc = ((unsigned long) (s[0] & 0x07) << 18) |
+ ((unsigned long) (s[1] ^ 0x80) << 12) |
+ ((unsigned long) (s[2] ^ 0x80) << 6) |
+ (unsigned long) (s[3] ^ 0x80);
+
+ return 4;
+ }
+ errno = EILSEQ;
+ return -1;
+}
+
+
+struct tstring {
+ const unsigned char *ptr;
+ size_t len;
+};
+
+static int
+_next_char_from_string(void *data)
+{
+ struct tstring *p = data;
+ if (p->len == 0)
+ return 0;
+ p->len--;
+ return *p->ptr++;
+}
+
+int
+utf8_mbtowc(unsigned int *pwc, const char *r, size_t len)
+{
+ struct tstring ts;
+ ts.ptr = (const unsigned char*)r;
+ ts.len = len ? len : utf8_char_width(r);
+ return utf8_mbtowc_internal(&ts, _next_char_from_string, pwc);
+}
+
+
+int
+utf8_symcmp(char *a, char *b)
+{
+ unsigned int wa, wb;
+
+ utf8_mbtowc(&wa, a, utf8_char_width(a));
+ utf8_mbtowc(&wb, b, utf8_char_width(b));
+ if (wa < wb)
+ return -1;
+ if (wa > wb)
+ return 1;
+ return 0;
+}
+
+int
+urf8_symcasecmp(char *a, char *b)
+{
+ unsigned int wa, wb;
+
+ utf8_mbtowc(&wa, a, utf8_char_width(a));
+ utf8_mbtowc(&wb, b, utf8_char_width(b));
+ wa = utf8_wc_toupper(wa);
+ wb = utf8_wc_toupper(wb);
+ if (wa < wb)
+ return -1;
+ if (wa > wb)
+ return 1;
+ return 0;
+}
+
+int
+utf8_strcasecmp(char *a, char *b)
+{
+ int alen, blen;
+
+ for (; *a; a += alen, b += blen) {
+ unsigned wa, wb;
+
+ if (*b == 0)
+ return 1;
+
+ alen = utf8_char_width(a);
+ if (alen == 0)
+ return -1;
+ utf8_mbtowc(&wa, a, alen);
+ blen = utf8_char_width(b);
+ if (blen == 0)
+ return 1;
+ utf8_mbtowc(&wb, b, blen);
+ wa = utf8_wc_toupper(wa);
+ wb = utf8_wc_toupper(wb);
+ if (wa < wb)
+ return -1;
+ if (wa > wb)
+ return 1;
+
+ }
+ if (*b)
+ return -1;
+ return 0;
+}
+
+int
+utf8_strncasecmp(char *a, char *b, size_t maxlen)
+{
+ int alen, blen;
+ char *aend = a + maxlen, *bend = b + maxlen;
+
+ for (; a < aend; a += alen, b += blen) {
+ unsigned wa, wb;
+
+ if (*a == 0)
+ return (*b == 0) ? 0 : -1;
+
+ if (*b == 0 || b >= bend)
+ return 1;
+
+ alen = utf8_char_width(a);
+ if (alen == 0)
+ return -1;
+ utf8_mbtowc(&wa, a, alen);
+ blen = utf8_char_width(b);
+ if (blen == 0)
+ return 1;
+ utf8_mbtowc(&wb, b, blen);
+ wa = utf8_wc_toupper(wa);
+ wb = utf8_wc_toupper(wb);
+ if (wa < wb)
+ return -1;
+ if (wa > wb)
+ return 1;
+
+ }
+ return 0;
+}
+
+
+unsigned
+utf8_wc_toupper(unsigned wc)
+{
+ int plane = (wc >> 8) & 0xFF;
+ return uni_plane[plane] ? uni_plane[plane][wc & 0xFF].toupper : wc;
+}
+
+int
+utf8_toupper(char *s, size_t len)
+{
+ while (len > 0) {
+ unsigned wc;
+ int rc = utf8_mbtowc(&wc, s, len);
+ if (rc <= 0)
+ return 1;
+ if (rc != utf8_wctomb(s, utf8_wc_toupper(wc)))
+ return 1;
+ s += rc;
+ len -= rc;
+ }
+ return 0;
+}
+
+unsigned
+utf8_wc_tolower(unsigned wc)
+{
+ int plane = (wc >> 8) & 0xFF;
+ return uni_plane[plane] ? uni_plane[plane][wc & 0xFF].tolower : wc;
+}
+
+int
+utf8_tolower(char *s, size_t len)
+{
+ while (len > 0) {
+ unsigned wc;
+ int rc = utf8_mbtowc(&wc, s, len);
+ if (rc <= 0)
+ return 1;
+ if (rc != utf8_wctomb(s, utf8_wc_tolower(wc)))
+ return 1;
+ s += rc;
+ len -= rc;
+ }
+ return 0;
+}
+
+
+size_t
+utf8_wc_strlen(const unsigned *s)
+{
+ size_t len = 0;
+ while (*s++)
+ len++;
+ return len;
+}
+
+unsigned *
+utf8_wc_strdup(const unsigned *s)
+{
+ size_t len = utf8_wc_strlen(s) + 1;
+ unsigned *clone = calloc(len, sizeof s[0]);
+ if (clone)
+ memcpy(clone, s, len);
+ return clone;
+}
+
+size_t
+utf8_wc_hash_string(const unsigned *ws, size_t n_buckets)
+{
+ size_t value = 0;
+ unsigned wc;
+# define ROTATE_LEFT(Value, Shift) \
+ ((Value) << (Shift) | (Value) >> ((sizeof (size_t) * CHAR_BIT) - (Shift)))
+# define HASH_ONE_CHAR(Value, Byte) \
+ ((Byte) + ROTATE_LEFT (Value, 16))
+
+ while ((wc = *ws++))
+ value = HASH_ONE_CHAR(value, wc);
+ return value % n_buckets;
+}
+
+int
+utf8_wc_strcmp(const unsigned *a, const unsigned *b)
+{
+ while (*a == *b) {
+ if (*a == 0)
+ return 0;
+ a++;
+ b++;
+ }
+ if (*a < *b)
+ return -1;
+ if (*a > *b)
+ return 1;
+ return 0;
+}
+
+int
+utf8_wc_strcasecmp(const unsigned *a, const unsigned *b)
+{
+ unsigned wa, wb;
+
+ while (*a == *b) {
+ if (*a == 0)
+ return 0;
+ a++;
+ b++;
+ }
+ wa = utf8_wc_toupper(*a);
+ wb = utf8_wc_toupper(*b);
+
+ if (wa < wb)
+ return -1;
+ if (wa > wb)
+ return 1;
+ return 0;
+}
+
+const unsigned *
+utf8_wc_strchr(const unsigned *str, unsigned chr)
+{
+ for (; *str; str++)
+ if (*str == chr)
+ return str;
+ return NULL;
+}
+
+const unsigned *
+utf8_wc_strchr_ci(const unsigned *str, unsigned chr)
+{
+ unsigned u = utf8_wc_toupper(chr);
+ for (; *str; str++)
+ if (utf8_wc_toupper(*str) == u)
+ return str;
+ return NULL;
+}
+
+const unsigned *
+utf8_wc_strstr(const unsigned *haystack, const unsigned *needle)
+{
+ unsigned first = needle[0];
+
+ /* Is needle empty? */
+ if (first == 0)
+ return haystack;
+
+ /* Is needle nearly empty? */
+ if (needle[1] == 0)
+ return utf8_wc_strchr(haystack, first);
+ for (; *haystack; haystack++)
+ if (*haystack == first) {
+ /* Compare with needle's remaining units. */
+ const unsigned *hptr = haystack + 1;
+ const unsigned *nptr = needle + 1;
+ for (;;) {
+ if (*hptr != *nptr)
+ break;
+ hptr++;
+ nptr++;
+ if (*nptr == 0)
+ return haystack;
+ }
+ }
+ return NULL;
+}
+
+unsigned *
+utf8_wc_quote(const unsigned *s)
+{
+ size_t len = utf8_wc_strlen(s);
+ unsigned *clone = calloc(2 * len + 1, sizeof s[0]);
+ if (clone) {
+ size_t i, j;
+ for (i = j = 0; i < len; i++) {
+ switch (s[i]) {
+ case '\\':
+ case '"':
+ clone[j++] = '\\';
+ /* fall through */
+ default:
+ clone[j++] = s[i];
+ }
+ }
+ clone[j] = 0;
+ clone = realloc(clone, (j + 1) * sizeof(clone[0]));
+ }
+ return clone;
+}
+
+int
+utf8_wc_to_mbstr(const unsigned *wordbuf, size_t wordlen, char **sptr)
+{
+ size_t i;
+ size_t wbc;
+ char *s;
+
+ wbc = 0;
+ for (i = 0; i < wordlen; i++) {
+ char r[4];
+ int rc = utf8_wctomb(r, wordbuf[i]);
+ if (rc <= 0)
+ return rc;
+ wbc += rc;
+ }
+
+ s = malloc(wbc + 1);
+ if (!s) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ wbc = 0;
+ for (i = 0; i < wordlen; i++) {
+ char r[4];
+ int rc = utf8_wctomb(r, wordbuf[i]);
+ if (rc <= 0)
+ return rc;
+ memcpy(s + wbc, r, rc);
+ wbc += rc;
+ }
+ s[wbc] = 0;
+ *sptr = s;
+ return 0;
+}
+
+void
+utf8_wc_strnupper(unsigned *str, size_t len)
+{
+ for (; len; str++, len--)
+ *str = utf8_wc_toupper(*str);
+}
+
+void
+utf8_wc_strupper(unsigned *str)
+{
+ for (; *str; str++)
+ *str = utf8_wc_toupper(*str);
+}
+
+void
+utf8_wc_strnlower(unsigned *str, size_t len)
+{
+ for (; len; str++, len--)
+ *str = utf8_wc_tolower(*str);
+}
+
+void
+utf8_wc_strlower(unsigned *str)
+{
+ for (; *str; str++)
+ *str = utf8_wc_tolower(*str);
+}
+
+int
+utf8_mbstr_to_wc(const char *str, unsigned **wptr, size_t * plen)
+{
+ ssize_t sc = strlen(str);
+ size_t len, i;
+ unsigned *w = calloc(sizeof(w[0]), sc + 1);
+
+ if (!w)
+ return -1;
+ for (i = 0, len = strlen(str); len; i++) {
+ int rc = utf8_mbtowc(w + i, str, len);
+ if (rc <= 0) {
+ free(w);
+ return -1;
+ }
+ str += rc;
+ len -= rc;
+ }
+ *wptr = w;
+ if (plen)
+ *plen = i;
+ return 0;
+}
+
+#define ISWS(c) ((c)==' '||(c)=='\t'||(c)=='\n')
+
+int
+utf8_mbstr_to_norm_wc(const char *str, unsigned **nptr, size_t * plen)
+{
+ int inws = 0;
+ size_t len = strlen(str);
+ unsigned *base = calloc(len + 1, sizeof(base[0]));
+ size_t i = 0;
+
+ if (!base)
+ return -1;
+
+ while (len > 0) {
+ unsigned wc;
+ int rc = utf8_mbtowc(&wc, str, len);
+ if (rc <= 0)
+ return -1;
+ str += rc;
+ len -= rc;
+ if (rc == 1 && ISWS(wc)) {
+ if (!inws) {
+ wc = ' ';
+ inws = 1;
+ } else
+ continue;
+ } else
+ inws = 0;
+ base[i++] = wc;
+ }
+ base[i++] = 0;
+ *nptr = realloc(base, i * sizeof(base[0]));
+ if (plen)
+ *plen = i;
+ return 0;
+}
+
+int
+utf8_quote(const char *str, char **sptr)
+{
+ int rc;
+ unsigned *ws, *ret;
+
+ rc = utf8_mbstr_to_wc(str, &ws, NULL);
+ if (rc)
+ return rc;
+ ret = utf8_wc_quote(ws);
+ if (ret) {
+ rc = utf8_wc_to_mbstr(ret, utf8_wc_strlen(ret), sptr);
+ free(ret);
+ } else {
+ errno = ENOMEM;
+ rc = -1;
+ }
+ return rc;
+}
diff --git a/src/ellinika/utf8.h b/src/ellinika/utf8.h
new file mode 100644
index 0000000..ce26f09
--- a/dev/null
+++ b/src/ellinika/utf8.h
@@ -0,0 +1,71 @@
+/* This file is part of GNU Dico.
+ Copyright (C) 2008, 2010 Sergey Poznyakoff
+
+ GNU Dico is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Dico is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Dico. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <ctype.h>
+
+size_t utf8_char_width(const char *p);
+size_t utf8_strlen (const char *s);
+size_t utf8_strbytelen (const char *s);
+
+struct utf8_iterator {
+ char *string;
+ char *curptr;
+ unsigned curwidth;
+};
+
+#define utf8_iter_isascii(itr) \
+ ((itr).curwidth == 1 && isascii((itr).curptr[0]))
+
+int utf8_iter_end_p(struct utf8_iterator *itr);
+int utf8_iter_first(struct utf8_iterator *itr, char *ptr);
+int utf8_iter_next(struct utf8_iterator *itr);
+
+int utf8_mbtowc_internal (void *data, int (*read) (void*), unsigned int *pwc);
+int utf8_wctomb (char *r, unsigned int wc);
+
+int utf8_symcmp(char *a, char *b);
+int utf8_symcasecmp(char *a, char *b);
+int utf8_strcasecmp(char *a, char *b);
+int utf8_strncasecmp(char *a, char *b, size_t maxlen);
+
+unsigned utf8_wc_toupper (unsigned wc);
+int utf8_toupper (char *s, size_t len);
+unsigned utf8_wc_tolower (unsigned wc);
+int utf8_tolower (char *s, size_t len);
+size_t utf8_wc_strlen (const unsigned *s);
+unsigned *utf8_wc_strdup (const unsigned *s);
+size_t utf8_wc_hash_string (const unsigned *ws, size_t n_buckets);
+int utf8_wc_strcmp (const unsigned *a, const unsigned *b);
+int utf8_wc_to_mbstr(const unsigned *wordbuf, size_t wordlen, char **sptr);
+
+int utf8_mbstr_to_wc(const char *str, unsigned **wptr, size_t *plen);
+int utf8_mbstr_to_norm_wc(const char *str, unsigned **nptr, size_t *plen);
+
+int utf8_quote (const char *str, char **sptr);
+unsigned *utf8_wc_quote (const unsigned *s);
+
+const unsigned *utf8_wc_strchr(const unsigned *str, unsigned chr);
+const unsigned *utf8_wc_strchr_ci(const unsigned *str, unsigned chr);
+const unsigned *utf8_wc_strstr(const unsigned *haystack,
+ const unsigned *needle);
+
+void utf8_wc_strupper(unsigned *str);
+void utf8_wc_strlower(unsigned *str);
+
+void utf8_wc_strnupper(unsigned *str, size_t len);
+void utf8_wc_strnlower(unsigned *str, size_t len);
+
+

Return to:

Send suggestions and report system problems to the System administrator.